Godot 4 源码分析 - 命令行参数

Godot 4 源码分析 - 增加管道通信 学习研究Godot 4,很爽,虽然很庞杂,但相对于自己的水平来说,很强大,尤其是vulkan这块直接打包可用,省得自己从头琢磨。一点一点地消化、优化与完善,最终才能成为自己的。这段时间就在Godot的基础上,增加管道通信,实现Godot与本机已有程序进行通信,以备后续的无缝集成整合。其实,Godot支持各种网络通信,支持UDP、TCP等。为什么非要实现管道通信,本质上还是想看看改造效果。最终目标是实现Godot软件与自己的DrGraph软件的管道通信。 阅读详情

 粗看Godot 4的源码,稍微调试一下,发现一大堆的命令行参数。在widechar_main中

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

 Main::setup中,各命令行参数加入到List<Stirng> args中,并通过OS::get_singleton()->get_cmdline_platform_args()取得平台相关命令行参数,然后args逐项处理。

命令行参考

常规选项 - 显示命令行选项列表

-h, --help, /?

显示命令行选项列表。

if (I->get() == "-h" || I->get() == "--help" || I->get() == "/?") { // display help
	show_help = true;
	exit_code = ERR_HELP; // Hack to force an early exit in `main()` with a success code.
	goto error;

}

然后调用print_help

