コード例 #1
0
void FName::AutoTest()
{
    const FName AutoTest_1("AutoTest_1");
    const FName autoTest_1("autoTest_1");
    const FName autoTeSt_1("autoTeSt_1");
    const FName AutoTest1Find("autoTEST_1", EFindName::FNAME_Find);
    const FName AutoTest_2(TEXT("AutoTest_2"));
    const FName AutoTestB_2(TEXT("AutoTestB_2"));

    check(AutoTest_1 != AutoTest_2);
    check(AutoTest_1 == autoTest_1);
    check(AutoTest_1 == autoTeSt_1);
#if WITH_CASE_PRESERVING_NAME
    check(!FCString::Strcmp(*AutoTest_1.ToString(), TEXT("AutoTest_1")));
    check(!FCString::Strcmp(*autoTest_1.ToString(), TEXT("autoTest_1")));
    check(!FCString::Strcmp(*autoTeSt_1.ToString(), TEXT("autoTeSt_1")));
    check(!FCString::Strcmp(*AutoTestB_2.ToString(), TEXT("AutoTestB_2")));
#endif
    check(autoTest_1.GetComparisonIndex() == AutoTest_2.GetComparisonIndex());
    check(autoTest_1.GetPlainNameString() == AutoTest_1.GetPlainNameString());
    check(autoTest_1.GetPlainNameString() == AutoTest_2.GetPlainNameString());
    check(*AutoTestB_2.GetPlainNameString() != *AutoTest_2.GetPlainNameString());
    check(AutoTestB_2.GetNumber() == AutoTest_2.GetNumber());
    check(autoTest_1.GetNumber() != AutoTest_2.GetNumber());
}
コード例 #2
0
/**
* Returns a string for the specified texture group LOD settings to the specified ini.
*
* @param	TextureGroupID		Index/enum of the group
* @param	GroupName			String representation of the texture group
*/
FString FSystemSettingsData::GetLODGroupString( TextureGroup TextureGroupID, const TCHAR* GroupName )
{
	const FExposedTextureLODSettings::FTextureLODGroup& Group = TextureLODSettings.GetTextureLODGroup(TextureGroupID);

	const int32 MinLODSize = 1 << Group.MinLODMipCount;
	const int32 MaxLODSize = 1 << Group.MaxLODMipCount;

	FName MinMagFilter = NAME_Aniso;
	FName MipFilter = NAME_Linear;
	switch(Group.Filter)
	{
		case SF_Point:
			MinMagFilter = NAME_Point;
			MipFilter = NAME_Point;
			break;
		case SF_Bilinear:
			MinMagFilter = NAME_Linear;
			MipFilter = NAME_Point;
			break;
		case SF_Trilinear:
			MinMagFilter = NAME_Linear;
			MipFilter = NAME_Linear;
			break;
		case SF_AnisotropicPoint:
			MinMagFilter = NAME_Aniso;
			MipFilter = NAME_Point;
			break;
		case SF_AnisotropicLinear:
			MinMagFilter = NAME_Aniso;
			MipFilter = NAME_Linear;
			break;
	}

	FString NumStreamedMipsText;
	if ( Group.NumStreamedMips >= 0 )
	{
		NumStreamedMipsText = FString::Printf( TEXT(",NumStreamedMips=%i"), Group.NumStreamedMips );
	}

	return FString::Printf( TEXT("(MinLODSize=%i,MaxLODSize=%i,LODBias=%i,MinMagFilter=%s,MipFilter=%s%s,MipGenSettings=%s)"),
		MinLODSize, MaxLODSize, Group.LODBias, *MinMagFilter.GetPlainNameString(), *MipFilter.GetPlainNameString(), *NumStreamedMipsText, UTexture::GetMipGenSettingsString(Group.MipGenSettings) );
}
コード例 #3
0
USCS_Node* USimpleConstructionScript::CreateNodeAndRenameComponent(UActorComponent* NewComponentTemplate)
{
	check(NewComponentTemplate);

	// note that naming logic is duplicated in CreateNode:
	FName NewComponentVariableName = GenerateNewComponentName(NewComponentTemplate->GetClass());

	// Relocate the instance from the transient package to the BPGC and assign it a unique object name
	NewComponentTemplate->Rename(*(NewComponentVariableName.GetPlainNameString() + FGuid::NewGuid().ToString()), GetBlueprint()->GeneratedClass, REN_DontCreateRedirectors | REN_DoNotDirty);

	return CreateNodeImpl(NewComponentTemplate, NewComponentVariableName);
}
コード例 #4
0
void UOscFunctionLibrary::PushString(const TArray<FOscDataElemStruct> & input, FName Value, TArray<FOscDataElemStruct> & output)
{
    if(Value.GetDisplayNameEntry()->IsWide())
    {
        const auto tmp = Value.GetPlainNameString();
        UE_LOG(LogOSC, Error, TEXT("Invalid string argument \"%s\": ASCII only"), *tmp);
        return;
    }

    output = input;
    FOscDataElemStruct elem;
    elem.SetString(Value);
    output.Add(elem);
}
コード例 #5
0
ファイル: CoreNet.cpp プロジェクト: Tigrouzen/UnrealEngine-4
bool UPackageMap::SerializeName(FArchive& Ar, FName& Name)
{
	if (Ar.IsLoading())
	{
		uint8 bHardcoded = 0;
		Ar.SerializeBits(&bHardcoded, 1);
		if (bHardcoded)
		{
			// replicated by hardcoded index
			uint32 NameIndex;
			Ar.SerializeInt(NameIndex, MAX_NETWORKED_HARDCODED_NAME + 1);
			Name = EName(NameIndex);
			// hardcoded names never have a Number
		}
		else
		{
			// replicated by string
			FString InString;
			int32 InNumber;
			Ar << InString << InNumber;
			Name = FName(*InString, InNumber);
		}
	}
	else if (Ar.IsSaving())
	{
		uint8 bHardcoded = Name.GetIndex() <= MAX_NETWORKED_HARDCODED_NAME;
		Ar.SerializeBits(&bHardcoded, 1);
		if (bHardcoded)
		{
			// send by hardcoded index
			checkSlow(Name.GetNumber() <= 0); // hardcoded names should never have a Number
			uint32 NameIndex = uint32(Name.GetIndex());
			Ar.SerializeInt(NameIndex, MAX_NETWORKED_HARDCODED_NAME + 1);
		}
		else
		{
			// send by string
			FString OutString = Name.GetPlainNameString();
			int32 OutNumber = Name.GetNumber();
			Ar << OutString << OutNumber;
		}
	}
	return true;
}
コード例 #6
0
void APlatformerHUD::NotifyHitBoxClick(FName BoxName)
{
	Super::NotifyHitBoxClick(BoxName);

	if (BoxName.GetPlainNameString() == "Letter")
	{
		CurrentLetter = BoxName.GetNumber();
	}
	if (BoxName == "Up")
	{
		if (HighScoreName[CurrentLetter] < 'Z')
		{
			HighScoreName[CurrentLetter]++;
		}
	}
	if (BoxName == "Down")
	{
		if (HighScoreName[CurrentLetter] > 'A')
		{
			HighScoreName[CurrentLetter]--;
		}
	}
	if (BoxName == "OK")
	{
		bEnterNamePromptActive = false;
		if (PlayerOwner)
		{
			PlayerOwner->bShowMouseCursor = bEnterNamePromptActive;
		}

		FString EnteredName = FString();
		for (int32 i=0; i < HighScoreName.Num(); i++)
		{
			EnteredName.AppendChar(HighScoreName[i]);
		}

		OnHighscoreNameAccepted.Broadcast(EnteredName);
	}
}
コード例 #7
0
void UOscFunctionLibrary::SendOsc(FName Address, const TArray<FOscDataElemStruct> & Data, int32 TargetIndex)
{
    if(Address.GetDisplayNameEntry()->IsWide())
    {
        const auto tmp = Address.GetPlainNameString();
        UE_LOG(LogOSC, Error, TEXT("Invalid OSC address \"%s\": ASCII only"), *tmp);
        return;
    }
    
    static_assert(sizeof(uint8) == sizeof(char), "Cannot cast uint8 to char");
    uint8 buffer[1024];

    osc::OutboundPacketStream output((char *)buffer, sizeof(buffer));
    output << osc::BeginMessage(Address.GetPlainANSIString());
    for(const auto & elem : Data)
    {
        if(elem.IsFloat())
        {
            output << (float)elem.AsFloatValue();
        }
        else if(elem.IsInt())
        {
            output << (int32)elem.AsIntValue();
        }
        else if(elem.IsBool())
        {
            output << elem.AsBoolValue();
        }
        else if(elem.IsString())
        {
            output << elem.AsStringValue().GetPlainANSIString();
        }
    }
    output << osc::EndMessage;

    check(reinterpret_cast<const void *>(buffer) == reinterpret_cast<const void *>(output.Data()));
    GetMutableDefault<UOscSettings>()->Send(buffer, output.Size(), TargetIndex);
}
コード例 #8
0
	virtual TStatId GetHighPerformanceEnableForStat(FName StatShortName, const char* InGroup, const char* InCategory, bool bDefaultEnable, bool bShouldClearEveryFrame, EStatDataType::Type InStatType, TCHAR const* InDescription, bool bCycleStat, FPlatformMemory::EMemoryCounterRegion MemoryRegion = FPlatformMemory::MCR_Invalid) override
	{
		FScopeLock ScopeLock(&SynchronizationObject);

		FStatNameAndInfo LongName(StatShortName, InGroup, InCategory, InDescription, InStatType, bShouldClearEveryFrame, bCycleStat, MemoryRegion);

		FName Stat = LongName.GetEncodedName();

		FName Group(InGroup);
		FGroupEnable* Found = HighPerformanceEnable.Find(Group);
		if (Found)
		{
			if (Found->DefaultEnable != bDefaultEnable)
			{
				UE_LOG(LogStatGroupEnableManager, Fatal, TEXT("Stat group %s was was defined both on and off by default."), *Group.ToString());
			}
			TStatIdData** StatFound = Found->NamesInThisGroup.Find( Stat );
			TStatIdData** StatFoundAlways = Found->AlwaysEnabledNamesInThisGroup.Find( Stat );
			if( StatFound )
			{
				if( StatFoundAlways )
				{
					UE_LOG( LogStatGroupEnableManager, Fatal, TEXT( "Stat %s is both always enabled and not always enabled, so it was used for two different things." ), *Stat.ToString() );
				}
				return TStatId( *StatFound );
			}
			else if( StatFoundAlways )
			{
				return TStatId( *StatFoundAlways );
			}
		}
		else
		{
			Found = &HighPerformanceEnable.Add( Group, FGroupEnable( bDefaultEnable || !bShouldClearEveryFrame ) );

			// this was set up before we saw the group, so set the enable now
			if (EnableForNewGroup.Contains(Group))
			{
				Found->CurrentEnable = EnableForNewGroup.FindChecked(Group);
				EnableForNewGroup.Remove(Group); // by definition, we will never need this again
			}
			else if (UseEnableForNewGroups)
			{
				Found->CurrentEnable = EnableForNewGroups;
			}
		}
		if (PendingCount < 1)
		{
			PendingStatIds = new TStatIdData[NUM_PER_BLOCK];
			FMemory::Memzero( PendingStatIds, NUM_PER_BLOCK * sizeof( TStatIdData ) );
			PendingCount = NUM_PER_BLOCK;
		}
		--PendingCount;
		TStatIdData* Result = PendingStatIds;

		const FString StatDescription = InDescription ? InDescription : StatShortName.GetPlainNameString();

		// Get the wide stat description.
		const int32 StatDescLen = StatDescription.Len() + 1;
		// We are leaking this. @see STAT_StatDescMemory
		WIDECHAR* StatDescWide = new WIDECHAR[StatDescLen];
		TCString<WIDECHAR>::Strcpy( StatDescWide, StatDescLen, StringCast<WIDECHAR>( *StatDescription ).Get() );
		Result->WideString = reinterpret_cast<uint64>(StatDescWide);

		// Get the ansi stat description.
		// We are leaking this. @see STAT_StatDescMemory
		ANSICHAR* StatDescAnsi = new ANSICHAR[StatDescLen];
		TCString<ANSICHAR>::Strcpy( StatDescAnsi, StatDescLen, StringCast<ANSICHAR>( *StatDescription ).Get() );
		Result->AnsiString = reinterpret_cast<uint64>(StatDescAnsi);

		MemoryCounter.Add( StatDescLen*(sizeof( ANSICHAR ) + sizeof( WIDECHAR )) );
		
		++PendingStatIds;

		if( Found->CurrentEnable )
		{
			EnableStat( Stat, Result );
		}

		if( bShouldClearEveryFrame )
		{
			Found->NamesInThisGroup.Add( Stat, Result );
		}
		else
		{
			Found->AlwaysEnabledNamesInThisGroup.Add( Stat, Result );
		}
		return TStatId(Result);
	}
