跟着
https://www.cnblogs.com/timlly/p/13877623.html
学习
入口函数
UnrealEngine\Engine\Source\Runtime\Launch\Private\Windows\LaunchWindows.cpp
WinMain 入口
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;
}
然后进入 LAUNCH_API int32 LaunchWindowsStartup( HINSTANCE hInInstance, HINSTANCE hPrevInstance, char*, int32 nCmdShow, const TCHAR* CmdLine )
似乎是经过一些 debugger
然后进入 GuardedMain
UnrealEngine\Engine\Source\Runtime\Launch\Private\Windows\LaunchWindows.cpp
// When we're running embedded, assume that the outer application is going to be handling crash reporting
#if UE_BUILD_DEBUG
if (GUELibraryOverrideSettings.bIsEmbedded || !GAlwaysReportCrash)
#else
if (GUELibraryOverrideSettings.bIsEmbedded || bNoExceptionHandler || (bIsDebuggerPresent && !GAlwaysReportCrash))
#endif
{
// Don't use exception handling when a debugger is attached to exactly trap the crash. This does NOT check
// whether we are the first instance or not!
ErrorLevel = GuardedMain( CmdLine );
}
预初始化
然后就进入 EnginePreInit
UnrealEngine\Engine\Source\Runtime\Launch\Private\Launch.cpp
int32 ErrorLevel = EnginePreInit( CmdLine );
然后是
UnrealEngine\Engine\Source\Runtime\Launch\Private\Launch.cpp
/**
* PreInits the engine loop
*/
int32 EnginePreInit( const TCHAR* CmdLine )
{
int32 ErrorLevel = GEngineLoop.PreInit( CmdLine );
return( ErrorLevel );
}
然后是
UnrealEngine\Engine\Source\Runtime\Launch\Private\LaunchEngineLoop.cpp
int32 FEngineLoop::PreInit(const TCHAR* CmdLine)
{
#if UE_ENABLE_ARRAY_SLACK_TRACKING
// Any array allocations before this point won't have array slack tracking, although subsequent reallocations of existing arrays
// will gain tracking if that occurs. The goal is to filter out startup constructors which run before Main, which introduce a
// ton of noise into slack reports. Especially the roughly 30,000 static FString constructors in the code base, each with a
// unique call stack, and all having a little bit of slack due to malloc bucket size rounding.
ArraySlackTrackInit();
#endif
const int32 rv1 = PreInitPreStartupScreen(CmdLine);
if (rv1 != 0)
{
PreInitContext.Cleanup();
return rv1;
}
const int32 rv2 = PreInitPostStartupScreen(CmdLine);
if (rv2 != 0)
{
PreInitContext.Cleanup();
return rv2;
}
return 0;
}
然后跳到了 int32 FEngineLoop::PreInitPreStartupScreen(const TCHAR* CmdLine)
不断步进,然后看到一个问题
#if WITH_ENGINE
// Add the default engine shader dir
AddShaderSourceDirectoryMapping(TEXT("/Engine"), FPlatformProcess::ShaderDir());
UnrealEngine\Engine\Source\Runtime\RenderCore\Private\ShaderCore.cpp
前面大部分都是在检查
void AddShaderSourceDirectoryMapping(const FString& VirtualShaderDirectory, const FString& RealShaderDirectory)
{
...
GShaderSourceDirectoryMappings.Add(VirtualShaderDirectory, RealShaderDirectory);
}
最终也只是把它放到一个 map 里面
UnrealEngine\Engine\Source\Runtime\RenderCore\Private\ShaderCore.cpp
/** Global map of virtual file path to physical file paths */
static TMap<FString, FString> GShaderSourceDirectoryMappings;
然后后面还有调用 AddShaderSourceDirectoryMapping
的
然后是加载 module
UnrealEngine\Engine\Source\Runtime\Launch\Private\LaunchEngineLoop.cpp
// Load Core modules required for everything else to work (needs to be loaded before InitializeRenderingCVarsCaching)
{
SCOPED_BOOT_TIMING("LoadCoreModules");
if (!LoadCoreModules())
{
UE_LOG(LogInit, Error, TEXT("Failed to load Core modules."));
return 1;
}
}
...
{
SCOPED_BOOT_TIMING("LoadPreInitModules");
LoadPreInitModules();
}
加载 module 都是用的 FModuleManager::Get().LoadModule
UnrealEngine\Engine\Source\Runtime\Launch\Private\LaunchEngineLoop.cpp
部分代码
void FEngineLoop::LoadPreInitModules()
{
DECLARE_SCOPE_CYCLE_COUNTER(TEXT("Loading PreInit Modules"), STAT_PreInitModules, STATGROUP_LoadTime);
// GGetMapNameDelegate is initialized here
#if WITH_ENGINE
FModuleManager::Get().LoadModule(TEXT("Engine"));
FModuleManager::Get().LoadModule(TEXT("Renderer"));
FModuleManager::Get().LoadModule(TEXT("AnimGraphRuntime"));
FPlatformApplicationMisc::LoadPreInitModules();
之后似乎我也看不懂
于是回到 int32 FEngineLoop::PreInit(const TCHAR* CmdLine)
奇怪的是,我在 const int32 rv2 = PreInitPostStartupScreen(CmdLine);
这里加了断点,但是直到选择项目的界面出现了,也没有触发
但是毫无疑问,我从 int32 ErrorLevel = EnginePreInit( CmdLine );
里面退出来之后,接下来还是继续留在 int32 GuardedMain( const TCHAR* CmdLine )
里面,并且这个时候也没进到项目选择的界面
所以……那个问题就不管了
然后是编辑器初始化
UnrealEngine\Engine\Source\Runtime\Launch\Private\Launch.cpp
#if WITH_EDITOR
if (GIsEditor)
{
ErrorLevel = EditorInit(GEngineLoop);
}
else
#endif
{
ErrorLevel = EngineInit();
}
}
初始化这里似乎不应该深究
我看 UE 官方的 PPT 都说很多人讨厌臃肿的初始化hhh