godot游戏引擎的启动

发布时间 2023-05-08 16:21:16作者: 秦舒云

启动的入口代码在:platform/windows/godot_windows.cpp

WinMain()->main()
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
	godot_hinstance = hInstance;
	return main(0, nullptr);
}
main()->_main()
 int main(int argc, char **argv) {
	// override the arguments for the test handler / if symbol is provided
	// TEST_MAIN_OVERRIDE

	// _argc and _argv are ignored
	// we are going to use the WideChar version of them instead
#ifdef CRASH_HANDLER_EXCEPTION
	__try {
		return _main();
	} __except (CrashHandlerException(GetExceptionInformation())) {
		return 1;
	}
#else
	return _main();
#endif
}
_main()->Main类
 int _main() {
	result = widechar_main(argc, wc_argv);
}

int widechar_main(int argc, wchar_t **argv) {
	OS_Windows os(nullptr);

	setlocale(LC_CTYPE, "");

	char **argv_utf8 = new char *[argc];

	for (int i = 0; i < argc; ++i) {
		argv_utf8[i] = wc_to_utf8(argv[i]);
	}

	TEST_MAIN_PARAM_OVERRIDE(argc, argv_utf8)

	Error err = Main::setup(argv_utf8[0], argc - 1, &argv_utf8[1]);

	if (err != OK) {
		for (int i = 0; i < argc; ++i) {
			delete[] argv_utf8[i];
		}
		delete[] argv_utf8;

		if (err == ERR_HELP) { // Returned by --help and --version, so success.
			return 0;
		}
		return 255;
	}

	if (Main::start()) {
		os.run();
	}
	Main::cleanup();

	for (int i = 0; i < argc; ++i) {
		delete[] argv_utf8[i];
	}
	delete[] argv_utf8;

	return os.get_exit_code();
}

 

main/main.cpp

Main类的关键函数和启动时调用
/* 引擎初始化
 *
 * 由若干个methods组成,这些methonds会被平台特定 main(argc, argv)所调用.
 * 为了完整的理解引擎初始化, 需要从平台的main开始,看他是怎样调用 Main class' methods的.
 *
 * 典型的初始化过程分3步构成 (其中setup2这步可以由setup自动触发,也可以在平台的main中手动触发).
 *
 * - setup(execpath, argc, argv, p_second_phase) 是所有平台的主入口点,
 *   负责所有底层singletons and core types 的初始化,并且解析cmd参数并进行配置。
 *   如果 p_second_phase 为 true, 将会接下来执行 setup2() (default behavior). 这个过程在某些平台(Android, iOS, UWP)
 *   是disabled,在他们自己运行时触发。
 *
 * - setup2(p_main_tid_override) registers high level servers and singletons, displays the
 *   boot splash, then registers higher level types (scene, editor, etc.).
 *
 * - start()是最后一步,也是cmd工具开始运行的地方,main loop 最终被创建,系统的设置也放入执行,这里也是editor node创建的地方.
 *   如果需要 start()会处理命令行参数的子参数, 这个很麻烦需要setup()进行全局的解析。
 */
Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_phase) {}