コード例 #9
0
	/** Build the streamed audio. This function is safe to call from any thread. */
	void BuildStreamedAudio()
	{
		GetStreamedAudioDerivedDataKeySuffix(SoundWave, AudioFormatName, KeySuffix);

		DerivedData->Chunks.Empty();
		
		ITargetPlatformManagerModule* TPM = GetTargetPlatformManager();
		const IAudioFormat* AudioFormat = NULL;
		if (TPM)
		{
			AudioFormat = TPM->FindAudioFormat(AudioFormatName);
		}

		if (AudioFormat)
		{
			DerivedData->AudioFormat = AudioFormatName;

			FByteBulkData* CompressedData = SoundWave.GetCompressedData(AudioFormatName);
			TArray<uint8> CompressedBuffer;
			CompressedBuffer.Empty(CompressedData->GetBulkDataSize());
			CompressedBuffer.AddUninitialized(CompressedData->GetBulkDataSize());
			void* BufferData = CompressedBuffer.GetData();
			CompressedData->GetCopy(&BufferData, false);
			TArray<TArray<uint8>> ChunkBuffers;

			if (AudioFormat->SplitDataForStreaming(CompressedBuffer, ChunkBuffers))
			{
				for (int32 ChunkIndex = 0; ChunkIndex < ChunkBuffers.Num(); ++ChunkIndex)
				{
					FStreamedAudioChunk* NewChunk = new(DerivedData->Chunks) FStreamedAudioChunk();
					NewChunk->DataSize = ChunkBuffers[ChunkIndex].Num();
					NewChunk->BulkData.Lock(LOCK_READ_WRITE);
					void* NewChunkData = NewChunk->BulkData.Realloc(ChunkBuffers[ChunkIndex].Num());
					FMemory::Memcpy(NewChunkData, ChunkBuffers[ChunkIndex].GetData(), ChunkBuffers[ChunkIndex].Num());
					NewChunk->BulkData.Unlock();
				}
			}
			else
			{
				// Could not split so copy compressed data into a single chunk
				FStreamedAudioChunk* NewChunk = new(DerivedData->Chunks) FStreamedAudioChunk();
				NewChunk->DataSize = CompressedBuffer.Num();
				NewChunk->BulkData.Lock(LOCK_READ_WRITE);
				void* NewChunkData = NewChunk->BulkData.Realloc(CompressedBuffer.Num());
				FMemory::Memcpy(NewChunkData, CompressedBuffer.GetData(), CompressedBuffer.Num());
				NewChunk->BulkData.Unlock();
			}

			DerivedData->NumChunks = DerivedData->Chunks.Num();

			// Store it in the cache.
			PutDerivedDataInCache(DerivedData, KeySuffix);
		}
		
		if (DerivedData->Chunks.Num())
		{
			bool bInlineChunks = (CacheFlags & EStreamedAudioCacheFlags::InlineChunks) != 0;
			bSucceeded = !bInlineChunks || DerivedData->TryInlineChunkData();
		}
		else
		{
			UE_LOG(LogAudio, Warning, TEXT("Failed to build %s derived data for %s"),
				*AudioFormatName.GetPlainNameString(),
				*SoundWave.GetPathName()
				);
		}
	}
