diff options
author | Rémi Verschelde <rverschelde@gmail.com> | 2021-06-16 19:08:29 +0200 |
---|---|---|
committer | Rémi Verschelde <rverschelde@gmail.com> | 2021-06-16 19:11:08 +0200 |
commit | aa2215e6810f9d2f50552a1de7a688e3ac13a4ae (patch) | |
tree | 78577e002576b5d9f44c43417804303a746345ac | |
parent | 48fe9c97948f44125e68f3b8f67eaaf032c763bd (diff) |
Main: Fixup bogus fallback to project manager with more bolognese
WARNING: Hacks everywhere!
The logic in `main.cpp` is due a full rewrite as it's extremely hacky,
splitting argument parsing over several functions, with a mess of global state
and assumptions about what combinations of arguments or lack thereof should
mean in terms of what we want to read: game, editor, project manager, or
command line tools such as `--doctool`, `--export` or `--script`.
Until this is fully rewritten, this patch hacks things some more to ensure
that we don't fall back to the project manager in cases where it's not
warranted, and especially not *too late*, as it can mean that we haven't
properly initialized stuff like `EditorPaths` needed by the PM (which in turn
impacts what kind of path will be used for logs and the shader cache, etc...
the rabbit hole goes deep).
Fixes #41435.
Fixes #49392.
Fixes #49658.
Fixes https://github.com/godotengine/godot/issues/38202#issuecomment-773158477.
-rw-r--r-- | editor/editor_paths.cpp | 4 | ||||
-rw-r--r-- | main/main.cpp | 56 | ||||
-rw-r--r-- | main/main.h | 1 |
3 files changed, 42 insertions, 19 deletions
diff --git a/editor/editor_paths.cpp b/editor/editor_paths.cpp index 323707ec6c..c9817190dd 100644 --- a/editor/editor_paths.cpp +++ b/editor/editor_paths.cpp @@ -186,7 +186,7 @@ EditorPaths::EditorPaths() { // Validate or create project-specific editor data dir (`res://.godot`), // including shader cache subdir. - if (Main::is_project_manager()) { + if (Main::is_project_manager() || Main::is_cmdline_tool()) { // Nothing to create, use shared editor data dir for shader cache. Engine::get_singleton()->set_shader_cache_path(data_dir); } else { @@ -209,6 +209,4 @@ EditorPaths::EditorPaths() { dir_res->make_dir(ProjectSettings::IMPORTED_FILES_PATH); } } - - print_line("paths valid: " + itos((int)paths_valid)); } diff --git a/main/main.cpp b/main/main.cpp index f1905fc47b..667aebebae 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -137,6 +137,7 @@ static int audio_driver_idx = -1; static bool single_window = false; static bool editor = false; static bool project_manager = false; +static bool cmdline_tool = false; static String locale; static bool show_help = false; static bool auto_quit = false; @@ -185,6 +186,10 @@ bool Main::is_project_manager() { return project_manager; } +bool Main::is_cmdline_tool() { + return cmdline_tool; +} + static String unescape_cmdline(const String &p_str) { return p_str.replace("%20", " "); } @@ -881,18 +886,25 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph auto_build_solutions = true; editor = true; + cmdline_tool = true; #ifdef DEBUG_METHODS_ENABLED } else if (I->get() == "--gdnative-generate-json-api" || I->get() == "--gdnative-generate-json-builtin-api") { // Register as an editor instance to use low-end fallback if relevant. editor = true; + cmdline_tool = true; // We still pass it to the main arguments since the argument handling itself is not done in this function main_args.push_back(I->get()); #endif } else if (I->get() == "--export" || I->get() == "--export-debug" || I->get() == "--export-pack") { // Export project - + // Actually handling is done in start(). editor = true; + cmdline_tool = true; + main_args.push_back(I->get()); + } else if (I->get() == "--doctool") { + // Actually handling is done in start(). + cmdline_tool = true; main_args.push_back(I->get()); #endif } else if (I->get() == "--path") { // set path of project to start or edit @@ -1125,8 +1137,8 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph } if (!project_manager && !editor) { - // Determine if the project manager should be requested - project_manager = main_args.size() == 0 && !found_project; + // If we didn't find a project, we fall back to the project manager. + project_manager = !found_project && !cmdline_tool; } #endif @@ -1452,7 +1464,7 @@ Error Main::setup2(Thread::ID p_main_tid_override) { #endif #ifdef TOOLS_ENABLED - if (editor || project_manager) { + if (editor || project_manager || cmdline_tool) { EditorPaths::create(); } #endif @@ -1577,7 +1589,7 @@ Error Main::setup2(Thread::ID p_main_tid_override) { print_verbose("Using \"" + tablet_driver + "\" pen tablet driver..."); - /* Initialize Visual Server */ + /* Initialize Rendering Server */ rendering_server = memnew(RenderingServerDefault(OS::get_singleton()->get_render_thread_mode() == OS::RENDER_SEPARATE_THREAD)); @@ -1828,13 +1840,13 @@ bool Main::start() { ERR_FAIL_COND_V(!_start_success, false); bool hasicon = false; - String doc_tool_path; String positional_arg; String game_path; String script; bool check_only = false; #ifdef TOOLS_ENABLED + String doc_tool_path; bool doc_base = true; String _export_preset; bool export_debug = false; @@ -1844,8 +1856,9 @@ bool Main::start() { main_timer_sync.init(OS::get_singleton()->get_ticks_usec()); List<String> args = OS::get_singleton()->get_cmdline_args(); - // parameters that do not have an argument to the right for (int i = 0; i < args.size(); i++) { + // First check parameters that do not have an argument to the right. + // Doctest Unit Testing Handler // Designed to override and pass arguments to the unit test handler. if (args[i] == "--check-only") { @@ -1875,7 +1888,7 @@ bool Main::start() { game_path = args[i]; } } - //parameters that have an argument to the right + // Then parameters that have an argument to the right. else if (i < (args.size() - 1)) { bool parsed_pair = true; if (args[i] == "-s" || args[i] == "--script") { @@ -1907,16 +1920,19 @@ bool Main::start() { if (parsed_pair) { i++; } - } else if (args[i] == "--doctool") { - // Handle case where no path is given to --doctool. + } +#ifdef TOOLS_ENABLED + // Handle case where no path is given to --doctool. + else if (args[i] == "--doctool") { doc_tool_path = "."; } +#endif } #ifdef TOOLS_ENABLED if (doc_tool_path != "") { - Engine::get_singleton()->set_editor_hint( - true); // Needed to instance editor-only classes for their default values + // Needed to instance editor-only classes for their default values + Engine::get_singleton()->set_editor_hint(true); { DirAccessRef da = DirAccess::open(doc_tool_path); @@ -1988,17 +2004,26 @@ bool Main::start() { return false; } - #endif if (script == "" && game_path == "" && String(GLOBAL_GET("application/run/main_scene")) != "") { game_path = GLOBAL_GET("application/run/main_scene"); } +#ifdef TOOLS_ENABLED + if (!editor && !project_manager && !cmdline_tool && script == "" && game_path == "") { + // If we end up here, it means we didn't manage to detect what we want to run. + // Let's throw an error gently. The code leading to this is pretty brittle so + // this might end up triggered by valid usage, in which case we'll have to + // fine-tune further. + ERR_FAIL_V_MSG(false, "Couldn't detect whether to run the editor, the project manager or a specific project. Aborting."); + } +#endif + MainLoop *main_loop = nullptr; if (editor) { main_loop = memnew(SceneTree); - }; + } String main_loop_type = GLOBAL_DEF("application/run/main_loop_type", "SceneTree"); if (script != "") { @@ -2360,14 +2385,13 @@ bool Main::start() { } #ifdef TOOLS_ENABLED - if (project_manager || (script == "" && game_path == "" && !editor)) { + if (project_manager) { Engine::get_singleton()->set_editor_hint(true); ProjectManager *pmanager = memnew(ProjectManager); ProgressDialog *progress_dialog = memnew(ProgressDialog); pmanager->add_child(progress_dialog); sml->get_root()->add_child(pmanager); DisplayServer::get_singleton()->set_context(DisplayServer::CONTEXT_PROJECTMAN); - project_manager = true; } if (project_manager || editor) { diff --git a/main/main.h b/main/main.h index f4fff6b97e..84077137ba 100644 --- a/main/main.h +++ b/main/main.h @@ -45,6 +45,7 @@ class Main { public: static bool is_project_manager(); + static bool is_cmdline_tool(); static int test_entrypoint(int argc, char *argv[], bool &tests_need_run); static Error setup(const char *execpath, int argc, char *argv[], bool p_second_phase = true); static Error setup2(Thread::ID p_main_tid_override = 0); |