void Main::print_help(const char *p_binary) {
	print_line(String(VERSION_NAME) + " v" + get_full_version_string() + " - " + String(VERSION_WEBSITE));
	OS::get_singleton()->print("Free and open source software under the terms of the MIT license.\n");
	OS::get_singleton()->print("(c) 2014-present Godot Engine contributors.\n");
	OS::get_singleton()->print("(c) 2007-2014 Juan Linietsky, Ariel Manzur.\n");
	OS::get_singleton()->print("\n");
	OS::get_singleton()->print("Usage: %s [options] [path to scene or 'project.godot' file]\n", p_binary);
	OS::get_singleton()->print("\n");

	OS::get_singleton()->print("General options:\n");
	OS::get_singleton()->print("  -h, --help                        Display this help message.\n");
	OS::get_singleton()->print("  --version                         Display the version string.\n");
	OS::get_singleton()->print("  -v, --verbose                     Use verbose stdout mode.\n");
	OS::get_singleton()->print("  -q, --quiet                       Quiet mode, silences stdout messages. Errors are still displayed.\n");
	OS::get_singleton()->print("\n");

	OS::get_singleton()->print("Run options:\n");
	OS::get_singleton()->print("  --, ++                            Separator for user-provided arguments. Following arguments are not used by the engine, but can be read from `OS.get_cmdline_user_args()`.\n");
#ifdef TOOLS_ENABLED
	OS::get_singleton()->print("  -e, --editor                      Start the editor instead of running the scene.\n");
	OS::get_singleton()->print("  -p, --project-manager             Start the project manager, even if a project is auto-detected.\n");
	OS::get_singleton()->print("  --debug-server <uri>              Start the editor debug server (<protocol>://<host/IP>[:<port>], e.g. tcp://127.0.0.1:6007)\n");
#endif
	OS::get_singleton()->print("  --quit                            Quit after the first iteration.\n");
	OS::get_singleton()->print("  -l, --language <locale>           Use a specific locale (<locale> being a two-letter code).\n");
	OS::get_singleton()->print("  --path <directory>                Path to a project (<directory> must contain a 'project.godot' file).\n");
	OS::get_singleton()->print("  -u, --upwards                     Scan folders upwards for project.godot file.\n");
	OS::get_singleton()->print("  --main-pack <file>                Path to a pack (.pck) file to load.\n");
	OS::get_singleton()->print("  --render-thread <mode>            Render thread mode ['unsafe', 'safe', 'separate'].\n");
	OS::get_singleton()->print("  --remote-fs <address>             Remote filesystem (<host/IP>[:<port>] address).\n");
	OS::get_singleton()->print("  --remote-fs-password <password>   Password for remote filesystem.\n");

	OS::get_singleton()->print("  --audio-driver <driver>           Audio driver [");
	for (int i = 0; i < AudioDriverManager::get_driver_count(); i++) {
		if (i > 0) {
			OS::get_singleton()->print(", ");
		}
		OS::get_singleton()->print("'%s'", AudioDriverManager::get_driver(i)->get_name());
	}
	OS::get_singleton()->print("].\n");

	OS::get_singleton()->print("  --display-driver <driver>         Display driver (and rendering driver) [");
	for (int i = 0; i < DisplayServer::get_create_function_count(); i++) {
		if (i > 0) {
			OS::get_singleton()->print(", ");
		}
		OS::get_singleton()->print("'%s' (", DisplayServer::get_create_function_name(i));
		Vector<String> rd = DisplayServer::get_create_function_rendering_drivers(i);
		for (int j = 0; j < rd.size(); j++) {
			if (j > 0) {
				OS::get_singleton()->print(", ");
			}
			OS::get_singleton()->print("'%s'", rd[j].utf8().get_data());
		}
		OS::get_singleton()->print(")");
	}
	OS::get_singleton()->print("].\n");

	OS::get_singleton()->print("  --rendering-method <renderer>     Renderer name. Requires driver support.\n");
	OS::get_singleton()->print("  --rendering-driver <driver>       Rendering driver (depends on display driver).\n");
	OS::get_singleton()->print("  --gpu-index <device_index>        Use a specific GPU (run with --verbose to get available device list).\n");
	OS::get_singleton()->print("  --text-driver <driver>            Text driver (Fonts, BiDi, shaping).\n");
	OS::get_singleton()->print("  --tablet-driver <driver>          Pen tablet input driver.\n");
	OS::get_singleton()->print("  --headless                        Enable headless mode (--display-driver headless --audio-driver Dummy). Useful for servers and with --script.\n");
	OS::get_singleton()->print("  --write-movie <file>              Writes a video to the specified path (usually with .avi or .png extension).\n");
	OS::get_singleton()->print("                                    --fixed-fps is forced when enabled, but it can be used to change movie FPS.\n");
	OS::get_singleton()->print("                                    --disable-vsync can speed up movie writing but makes interaction more difficult.\n");

	OS::get_singleton()->print("\n");

	OS::get_singleton()->print("Display options:\n");
	OS::get_singleton()->print("  -f, --fullscreen                  Request fullscreen mode.\n");
	OS::get_singleton()->print("  -m, --maximized                   Request a maximized window.\n");
	OS::get_singleton()->print("  -w, --windowed                    Request windowed mode.\n");
	OS::get_singleton()->print("  -t, --always-on-top               Request an always-on-top window.\n");
	OS::get_singleton()->print("  --resolution <W>x<H>              Request window resolution.\n");
	OS::get_singleton()->print("  --position <X>,<Y>                Request window position (if set, screen argument is ignored).\n");
	OS::get_singleton()->print("  --screen <N>                      Request window screen.\n");
	OS::get_singleton()->print("  --single-window                   Use a single window (no separate subwindows).\n");
	OS::get_singleton()->print("  --xr-mode <mode>                  Select XR (Extended Reality) mode ['default', 'off', 'on'].\n");
	OS::get_singleton()->print("\n");

	OS::get_singleton()->print("Debug options:\n");
	OS::get_singleton()->print("  -d, --debug                       Debug (local stdout debugger).\n");
	OS::get_singleton()->print("  -b, --breakpoints                 Breakpoint list as source::line comma-separated pairs, no spaces (use %%20 instead).\n");
	OS::get_singleton()->print("  --profiling                       Enable profiling in the script debugger.\n");
	OS::get_singleton()->print("  --gpu-profile                     Show a GPU profile of the tasks that took the most time during frame rendering.\n");
	OS::get_singleton()->print("  --gpu-validation                  Enable graphics API validation layers for debugging.\n");
#if DEBUG_ENABLED
	OS::get_singleton()->print("  --gpu-abort                       Abort on graphics API usage errors (usually validation layer errors). May help see the problem if your system freezes.\n");
#endif
	OS::get_singleton()->print("  --remote-debug <uri>              Remote debug (<protocol>://<host/IP>[:<port>], e.g. tcp://127.0.0.1:6007).\n");
#if defined(DEBUG_ENABLED)
	OS::get_singleton()->print("  --debug-collisions                Show collision shapes when running the scene.\n");
	OS::get_singleton()->print("  --debug-paths                     Show path lines when running the scene.\n");
	OS::get_singleton()->print("  --debug-navigation                Show navigation polygons when running the scene.\n");
	OS::get_singleton()->print("  --debug-stringnames               Print all StringName allocations to stdout when the engine quits.\n");
#endif
	OS::get_singleton()->print("  --frame-delay <ms>                Simulate high CPU load (delay each frame by <ms> milliseconds).\n");
	OS::get_singleton()->print("  --time-scale <scale>              Force time scale (higher values are faster, 1.0 is normal speed).\n");
	OS::get_singleton()->print("  --disable-vsync                   Forces disabling of vertical synchronization, even if enabled in the project settings. Does not override driver-level V-Sync enforcement.\n");
	OS::get_singleton()->print("  --disable-render-loop             Disable render loop so rendering only occurs when called explicitly from script.\n");
	OS::get_singleton()->print("  --disable-crash-handler           Disable crash handler when supported by the platform code.\n");
	OS::get_singleton()->print("  --fixed-fps <fps>                 Force a fixed number of frames per second. This setting disables real-time synchronization.\n");
	OS::get_singleton()->print("  --print-fps                       Print the frames per second to the stdout.\n");
	OS::get_singleton()->print("\n");

	OS::get_singleton()->print("Standalone tools:\n");
	OS::get_singleton()->print("  -s, --script <script>             Run a script.\n");
	OS::get_singleton()->print("  --check-only                      Only parse for errors and quit (use with --script).\n");
#ifdef TOOLS_ENABLED
	OS::get_singleton()->print("  --export-release <preset> <path>  Export the project in release mode using the given preset and output path. The preset name should match one defined in export_presets.cfg.\n");
	OS::get_singleton()->print("                                    <path> should be absolute or relative to the project directory, and include the filename for the binary (e.g. 'builds/game.exe').\n");
	OS::get_singleton()->print("                                    The target directory must exist.\n");
	OS::get_singleton()->print("  --export-debug <preset> <path>    Export the project in debug mode using the given preset and output path. See --export-release description for other considerations.\n");
	OS::get_singleton()->print("  --export-pack <preset> <path>     Export the project data only using the given preset and output path. The <path> extension determines whether it will be in PCK or ZIP format.\n");
#ifndef DISABLE_DEPRECATED
	OS::get_singleton()->print("  --convert-3to4 [<max_file_kb>] [<max_line_size>]\n");
	OS::get_singleton()->print("                                    Converts project from Godot 3.x to Godot 4.x.\n");
	OS::get_singleton()->print("  --validate-conversion-3to4 [<max_file_kb>] [<max_line_size>]\n");
	OS::get_singleton()->print("                                    Shows what elements will be renamed when converting project from Godot 3.x to Godot 4.x.\n");
#endif // DISABLE_DEPRECATED
	OS::get_singleton()->print("  --doctool [<path>]                Dump the engine API reference to the given <path> (defaults to current dir) in XML format, merging if existing files are found.\n");
	OS::get_singleton()->print("  --no-docbase                      Disallow dumping the base types (used with --doctool).\n");
	OS::get_singleton()->print("  --build-solutions                 Build the scripting solutions (e.g. for C# projects). Implies --editor and requires a valid project to edit.\n");
	OS::get_singleton()->print("  --dump-gdextension-interface      Generate GDExtension header file 'gdextension_interface.h' in the current folder. This file is the base file required to implement a GDExtension.\n");
	OS::get_singleton()->print("  --dump-extension-api              Generate JSON dump of the Godot API for GDExtension bindings named 'extension_api.json' in the current folder.\n");
	OS::get_singleton()->print("  --startup-benchmark               Benchmark the startup time and print it to console.\n");
	OS::get_singleton()->print("  --startup-benchmark-file <path>   Benchmark the startup time and save it to a given file in JSON format.\n");
#ifdef TESTS_ENABLED
	OS::get_singleton()->print("  --test [--help]                   Run unit tests. Use --test --help for more information.\n");
#endif
#endif
	OS::get_singleton()->print("\n");
}

 最终会在DOS窗口显示各种参数信息

