浏览代码

[macOS] Do not use NSApplication main loop for headless mode.

Pāvels Nadtočajevs 1 月之前
父节点
当前提交
8b045ca8fe
共有 3 个文件被更改,包括 69 次插入0 次删除
  1. 9 0
      platform/macos/godot_main_macos.mm
  2. 7 0
      platform/macos/os_macos.h
  3. 53 0
      platform/macos/os_macos.mm

+ 9 - 0
platform/macos/godot_main_macos.mm

@@ -56,6 +56,7 @@ int main(int argc, char **argv) {
 
 	int wait_for_debugger = 0; // wait 5 second by default
 	bool is_embedded = false;
+	bool is_headless = false;
 
 	for (int i = 0; i < argc; i++) {
 		if (strcmp("-NSDocumentRevisionsDebugMode", argv[i]) == 0) {
@@ -75,6 +76,12 @@ int main(int argc, char **argv) {
 		if (strcmp("--embedded", argv[i]) == 0) {
 			is_embedded = true;
 		}
+		if (strcmp("--headless", argv[i]) == 0 || strcmp("--doctool", argv[i]) == 0) {
+			is_headless = true;
+		}
+		if (i < argc - 1 && strcmp("--display-driver", argv[i]) == 0 && strcmp("headless", argv[i + 1]) == 0) {
+			is_headless = true;
+		}
 
 		args.ptr()[argsc] = argv[i];
 		argsc++;
@@ -90,6 +97,8 @@ int main(int argc, char **argv) {
 		WARN_PRINT("Embedded mode is not supported in release builds.");
 		return EXIT_FAILURE;
 #endif
+	} else if (is_headless) {
+		os = memnew(OS_MacOS_Headless(args[0], remaining_args, remaining_args > 0 ? &args[1] : nullptr));
 	} else {
 		os = memnew(OS_MacOS_NSApp(args[0], remaining_args, remaining_args > 0 ? &args[1] : nullptr));
 	}

+ 7 - 0
platform/macos/os_macos.h

@@ -171,6 +171,13 @@ public:
 	OS_MacOS_NSApp(const char *p_execpath, int p_argc, char **p_argv);
 };
 
+class OS_MacOS_Headless : public OS_MacOS {
+public:
+	virtual void run() override;
+
+	OS_MacOS_Headless(const char *p_execpath, int p_argc, char **p_argv);
+};
+
 #ifdef DEBUG_ENABLED
 
 class OS_MacOS_Embedded : public OS_MacOS {

+ 53 - 0
platform/macos/os_macos.mm

@@ -1171,6 +1171,59 @@ OS_MacOS_NSApp::OS_MacOS_NSApp(const char *p_execpath, int p_argc, char **p_argv
 	sigaction(SIGINT, &action, nullptr);
 }
 
+// MARK: - OS_MacOS_Headless
+
+void OS_MacOS_Headless::run() {
+	CFRunLoopGetCurrent();
+
+	@autoreleasepool {
+		Error err = Main::setup(execpath, argc, argv);
+		if (err != OK) {
+			if (err == ERR_HELP) {
+				return set_exit_code(EXIT_SUCCESS);
+			}
+			return set_exit_code(EXIT_FAILURE);
+		}
+	}
+
+	int ret;
+	@autoreleasepool {
+		ret = Main::start();
+	}
+
+	if (ret == EXIT_SUCCESS && main_loop) {
+		@autoreleasepool {
+			main_loop->initialize();
+		}
+
+		while (true) {
+			@autoreleasepool {
+				@try {
+					if (Input::get_singleton()) {
+						Input::get_singleton()->flush_buffered_events();
+					}
+
+					if (Main::iteration()) {
+						break;
+					}
+
+					CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, 0);
+				} @catch (NSException *exception) {
+					ERR_PRINT("NSException: " + String::utf8([exception reason].UTF8String));
+				}
+			}
+		}
+
+		main_loop->finalize();
+	}
+
+	Main::cleanup();
+}
+
+OS_MacOS_Headless::OS_MacOS_Headless(const char *p_execpath, int p_argc, char **p_argv) :
+		OS_MacOS(p_execpath, p_argc, p_argv) {
+}
+
 // MARK: - OS_MacOS_Embedded
 
 #ifdef DEBUG_ENABLED