对于Windows平台,WinMain
为应用程序入口;
WinMain
所在的源文件为:
Engine/Source/Launch/Private/Windows/LaunchWindows.cpp
int32 WINAPI WinMain(_In_ HINSTANCE hInInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ char* pCmdLine, _In_ int32 nCmdShow)
{
int32 Result = LaunchWindowsStartup(hInInstance, hPrevInstance, pCmdLine, nCmdShow, nullptr);
LaunchWindowsShutdown();
return Result;
}
LaunchWindowsStartup
中调用GuardedMainWrapper
继而调用GuardedMain
进入引擎整体的调用流程:
int32 GuardedMain( const TCHAR* CmdLine )
{
FTrackedActivity::GetEngineActivity().Update(TEXT("Starting"), FTrackedActivity::ELight::Yellow);
// 省略部分代码
FTrackedActivity::GetEngineActivity().Update(TEXT("Initializing"));
// 执行PreInit
int32 ErrorLevel = EnginePreInit( CmdLine );
// 省略部分代码
// 执行Init
#if WITH_EDITOR
if (GIsEditor)
{
ErrorLevel = EditorInit(GEngineLoop);
}
else
#endif
{
ErrorLevel = EngineInit();
}
}
FTrackedActivity::GetEngineActivity().Update(TEXT("Ticking loop"), FTrackedActivity::ELight::Green);
// Don't tick if we're running an embedded engine - we rely on the outer
// application ticking us instead.
if (!GUELibraryOverrideSettings.bIsEmbedded)
{
while( !IsEngineExitRequested() )
{
// 执行Tick
EngineTick();
}
}
TRACE_BOOKMARK(TEXT("Tick loop end"));
#if WITH_EDITOR
if( GIsEditor )
{
EditorExit();
}
#endif
return ErrorLevel;
}
这其中主要进行是引擎主线程的整个生命周期:
1. EnginePreInit
2. EngineInit
3. EngineTick
4. EngineExit
而这四步调用中都是通过一个全局对象FEngineLoop GEngineLoop
调用到文件
\Engine\Source\Runtime\Launch\Private\LaunchEngineLoop.cpp
中的对应接口。
1. EnginePreInit
EnginePreInit
中进行了一系列的引擎启动初始化准备工作,其中包括
为每个继承自UObject
的对象创建CDO对象:
// Make sure all UObject classes are registered and default properties have been initialized
{
UE_SCOPED_ENGINE_ACTIVITY(TEXT("Initializing UObject Classes"));
ProcessNewlyLoadedUObjects();
}
ProcessNewlyLoadedUObjects
位于:
\Engine\Source\Runtime\CoreUObject\Private\UObject\UObjectBase.cpp
void ProcessNewlyLoadedUObjects(FName Package, bool bCanProcessNewlyLoadedObjects)
{
//省略部分代码
bool bNewUObjects = false;
TArray<UClass*> AllNewClasses;
while (GFirstPendingRegistrant ||
ClassRegistry.HasPendingRegistrations() ||
StructRegistry.HasPendingRegistrations() ||
EnumRegistry.HasPendingRegistrations())
{
bNewUObjects = true;
UObjectProcessRegistrants();
UObjectLoadAllCompiledInStructs();
FCoreUObjectDelegates::CompiledInUObjectsRegisteredDelegate.Broadcast(Package);
//为每个继承自`UObject`的对象创建CDO对象
UObjectLoadAllCompiledInDefaultProperties(AllNewClasses);
}
//省略部分代码
}
/**
* Load any outstanding compiled in default properties
*/
static void UObjectLoadAllCompiledInDefaultProperties(TArray<UClass*>& OutAllNewClasses)
{
//省略部分代码
{
SCOPED_BOOT_TIMING("CoreUObject Classes"