Usage: D:\Godot Engine\bin\godot.windows.editor.x86_32.exe [options] [path to scene or 'project.godot' file]

General options:
  -h, --help                        Display this help message.
  --version                         Display the version string.
  -v, --verbose                     Use verbose stdout mode.
  -q, --quiet                       Quiet mode, silences stdout messages. Errors are still displayed.

Run options:
  --, ++                            Separator for user-provided arguments. Following arguments are not used by the engine, but can be read from `OS.get_cmdline_user_args()`.
  -e, --editor                      Start the editor instead of running the scene.
  -p, --project-manager             Start the project manager, even if a project is auto-detected.
  --debug-server <uri>              Start the editor debug server (<protocol>://<host/IP>[:<port>], e.g. tcp://127.0.0.1:6007)
  --quit                            Quit after the first iteration.
  -l, --language <locale>           Use a specific locale (<locale> being a two-letter code).
  --path <directory>                Path to a project (<directory> must contain a 'project.godot' file).
  -u, --upwards                     Scan folders upwards for project.godot file.
  --main-pack <file>                Path to a pack (.pck) file to load.
  --render-thread <mode>            Render thread mode ['unsafe', 'safe', 'separate'].
  --remote-fs <address>             Remote filesystem (<host/IP>[:<port>] address).
  --remote-fs-password <password>   Password for remote filesystem.
  --audio-driver <driver>           Audio driver ['WASAPI', 'Dummy'].
  --display-driver <driver>         Display driver (and rendering driver) ['windows' ('vulkan', 'opengl3'), 'headless' ('dummy')].
  --rendering-method <renderer>     Renderer name. Requires driver support.
  --rendering-driver <driver>       Rendering driver (depends on display driver).
  --gpu-index <device_index>        Use a specific GPU (run with --verbose to get available device list).
  --text-driver <driver>            Text driver (Fonts, BiDi, shaping).
  --tablet-driver <driver>          Pen tablet input driver.
  --headless                        Enable headless mode (--display-driver headless --audio-driver Dummy). Useful for servers and with --script.
  --write-movie <file>              Writes a video to the specified path (usually with .avi or .png extension).
                                    --fixed-fps is forced when enabled, but it can be used to change movie FPS.
                                    --disable-vsync can speed up movie writing but makes interaction more difficult.

Display options:
  -f, --fullscreen                  Request fullscreen mode.
  -m, --maximized                   Request a maximized window.
  -w, --windowed                    Request windowed mode.
  -t, --always-on-top               Request an always-on-top window.
  --resolution <W>x<H>              Request window resolution.
  --position <X>,<Y>                Request window position (if set, screen argument is ignored).
  --screen <N>                      Request window screen.
  --single-window                   Use a single window (no separate subwindows).
  --xr-mode <mode>                  Select XR (Extended Reality) mode ['default', 'off', 'on'].

Debug options:
  -d, --debug                       Debug (local stdout debugger).
  -b, --breakpoints                 Breakpoint list as source::line comma-separated pairs, no spaces (use %20 instead).
  --profiling                       Enable profiling in the script debugger.
  --gpu-profile                     Show a GPU profile of the tasks that took the most time during frame rendering.
  --gpu-validation                  Enable graphics API validation layers for debugging.
  --gpu-abort                       Abort on graphics API usage errors (usually validation layer errors). May help see the problem if your system freezes.
  --remote-debug <uri>              Remote debug (<protocol>://<host/IP>[:<port>], e.g. tcp://127.0.0.1:6007).
  --debug-collisions                Show collision shapes when running the scene.
  --debug-paths                     Show path lines when running the scene.
  --debug-navigation                Show navigation polygons when running the scene.
  --debug-stringnames               Print all StringName allocations to stdout when the engine quits.
  --frame-delay <ms>                Simulate high CPU load (delay each frame by <ms> milliseconds).
  --time-scale <scale>              Force time scale (higher values are faster, 1.0 is normal speed).
  --disable-vsync                   Forces disabling of vertical synchronization, even if enabled in the project settings. Does not override driver-level V-Sync enforcement.
  --disable-render-loop             Disable render loop so rendering only occurs when called explicitly from script.
  --disable-crash-handler           Disable crash handler when supported by the platform code.
  --fixed-fps <fps>                 Force a fixed number of frames per second. This setting disables real-time synchronization.
  --print-fps                       Print the frames per second to the stdout.

Standalone tools:
  -s, --script <script>             Run a script.
  --check-only                      Only parse for errors and quit (use with --script).
  --export-release <preset> <path>  Export the project in release mode using the given preset and output path. The preset name should match one defined in export_presets.cfg.
                                    <path> should be absolute or relative to the project directory, and include the filename for the binary (e.g. 'builds/game.exe').
                                    The target directory must exist.
  --export-debug <preset> <path>    Export the project in debug mode using the given preset and output path. See --export-release description for other considerations.
  --export-pack <preset> <path>     Export the project data only using the given preset and output path. The <path> extension determines whether it will be in PCK or ZIP format.
  --convert-3to4 [<max_file_kb>] [<max_line_size>]
                                    Converts project from Godot 3.x to Godot 4.x.
  --validate-conversion-3to4 [<max_file_kb>] [<max_line_size>]
                                    Shows what elements will be renamed when converting project from Godot 3.x to Godot 4.x.
  --doctool [<path>]                Dump the engine API reference to the given <path> (defaults to current dir) in XML format, merging if existing files are found.
  --no-docbase                      Disallow dumping the base types (used with --doctool).
  --build-solutions                 Build the scripting solutions (e.g. for C# projects). Implies --editor and requires a valid project to edit.
  --dump-gdextension-interface      Generate GDExtension header file 'gdextension_interface.h' in the current folder. This file is the base file required to implement a GDExtension.
  --dump-extension-api              Generate JSON dump of the Godot API for GDExtension bindings named 'extension_api.json' in the current folder.
  --startup-benchmark               Benchmark the startup time and print it to console.
  --startup-benchmark-file <path>   Benchmark the startup time and save it to a given file in JSON format.

常规选项 - 显示版本字符串

--version

显示版本字符串。

else if (I->get() == "--version") {
	print_line(get_full_version_string());
	exit_code = ERR_HELP; // Hack to force an early exit in `main()` with a success code.
	goto error;

} 

 大致如此。

汇总

常规选项

命令

描述

-h, --help, /?

显示命令行选项列表。

--version

显示版本字符串。

-v, --verbose

使用冗长输出模式。

--quiet

安静模式, 静默输出的信息. 但错误仍然会显示.

运行选项

命令

描述

-e, --editor

启动编辑器,不运行场景(必须已启用 tools)。

-p, --project-manager

启动项目管理器, 即使一个项目已经被自动检测到 ( 工具 必须处于开启状态).

-q, --quit

第一次迭代后退出.

-l <locale>, --language <locale>

使用指定的区域设置(<locale> 是一个两个字母的代码)。详情请参阅 区域设置。

--path <目录>

项目的路径(<directory> 目录中必须包含一个“project.godot”文件)。

-u, --upwards

向上扫描文件夹中的“project.godot”文件。

--main-pack <file>

要加载的包(.pck)文件的路径。

--render-thread <模式>

渲染线程模式('unsafe','safe', 'separate'). 阅读 线程模式 以获得更多细节.

--remote-fs <地址>

远端文件系统 (<主机名/IP>[:<端口号>] 地址).

--audio-driver <驱动>

音频驱动. 先使用 --help 来显示可用的驱动列表.

--video-driver <驱动>

视频驱动. 先使用 --help 来显示可用的驱动列表.

显示选项

命令

描述

-f, --fullscreen

请求使用全屏模式.

-m, --maximized

请求一个最大化了的窗口.

-w, --windowed

要求窗口模式.

-t, --always-on-top

请求一个总在最顶的窗口.

--resolution <W>x<H>

请求窗口分辨率.

--position <X>,<Y>

指定屏幕位置.

--low-dpi

强制低解析度模式(仅在macOS 和 Windows 中可用).

--no-window

使用不可见窗口运行时,与 --script 一起使用,将很有用。

调试选项

备注

调试模式仅仅在编辑器和调试输出模板中起作用(这要求使用 debug 或 release_debug 构建目标, 阅读 目标 以获得更多信息).

命令

描述

-d, --debug

调试(本地标准输出调试器).

-b, --breakpoints

断点列表作为 source::line 逗号分隔对时,没有空格(使用 %%20 代替)。

--profiling

在脚本调试器中启用分析.

--remote-debug <地址>

远程调试 (<主机名/IP>:<端口号> 地址).

--debug-collisions

运行场景时显示碰撞框的形状.

--debug-navigation

当运行场景时显示多边形导航.

--frame-delay <ms>

模拟高 CPU 负载(每帧延迟 <ms> 毫秒)。

--time-scale <缩放>

强制时间缩放(值越大, 速度越快,1.0是正常速度).

--disable-render-loop

禁用渲染循环, 以便仅在从脚本显式调用时才进行渲染.

--disable-crash-handler

当平台代码支持时, 禁用崩溃处理程序.

--fixed-fps <帧率>

每秒强制固定数量的帧. 此设置禁用实时同步.

--print-fps

打印每秒的帧数到标准输出上.

单独的工具

命令

描述

-s <script>, --script <script>

运行脚本.

--check-only

仅解析错误并退出(与 --script 一起使用)。

--export <平台>

使用给定的导出平台导出项目. 仅当路径以.pck或.zip结尾时才导出主包(必须启用 tools ).

--export-debug <平台>

像 --export 一样,但是使用调试模板(必须已启用 tools)。

--doctool <路径>

将引擎 API 参考以 XML 格式转储到给定的 <路径> 中,如果发现现有文件则合并(必须已启用 tools)。

--no-docbase

禁止转储基本类型(和 --doctool 一起使用, 工具 必须启用).

--build-solutions

构建脚本解决方案(例如用于构建C#项目, 必须启用 tools).

--gdnative-generate-json-api

为GDNative绑定生成Godot API的JSON输出(必须启用 tools).

--test <test>

运行单元测试. 可以先用 --help 显示测试列表.(必须启用 tools).

--export-pack <预设> <路径>

像 --export 一样,它只会以预设的参数导出游戏包。<路径> 决定导出的游戏包文件后缀名为 PCK 或者 ZIP(必须已启用 tools)。

其实,也不用太过于纠结钻研各命令行参数的含义,用的多了,就清楚了。

Godot运行方式

在调试过程中,发现Godot运行后打开工程管理器(Project Manager),选择目标工程后,进入编辑器,结果调试过程结束了。

经过几次折腾,大致明白Godot运行方式,包括工程管理器、编辑器、场景运行三种。这三种方式可以通过命令行参数来决定。

缺省情况下,为工程管理器模式

 在VS中配置调试命令参数为-p,即进入工程管理器模式

 如果要直接运行或调试编辑器,可配置命令参数为--path C:\Users\Administrator\Downloads\dodge_assets\dodge_assets -e ,将直接打开指定目录下的Godot工程,进行编辑 

直接运行工程,就直接指定--path路径,不带-p/-e参数即可

Godot带控制台运行方式

Godot支持控制台方式,源码console_wrapper_windows.cpp,学习了一下源码,没怎么看懂,主要是其中的几个主要函数从来没用过。不过这个功能学不学对后续没什么影响,因为我感觉加了控制台,就是增加了日志输出。在上一篇文章中,已经实现日志文件输出,所以不用控制台也是OK的。

int main(int argc, char *argv[]) {
	// Get executable name.
	WCHAR exe_name[MAX_PATH] = {};
	if (!GetModuleFileNameW(nullptr, exe_name, MAX_PATH)) {
		wprintf(L"GetModuleFileName failed, error %d\n", GetLastError());
		return -1;
	}

	// Get product name from the resources and set console title.
	DWORD ver_info_handle = 0;
	DWORD ver_info_size = GetFileVersionInfoSizeW(exe_name, &ver_info_handle);
	if (ver_info_size > 0) {
		LPBYTE ver_info = (LPBYTE)malloc(ver_info_size);
		if (ver_info) {
			if (GetFileVersionInfoW(exe_name, ver_info_handle, ver_info_size, ver_info)) {
				LPCWSTR text_ptr = nullptr;
				UINT text_size = 0;
				if (VerQueryValueW(ver_info, L"\\StringFileInfo\\040904b0\\ProductName", (void **)&text_ptr, &text_size) && (text_size > 0)) {
					SetConsoleTitleW(text_ptr);
				}
			}
			free(ver_info);
		}
	}

	// Enable virtual terminal sequences processing.
	HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE);
	DWORD out_mode = ENABLE_PROCESSED_OUTPUT | ENABLE_VIRTUAL_TERMINAL_PROCESSING;
	SetConsoleMode(stdout_handle, out_mode);

	// Find main executable name and check if it exist.
	static PCWSTR exe_renames[] = {
		L".console.exe",
		L"_console.exe",
		L" console.exe",
		L"console.exe",
		nullptr,
	};

	bool rename_found = false;
	for (int i = 0; exe_renames[i]; i++) {
		PWSTR c = StrRStrIW(exe_name, nullptr, exe_renames[i]);
		if (c) {
			CopyMemory(c, L".exe", sizeof(WCHAR) * 5);
			rename_found = true;
			break;
		}
	}
	if (!rename_found) {
		wprintf(L"Invalid wrapper executable name.\n");
		return -1;
	}

	DWORD file_attrib = GetFileAttributesW(exe_name);
	if (file_attrib == INVALID_FILE_ATTRIBUTES || (file_attrib & FILE_ATTRIBUTE_DIRECTORY)) {
		wprintf(L"Main executable %ls not found.\n", exe_name);
		return -1;
	}

	// Create job to monitor process tree.
	HANDLE job_handle = CreateJobObjectW(nullptr, nullptr);
	if (!job_handle) {
		wprintf(L"CreateJobObject failed, error %d\n", GetLastError());
		return -1;
	}

	HANDLE io_port_handle = CreateIoCompletionPort(INVALID_HANDLE_VALUE, nullptr, 0, 1);
	if (!io_port_handle) {
		wprintf(L"CreateIoCompletionPort failed, error %d\n", GetLastError());
		return -1;
	}

	JOBOBJECT_ASSOCIATE_COMPLETION_PORT compl_port;
	ZeroMemory(&compl_port, sizeof(compl_port));
	compl_port.CompletionKey = job_handle;
	compl_port.CompletionPort = io_port_handle;

	if (!SetInformationJobObject(job_handle, JobObjectAssociateCompletionPortInformation, &compl_port, sizeof(compl_port))) {
		wprintf(L"SetInformationJobObject(AssociateCompletionPortInformation) failed, error %d\n", GetLastError());
		return -1;
	}

	JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli;
	ZeroMemory(&jeli, sizeof(jeli));
	jeli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;

	if (!SetInformationJobObject(job_handle, JobObjectExtendedLimitInformation, &jeli, sizeof(jeli))) {
		wprintf(L"SetInformationJobObject(ExtendedLimitInformation) failed, error %d\n", GetLastError());
		return -1;
	}

	// Start the main process.
	PROCESS_INFORMATION pi;
	ZeroMemory(&pi, sizeof(pi));

	STARTUPINFOW si;
	ZeroMemory(&si, sizeof(si));
	si.cb = sizeof(si);

	WCHAR new_command_line[32767];
	_snwprintf_s(new_command_line, 32767, _TRUNCATE, L"%ls %ls", exe_name, PathGetArgsW(GetCommandLineW()));

	if (!CreateProcessW(nullptr, new_command_line, nullptr, nullptr, true, CREATE_SUSPENDED, nullptr, nullptr, &si, &pi)) {
		wprintf(L"CreateProcess failed, error %d\n", GetLastError());
		return -1;
	}

	if (!AssignProcessToJobObject(job_handle, pi.hProcess)) {
		wprintf(L"AssignProcessToJobObject failed, error %d\n", GetLastError());
		return -1;
	}

	ResumeThread(pi.hThread);
	CloseHandle(pi.hThread);

	// Wait until main process and all of its children are finished.
	DWORD completion_code = 0;
	ULONG_PTR completion_key = 0;
	LPOVERLAPPED overlapped = nullptr;

	while (GetQueuedCompletionStatus(io_port_handle, &completion_code, &completion_key, &overlapped, INFINITE)) {
		if ((HANDLE)completion_key == job_handle && completion_code == JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO) {
			break;
		}
	}

	CloseHandle(job_handle);
	CloseHandle(io_port_handle);

	// Get exit code of the main process.
	DWORD exit_code = 0;
	GetExitCodeProcess(pi.hProcess, &exit_code);

	CloseHandle(pi.hProcess);

	return exit_code;
}

Godot 4 源码分析 - 初探 准备研究GoDot 4源码。 阅读详情

相关推荐

Godot 4 源码分析 - 碰撞

在真实场景中,A、B都占据相应的空间位置(3D)或平面位置(2D),在运行过程中,A、B至少有一个能动,它们的相对位置可能会变化,在某个时刻会有交叠。具体而言,一个节点的Layer值必须包含在另一个节点的Mask值中,同时另一个节点的Layer值必须包含在该节点的Mask值中。Layer与Mask应该都是32位整数,对象A有Layer与Mask属性,对象B也有Layer与Mask属性。对于敌人对象之间,可将它们分配到相同的碰撞图层并设置相应的碰撞掩码,以确保它们不会互相碰撞。果然,与猜测的一致。

drgraph的博客 3858

Godot4 你的第一个2d游戏

Godot4 你的第一个2d游戏

Godot 4 源码分析 - 动态导入图片文件

用Godot 4尝试编一个电子书软件,初步效果已经出来,并且通过管道通信接口可以获取、设置属性、调用函数,貌似能处理各种事宜了。其实不然,外因通过内因起作用,如果没把里面搞明白,功能没有开放出来,则有些需求就不能实现。比如,现在想动态加载新的图书,这就是一个实际需求。如果每一本电子书,都需要导出一次,那这个软件就太不通用了。直接加载另一图片,结果不成功这就得研究一下了。

drgraph的博客 2761

Godot 4 源码分析 - 练手 - 和谐共生

今天看到一个微信视频,和谐共生,大概效果如下研究这么长时间的Godot,今天试试能否实现上述效果粗看一下,这个效果实现分几步:1. 画圆,并确定多个圆的位置规律2. 动点,并确定各动点的运动规律3. 综合调试。

drgraph的博客 1432

Godot 4 源码分析 - 代码自动补全流程

对于Script编辑器而言,code_complete_func指向ScriptTextEditor::_code_complete_scripts,本质上是调用GDScriptLanguage::complete_code函数。1) CodeTextEditor中创建时钟code_complete_timer,其timeout超时信号绑定_code_complete_timer_timeout函数。而_line_col_changed函数(绑定caret_changed事件)会停止时钟。

drgraph的博客 1633

Godot 4 源码分析 - 增加格式化字符串功能

这个过程中发现一个小问题:std::string没法直接转成String,String类提供了一堆构造函数,但就是没有std::string。Godot 4的主要字符串类型为String,已经设计得比较完善了,但有一个问题,格式化这块没怎么考虑。比如,要将Variant 转为 std::string,直接一路火花带闪电。不过fmt的使用方式是{},有点新鲜,貌似与C++ 20兼容,那就先用上。String中有一个format函数,但这个函数只有两个参数,这咋用?顺便再在网上转下,发现fmt库的评价不错。

drgraph的博客 1680

Godot 4 源码分析 - Project Manager

我之前一直用RAD开发Windows程序,哪里还见过这种自己从头搭起来的,比如create_project_item_control处理各工程项。_open_selected_projects_ask,其实最终调用_open_selected_projects。除去界面各控件外,就是加载工程项_load_recent_projects(),直接处理。至于其中的循环,因为在ProjectManager构造函数中,已设置。当然,还有ENTER键会直接调用_open_selected_projects_ask。

drgraph的博客 2940

Godot 4 源码分析 - 日志输出

使用软件,日志可以提供比较多的运行信息,研究日志也是一种学习。Godot有两种运行模式:带控制台与不带控制台。带控制台的情况下,运行时会打开一个DOS窗口,具体的日志信息就显示在DOS窗口中。但不带控制台,就我目前的了解,这些日志就不知道在哪里显示了。

drgraph的博客 2029

Godot 4 源码分析 - 获取属性信息

在管道通信基础上,可进行宿主程序与Godot的双向通信。先拿属性信息试试手。

drgraph的博客 1107

Godot 4 源码分析 - 获取脚本

继续测试自定义结构发送Book.script.TAutoTurn,结果返回为对象: <GDScript#-9223372010833313372>279. 16:18:07:517 > 【主线程】 > [Pipe.发送] > 发送数据中内容[DrGraph.87: Request - wait 1000 ms]:[int]类型 > 值 = 2[UnicodeString]类型 > 值 = Book.script[UnicodeString]类型 > 值 = TAutoTurn。

drgraph的博客 1525

Godot 4 源码分析 - Path2D与PathFollow2D

因为路径是有长度的,本例中为2400,randi()值将按2400取模得到最终的随机值0 - 2399,当然也可以归一化,设置其progress_ratio值为0.0 - 1.0,意思一样。从PathFollow2D代码来看,它派生于Node2D,所以具备transform属性:Position、Rotation、Scale、Skew,对于路径上的点使用而言,这些信息就足够了,能够确定这些点的位置、方向,其实就是一个矢量。查看源码,set_progress的逻辑不只是取模,还有限制范围。

drgraph的博客 2250

Godot Little Camera Preview与Godot 4.2+兼容性:升级指南与最佳实践

Godot Little Camera Preview是一款为Godot引擎设计的画中画风格预览插件,支持2D和3D相机实时预览。本指南将帮助开发者快速解决与Godot 4.2+版本的兼容性问题,掌握升级的关键步骤和最佳实践,确保插件功能稳定运行。 ## 插件核心功能与兼容性现状 Godot Little Camera Preview作为轻量级相机预览工具,主要提供以下核心功能: - 实时画中

gitblog_01129的博客 752

Godot 4 源码分析 - 文件读入编码处理

今天需要读入xml文件进行处理,结果读入一个带中文的文件时,出错了。当然程序还能运行,但编译器一直报错,而且XML解析也不正确。回头看了一下,原目标文件为GB2312编码。而Godot的FileAccess不支持别的编码。其实已经读入到w里,但String::parse_utf8出错。XML文本内容解析为图形效果。

drgraph的博客 1520

Godot4.x的整体架构图解析-源码阅读

Godot引擎核心架构解析 本文通过分析Godot 4.4.1源码,重点探讨了引擎的核心架构设计。文章首先指出官方架构图中关系表达不清晰的问题,进而绘制了UML类图来明确类之间的关系。特别分析了Variant与Object的关联实现,揭示了Variant作为通用数据容器如何通过内部ObjData结构持有Object引用。此外,以Sprite2D模块为例,详细说明了Scene模块与RenderingServer的依赖关系,展示了从纹理设置到最终渲染的完整调用链路。这些分析为深入理解Godot引擎的底层机制提供

Pengcode的博客 924

Godot 源码分析(二):Vulkan 渲染后端支持全景

Godot 4.0 起把图形 API 从 OpenGL ES 3.0 升级为,并保留了对三个后端。在深入 Godot 源码之前,先把这四个 API 放在一起做一个系统对比,搞清楚"为什么 Vulkan 是第一选择",而不是其他三个。

大坡3D软件开发 317

Godot 源码分析(四):Vulkan 上一层的调用接口(RenderingServer / RenderingDevice / RendererRD)

本文分析了Godot引擎中Vulkan渲染接口的层次架构,从上至下分为四层:1)RenderingServer单例层提供场景、材质等高层API;2)RendererRD层实现具体场景渲染器;3)RenderingDevice层抽象平台无关的GPU操作;4)Vulkan驱动层对接原生API。这种分层设计实现了三大目标:跨平台兼容性(支持Vulkan/Metal/D3D12等)、上层业务稳定性(保持Godot3到4的接口兼容)、统一的资源管线和命令接口。文章通过调用关系图展示了各层职责划分,并详细说明了分层架构

大坡3D软件开发 699

GDMaim版本兼容性:支持哪些Godot版本以及如何迁移到新版本

GDMaim是一款专为Godot引擎设计的GDScript代码混淆插件,为游戏开发者提供强大的代码保护方案。本文将详细介绍GDMaim的版本兼容性,包括支持的Godot版本范围、升级迁移指南,以及在不同版本间的平滑过渡策略。无论你是初次接触GDMaim的新手,还是计划升级到最新Godot版本的老用户,这篇文章都将为你提供完整的兼容性指南。 ## 📊 GDMaim支持的Godot版本矩阵 根据

gitblog_00592的博客 782

Godot4 你的第一个 3D 游戏 上集

Godot4 3D

watch361的博客 3813
上一篇: Godot 4 源码分析 - Project Manager
下一篇: Godot 4 源码分析 - 代码自动补全流程
DrGraph
博客等级 码龄14年 228粉丝 77原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值