From fe27a72cb59d4039e25984355993428fc6f6739e Mon Sep 17 00:00:00 2001 From: David Snopek Date: Wed, 18 Jun 2025 10:12:34 -0500 Subject: [PATCH] Allow editor plugins to modify run arguments --- doc/classes/EditorPlugin.xml | 14 ++++++++++++++ editor/editor_node.cpp | 7 +++++++ editor/editor_node.h | 1 + editor/plugins/editor_plugin.cpp | 8 ++++++++ editor/plugins/editor_plugin.h | 2 ++ editor/run/editor_run_bar.cpp | 6 +++++- 6 files changed, 37 insertions(+), 1 deletion(-) diff --git a/doc/classes/EditorPlugin.xml b/doc/classes/EditorPlugin.xml index 9892d208329..5d3e7afab7b 100644 --- a/doc/classes/EditorPlugin.xml +++ b/doc/classes/EditorPlugin.xml @@ -362,6 +362,20 @@ Remember that you have to manage the visibility of all your editor controls manually. + + + + + + This function is called when an individual scene is about to be played in the editor. [param args] is a list of command line arguments that will be passed to the new Godot instance, which will be replaced by the list returned by this function. + [codeblock] + func _run_scene(scene, args): + args.append("--an-extra-argument") + return args + [/codeblock] + [b]Note:[/b] Text that is printed in this method will not be visible in the editor's Output panel unless [member EditorSettings.run/output/always_clear_output_on_play] is [code]false[/code]. + + diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index c32393a7803..960ff3c828d 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -7103,6 +7103,13 @@ bool EditorNode::call_build() { return builds_successful; } +void EditorNode::call_run_scene(const String &p_scene, Vector &r_args) { + for (int i = 0; i < editor_data.get_editor_plugin_count(); i++) { + EditorPlugin *plugin = editor_data.get_editor_plugin(i); + plugin->run_scene(p_scene, r_args); + } +} + void EditorNode::_inherit_imported(const String &p_action) { open_imported->hide(); load_scene(open_import_request, true, true); diff --git a/editor/editor_node.h b/editor/editor_node.h index ca147a05e0a..284f976a933 100644 --- a/editor/editor_node.h +++ b/editor/editor_node.h @@ -724,6 +724,7 @@ public: void _on_plugin_ready(Object *p_script, const String &p_activate_name); bool call_build(); + void call_run_scene(const String &p_scene, Vector &r_args); // This is a very naive estimation, but we need something now. Will be reworked later. bool is_editor_ready() const { return is_inside_tree() && !waiting_for_first_scan; } diff --git a/editor/plugins/editor_plugin.cpp b/editor/plugins/editor_plugin.cpp index e2567221363..c492b6327ef 100644 --- a/editor/plugins/editor_plugin.cpp +++ b/editor/plugins/editor_plugin.cpp @@ -531,6 +531,13 @@ bool EditorPlugin::build() { return success; } +void EditorPlugin::run_scene(const String &p_scene, Vector &r_args) { + Vector new_args; + if (GDVIRTUAL_CALL(_run_scene, p_scene, r_args, new_args)) { + r_args = new_args; + } +} + void EditorPlugin::queue_save_layout() { EditorNode::get_singleton()->save_editor_layout_delayed(); } @@ -665,6 +672,7 @@ void EditorPlugin::_bind_methods() { GDVIRTUAL_BIND(_set_window_layout, "configuration"); GDVIRTUAL_BIND(_get_window_layout, "configuration"); GDVIRTUAL_BIND(_build); + GDVIRTUAL_BIND(_run_scene, "scene", "args"); GDVIRTUAL_BIND(_enable_plugin); GDVIRTUAL_BIND(_disable_plugin); diff --git a/editor/plugins/editor_plugin.h b/editor/plugins/editor_plugin.h index 70e247f0bdb..d33e53f83e1 100644 --- a/editor/plugins/editor_plugin.h +++ b/editor/plugins/editor_plugin.h @@ -133,6 +133,7 @@ protected: GDVIRTUAL1(_set_window_layout, Ref) GDVIRTUAL1(_get_window_layout, Ref) GDVIRTUAL0R(bool, _build) + GDVIRTUAL2RC(Vector, _run_scene, String, Vector) GDVIRTUAL0(_enable_plugin) GDVIRTUAL0(_disable_plugin) @@ -202,6 +203,7 @@ public: virtual void get_window_layout(Ref p_layout); virtual void edited_scene_changed() {} // if changes are pending in editor, apply them virtual bool build(); // builds with external tools. Returns true if safe to continue running scene. + virtual void run_scene(const String &p_scene, Vector &r_args); EditorInterface *get_editor_interface(); ScriptCreateDialog *get_script_create_dialog(); diff --git a/editor/run/editor_run_bar.cpp b/editor/run/editor_run_bar.cpp index 1fad3e51036..89b4b510cf2 100644 --- a/editor/run/editor_run_bar.cpp +++ b/editor/run/editor_run_bar.cpp @@ -314,13 +314,17 @@ void EditorRunBar::_run_scene(const String &p_scene_path, const Vector & if (!EditorNode::get_singleton()->call_build()) { return; } + + Vector args = p_run_args; + EditorNode::get_singleton()->call_run_scene(run_filename, args); + // Use the existing URI, in case it is overridden by the CLI. String uri = EditorDebuggerNode::get_singleton()->get_server_uri(); if (uri.is_empty()) { uri = "tcp://"; } EditorDebuggerNode::get_singleton()->start(uri); - Error error = editor_run.run(run_filename, write_movie_file, p_run_args); + Error error = editor_run.run(run_filename, write_movie_file, args); if (error != OK) { EditorDebuggerNode::get_singleton()->stop(); EditorNode::get_singleton()->show_accept(TTR("Could not start subprocess(es)!"), TTR("OK"));