コード例 #10
0
void FProfilerStatMetaData::UpdateFromStatsState( const FStatsThreadState& StatsThreadStats )
{
	TMap<FName, int32> GroupFNameIDs;

	for( auto It = StatsThreadStats.Threads.CreateConstIterator(); It; ++It )
	{
		ThreadDescriptions.Add( It.Key(), It.Value().ToString() );
	}

	const uint32 NoGroupID = 0;
	const uint32 ThreadGroupID = 1;

	// Special groups.
	InitializeGroup( NoGroupID, "NoGroup" );

	// Self must be 0.
	InitializeStat( 0, NoGroupID, TEXT( "Self" ), STATTYPE_CycleCounter );

	// ThreadRoot must be 1.
	InitializeStat( 1, NoGroupID, FStatConstants::NAME_ThreadRoot.GetPlainNameString(), STATTYPE_CycleCounter, FStatConstants::NAME_ThreadRoot );

	int32 UniqueID = 15;

	TArray<FName> GroupFNames;
	StatsThreadStats.Groups.MultiFind( NAME_Groups, GroupFNames );
	for( const auto& GroupFName : GroupFNames  )
	{
		UniqueID++;
		InitializeGroup( UniqueID, GroupFName.ToString() );
		GroupFNameIDs.Add( GroupFName, UniqueID );
	}

	for( auto It = StatsThreadStats.ShortNameToLongName.CreateConstIterator(); It; ++It )
	{
		const FStatMessage& LongName = It.Value();
		
		const FName GroupName = LongName.NameAndInfo.GetGroupName();
		if( GroupName == NAME_Groups )
		{
			continue;
		}
		const int32 GroupID = GroupFNameIDs.FindChecked( GroupName );

		const FName StatName = It.Key();
		UniqueID++;

		EStatType StatType = STATTYPE_Error;
		if( LongName.NameAndInfo.GetField<EStatDataType>() == EStatDataType::ST_int64 )
		{
			if( LongName.NameAndInfo.GetFlag( EStatMetaFlags::IsCycle ) )
			{
				StatType = STATTYPE_CycleCounter;
			}
			else if( LongName.NameAndInfo.GetFlag( EStatMetaFlags::IsMemory ) )
			{
				StatType = STATTYPE_MemoryCounter;
			}
			else
			{
				StatType = STATTYPE_AccumulatorDWORD;
			}
		}
		else if( LongName.NameAndInfo.GetField<EStatDataType>() == EStatDataType::ST_double )
		{
			StatType = STATTYPE_AccumulatorFLOAT;
		}
		else if( LongName.NameAndInfo.GetField<EStatDataType>() == EStatDataType::ST_Ptr )
		{
			// Not supported at this moment.
			continue;
		}

		check( StatType != STATTYPE_Error );

		int32 StatID = UniqueID;
		// Some hackery.
		if( StatName == TEXT( "STAT_FrameTime" ) )
		{
			StatID = 2;
		}

		const FString Description = LongName.NameAndInfo.GetDescription();
		const FString StatDesc = !Description.IsEmpty() ? Description : StatName.ToString();

		InitializeStat( StatID, GroupID, StatDesc, StatType, StatName );

		// Setup thread id to stat id.
		if( GroupName == FStatConstants::NAME_ThreadGroup )
		{
			uint32 ThreadID = 0;
			for( auto ThreadsIt = StatsThreadStats.Threads.CreateConstIterator(); ThreadsIt; ++ThreadsIt )
			{
				if (ThreadsIt.Value() == StatName)
				{
					ThreadID = ThreadsIt.Key();
					break;
				}
			}
			ThreadIDtoStatID.Add( ThreadID, StatID );

			// Game thread is always NAME_GameThread
			if( StatName == NAME_GameThread )
			{
				GameThreadID = ThreadID;
			}
			// Rendering thread may be "Rendering thread" or NAME_RenderThread with an index
			else if( StatName.GetPlainNameString().Contains( FName(NAME_RenderThread).GetPlainNameString() ) )
			{
				RenderThreadIDs.AddUnique( ThreadID );
			}
			else if( StatName.GetPlainNameString().Contains( TEXT( "RenderingThread" ) ) )
			{
				RenderThreadIDs.AddUnique( ThreadID );
			}
		}
	}
}
コード例 #11
0
TSharedPtr<IModuleInterface> FModuleManager::LoadModuleWithFailureReason(const FName InModuleName, EModuleLoadResult& OutFailureReason, bool bWasReloaded /*=false*/)
{
	DECLARE_SCOPE_CYCLE_COUNTER(TEXT("Module Load"), STAT_ModuleLoad, STATGROUP_LoadTime);

#if	STATS
	// This is fine here, we only load a handful of modules.
	static FString Module = TEXT( "Module" );
	const FString LongName = Module / InModuleName.GetPlainNameString();
	const TStatId StatId = FDynamicStats::CreateStatId<FStatGroup_STATGROUP_UObjects>( LongName );
	FScopeCycleCounter CycleCounter( StatId );
#endif // STATS

	TSharedPtr<IModuleInterface> LoadedModule;
	OutFailureReason = EModuleLoadResult::Success;

	// Update our set of known modules, in case we don't already know about this module
	AddModule( InModuleName );

	// Grab the module info.  This has the file name of the module, as well as other info.
	TSharedRef< FModuleInfo > ModuleInfo = Modules.FindChecked( InModuleName );

	if (ModuleInfo->Module.IsValid())
	{
		// Assign the already loaded module into the return value, otherwise the return value gives the impression the module failed load!
		LoadedModule = ModuleInfo->Module;
	}
	else
	{
	// Make sure this isn't a module that we had previously loaded, and then unloaded at shutdown time.
	//
	// If this assert goes off, your trying to load a module during the shutdown phase that was already
	// cleaned up.  The easiest way to fix this is to change your code to query for an already-loaded
	// module instead of trying to load it directly.
	checkf((!ModuleInfo->bWasUnloadedAtShutdown), TEXT("Attempted to load module '%s' that was already unloaded at shutdown.  FModuleManager::LoadModule() was called to load a module that was previously loaded, and was unloaded at shutdown time.  If this assert goes off, your trying to load a module during the shutdown phase that was already cleaned up.  The easiest way to fix this is to change your code to query for an already-loaded module instead of trying to load it directly."), *InModuleName.ToString());

	// Check if we're statically linked with the module.  Those modules register with the module manager using a static variable,
	// so hopefully we already know about the name of the module and how to initialize it.
	const FInitializeStaticallyLinkedModule* ModuleInitializerPtr = StaticallyLinkedModuleInitializers.Find(InModuleName);
		if (ModuleInitializerPtr != NULL)
	{
		const FInitializeStaticallyLinkedModule& ModuleInitializer(*ModuleInitializerPtr);

		// Initialize the module!
		ModuleInfo->Module = MakeShareable(ModuleInitializer.Execute());

		if (ModuleInfo->Module.IsValid())
		{
			// Startup the module
			ModuleInfo->Module->StartupModule();

			// Module was started successfully!  Fire callbacks.
			ModulesChangedEvent.Broadcast(InModuleName, EModuleChangeReason::ModuleLoaded);

			// Set the return parameter
			LoadedModule = ModuleInfo->Module;
		}
		else
		{
			UE_LOG(LogModuleManager, Warning, TEXT("ModuleManager: Unable to load module '%s' because InitializeModule function failed (returned NULL pointer.)"), *InModuleName.ToString());
			OutFailureReason = EModuleLoadResult::FailedToInitialize;
		}
	}
#if IS_MONOLITHIC
		else
		{
	// Monolithic builds that do not have the initializer were *not found* during the build step, so return FileNotFound
	// (FileNotFound is an acceptable error in some case - ie loading a content only project)
	UE_LOG(LogModuleManager, Warning, TEXT("ModuleManager: Module '%s' not found - its StaticallyLinkedModuleInitializers function is null."), *InModuleName.ToString());
	OutFailureReason = EModuleLoadResult::FileNotFound;
		}
#endif
#if !IS_MONOLITHIC
		else
		{
	// Make sure that any UObjects that need to be registered were already processed before we go and
	// load another module.  We just do this so that we can easily tell whether UObjects are present
	// in the module being loaded.
	if (bCanProcessNewlyLoadedObjects)
	{
		ProcessLoadedObjectsCallback.Broadcast();
	}

	// Try to dynamically load the DLL

	UE_LOG(LogModuleManager, Verbose, TEXT("ModuleManager: Load Module '%s' DLL '%s'"), *InModuleName.ToString(), *ModuleInfo->Filename);

	// Determine which file to load for this module.
	const FString ModuleFileToLoad = FPaths::ConvertRelativePathToFull(ModuleInfo->Filename);

	// Clear the handle and set it again below if the module is successfully loaded
	ModuleInfo->Handle = NULL;

	// Skip this check if file manager has not yet been initialized
			if (FPaths::FileExists(ModuleFileToLoad))
	{
				if (CheckModuleCompatibility(*ModuleFileToLoad))
	{
	ModuleInfo->Handle = FPlatformProcess::GetDllHandle(*ModuleFileToLoad);
					if (ModuleInfo->Handle != NULL)
	{
	// First things first.  If the loaded DLL has UObjects in it, then their generated code's
	// static initialization will have run during the DLL loading phase, and we'll need to
	// go in and make sure those new UObject classes are properly registered.
	{
		// Sometimes modules are loaded before even the UObject systems are ready.  We need to assume
		// these modules aren't using UObjects.
		if (bCanProcessNewlyLoadedObjects)
		{
			// OK, we've verified that loading the module caused new UObject classes to be
			// registered, so we'll treat this module as a module with UObjects in it.
			ProcessLoadedObjectsCallback.Broadcast();
		}
	}

	// Find our "InitializeModule" global function, which must exist for all module DLLs
						FInitializeModuleFunctionPtr InitializeModuleFunctionPtr =
							(FInitializeModuleFunctionPtr)FPlatformProcess::GetDllExport(ModuleInfo->Handle, TEXT("InitializeModule"));
						if (InitializeModuleFunctionPtr != NULL)
						{
							// Initialize the module!
							ModuleInfo->Module = MakeShareable(InitializeModuleFunctionPtr());

							if (ModuleInfo->Module.IsValid())
							{
								// Startup the module
								ModuleInfo->Module->StartupModule();

								// Module was started successfully!  Fire callbacks.
								ModulesChangedEvent.Broadcast(InModuleName, EModuleChangeReason::ModuleLoaded);

								// Set the return parameter
								LoadedModule = ModuleInfo->Module;
							}
							else
	{
								UE_LOG(LogModuleManager, Warning, TEXT("ModuleManager: Unable to load module '%s' because InitializeModule function failed (returned NULL pointer.)"), *ModuleFileToLoad);

		FPlatformProcess::FreeDllHandle(ModuleInfo->Handle);
		ModuleInfo->Handle = NULL;
		OutFailureReason = EModuleLoadResult::FailedToInitialize;
							}
	}
						else
	{
							UE_LOG(LogModuleManager, Warning, TEXT("ModuleManager: Unable to load module '%s' because InitializeModule function was not found."), *ModuleFileToLoad);

		FPlatformProcess::FreeDllHandle(ModuleInfo->Handle);
		ModuleInfo->Handle = NULL;
		OutFailureReason = EModuleLoadResult::FailedToInitialize;
						}
					}
					else
					{
						UE_LOG(LogModuleManager, Warning, TEXT("ModuleManager: Unable to load module '%s' because the file couldn't be loaded by the OS."), *ModuleFileToLoad);
						OutFailureReason = EModuleLoadResult::CouldNotBeLoadedByOS;
					}
				}
				else
				{
					// The log warning about this failure reason is within CheckModuleCompatibility
					OutFailureReason = EModuleLoadResult::FileIncompatible;
				}
			}
			else
			{
				UE_LOG(LogModuleManager, Warning, TEXT("ModuleManager: Unable to load module '%s' because the file '%s' was not found."), *InModuleName.ToString(), *ModuleFileToLoad);
				OutFailureReason = EModuleLoadResult::FileNotFound;
			}
	}
#endif
	}