Skip to content

Commit cc21f5f

Browse files
committed
Allow editor plugins to modify run arguments and re-run from within project
1 parent 48f361a commit cc21f5f

File tree

10 files changed

+68
-1
lines changed

10 files changed

+68
-1
lines changed

doc/classes/EditorPlugin.xml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,19 @@
362362
Remember that you have to manage the visibility of all your editor controls manually.
363363
</description>
364364
</method>
365+
<method name="_run_scene" qualifiers="virtual">
366+
<return type="PackedStringArray" />
367+
<param index="0" name="scene" type="String" />
368+
<param index="1" name="args" type="PackedStringArray" />
369+
<description>
370+
This function will be called when the project or individual scene is about to be played in the editor. The [param args] to run Godot are passed in, and will be replaced by the return value.
371+
[codeblock]
372+
func _run_scene(scene, args):
373+
args.push_back("--an-extra-argument")
374+
return args
375+
[/codeblock]
376+
</description>
377+
</method>
365378
<method name="_save_external_data" qualifiers="virtual">
366379
<return type="void" />
367380
<description>

editor/debugger/editor_debugger_node.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ ScriptEditorDebugger *EditorDebuggerNode::_add_debugger() {
121121
node->connect("set_breakpoint", callable_mp(this, &EditorDebuggerNode::_breakpoint_set_in_tree).bind(id));
122122
node->connect("clear_breakpoints", callable_mp(this, &EditorDebuggerNode::_breakpoints_cleared_in_tree).bind(id));
123123
node->connect("errors_cleared", callable_mp(this, &EditorDebuggerNode::_update_errors));
124+
node->connect("run_scene_requested", callable_mp(this, &EditorDebuggerNode::_run_scene_requested).bind(id));
124125

125126
if (tabs->get_tab_count() > 0) {
126127
get_debugger(0)->clear_style();
@@ -780,6 +781,24 @@ void EditorDebuggerNode::_save_node_requested(ObjectID p_id, const String &p_fil
780781
get_current_debugger()->save_node(p_id, p_file);
781782
}
782783

784+
void EditorDebuggerNode::_run_scene_requested(const String &p_scene, const Vector<String> &p_args, int p_debugger) {
785+
EditorRunBar *editor_run_bar = EditorRunBar::get_singleton();
786+
ERR_FAIL_NULL(editor_run_bar);
787+
788+
editor_run_bar->stop_playing();
789+
790+
// Defer starting the new one, so the old one has a chance to fully stop.
791+
callable_mp(this, &EditorDebuggerNode::_run_scene_internal).call_deferred(editor_run_bar, p_scene, p_args);
792+
}
793+
794+
void EditorDebuggerNode::_run_scene_internal(EditorRunBar *p_editor_run_bar, const String &p_scene, const Vector<String> &p_args) {
795+
if (p_scene.is_empty()) {
796+
p_editor_run_bar->play_main_scene(false);
797+
} else {
798+
p_editor_run_bar->play_custom_scene(p_scene, p_args);
799+
}
800+
}
801+
783802
void EditorDebuggerNode::_breakpoint_set_in_tree(Ref<RefCounted> p_script, int p_line, bool p_enabled, int p_debugger) {
784803
if (p_debugger != tabs->get_current_tab()) {
785804
return;

editor/debugger/editor_debugger_node.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ class DebugAdapterParser;
3939
class EditorDebuggerPlugin;
4040
class EditorDebuggerTree;
4141
class EditorDebuggerRemoteObjects;
42+
class EditorRunBar;
4243
class MenuButton;
4344
class ScriptEditorDebugger;
4445
class TabContainer;
@@ -143,6 +144,9 @@ class EditorDebuggerNode : public MarginContainer {
143144
void _remote_selection_cleared(int p_debugger);
144145
void _save_node_requested(ObjectID p_id, const String &p_file, int p_debugger);
145146

147+
void _run_scene_requested(const String &p_scene, const Vector<String> &p_args, int p_debugger);
148+
void _run_scene_internal(EditorRunBar *p_editor_run_bar, const String &p_scene, const Vector<String> &p_args);
149+
146150
void _breakpoint_set_in_tree(Ref<RefCounted> p_script, int p_line, bool p_enabled, int p_debugger);
147151
void _breakpoints_cleared_in_tree(int p_debugger);
148152

editor/debugger/script_editor_debugger.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -926,6 +926,11 @@ void ScriptEditorDebugger::_msg_embed_next_frame(uint64_t p_thread_id, const Arr
926926
emit_signal(SNAME("embed_shortcut_requested"), EMBED_NEXT_FRAME);
927927
}
928928

929+
void ScriptEditorDebugger::_msg_run_scene(uint64_t p_thread_id, const Array &p_data) {
930+
ERR_FAIL_COND(p_data.size() < 2);
931+
emit_signal(SNAME("run_scene_requested"), p_data[0], p_data[1]);
932+
}
933+
929934
void ScriptEditorDebugger::_parse_message(const String &p_msg, uint64_t p_thread_id, const Array &p_data) {
930935
emit_signal(SNAME("debug_data"), p_msg, p_data);
931936

@@ -976,6 +981,7 @@ void ScriptEditorDebugger::_init_parse_message_handlers() {
976981
parse_message_handlers["window:title"] = &ScriptEditorDebugger::_msg_window_title;
977982
parse_message_handlers["request_embed_suspend_toggle"] = &ScriptEditorDebugger::_msg_embed_suspend_toggle;
978983
parse_message_handlers["request_embed_next_frame"] = &ScriptEditorDebugger::_msg_embed_next_frame;
984+
parse_message_handlers["request_run_scene"] = &ScriptEditorDebugger::_msg_run_scene;
979985
}
980986

981987
void ScriptEditorDebugger::_set_reason_text(const String &p_reason, MessageType p_type) {
@@ -1944,6 +1950,7 @@ void ScriptEditorDebugger::_bind_methods() {
19441950
ADD_SIGNAL(MethodInfo("clear_breakpoints"));
19451951
ADD_SIGNAL(MethodInfo("errors_cleared"));
19461952
ADD_SIGNAL(MethodInfo("embed_shortcut_requested", PropertyInfo(Variant::INT, "embed_shortcut_action")));
1953+
ADD_SIGNAL(MethodInfo("run_scene_requested", PropertyInfo(Variant::STRING, "scene"), PropertyInfo(Variant::PACKED_STRING_ARRAY, "args")));
19471954
}
19481955

19491956
void ScriptEditorDebugger::add_debugger_tab(Control *p_control) {

editor/debugger/script_editor_debugger.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,7 @@ class ScriptEditorDebugger : public MarginContainer {
228228
void _msg_window_title(uint64_t p_thread_id, const Array &p_data);
229229
void _msg_embed_suspend_toggle(uint64_t p_thread_id, const Array &p_data);
230230
void _msg_embed_next_frame(uint64_t p_thread_id, const Array &p_data);
231+
void _msg_run_scene(uint64_t p_thread_id, const Array &p_data);
231232

232233
void _parse_message(const String &p_msg, uint64_t p_thread_id, const Array &p_data);
233234
void _set_reason_text(const String &p_reason, MessageType p_type);

editor/editor_node.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6975,6 +6975,15 @@ bool EditorNode::call_build() {
69756975
return builds_successful;
69766976
}
69776977

6978+
Vector<String> EditorNode::call_run_scene(const String &p_scene, const Vector<String> &p_args) {
6979+
Vector<String> args = p_args;
6980+
for (int i = 0; i < editor_data.get_editor_plugin_count(); i++) {
6981+
EditorPlugin *plugin = editor_data.get_editor_plugin(i);
6982+
args = plugin->run_scene(p_scene, args);
6983+
}
6984+
return args;
6985+
}
6986+
69786987
void EditorNode::_inherit_imported(const String &p_action) {
69796988
open_imported->hide();
69806989
load_scene(open_import_request, true, true);

editor/editor_node.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -727,6 +727,7 @@ class EditorNode : public Node {
727727
void _on_plugin_ready(Object *p_script, const String &p_activate_name);
728728

729729
bool call_build();
730+
Vector<String> call_run_scene(const String &p_scene, const Vector<String> &p_args);
730731

731732
// This is a very naive estimation, but we need something now. Will be reworked later.
732733
bool is_editor_ready() const { return is_inside_tree() && !waiting_for_first_scan; }

editor/gui/editor_run_bar.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,8 +315,10 @@ void EditorRunBar::_run_scene(const String &p_scene_path, const Vector<String> &
315315
return;
316316
}
317317

318+
Vector<String> args = EditorNode::get_singleton()->call_run_scene(run_filename, p_run_args);
319+
318320
EditorDebuggerNode::get_singleton()->start();
319-
Error error = editor_run.run(run_filename, write_movie_file, p_run_args);
321+
Error error = editor_run.run(run_filename, write_movie_file, args);
320322
if (error != OK) {
321323
EditorDebuggerNode::get_singleton()->stop();
322324
EditorNode::get_singleton()->show_accept(TTR("Could not start subprocess(es)!"), TTR("OK"));

editor/plugins/editor_plugin.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,14 @@ bool EditorPlugin::build() {
531531
return success;
532532
}
533533

534+
Vector<String> EditorPlugin::run_scene(const String &p_scene, const Vector<String> &p_args) {
535+
Vector<String> new_args;
536+
if (GDVIRTUAL_CALL(_run_scene, p_scene, p_args, new_args)) {
537+
return new_args;
538+
}
539+
return p_args;
540+
}
541+
534542
void EditorPlugin::queue_save_layout() {
535543
EditorNode::get_singleton()->save_editor_layout_delayed();
536544
}
@@ -665,6 +673,7 @@ void EditorPlugin::_bind_methods() {
665673
GDVIRTUAL_BIND(_set_window_layout, "configuration");
666674
GDVIRTUAL_BIND(_get_window_layout, "configuration");
667675
GDVIRTUAL_BIND(_build);
676+
GDVIRTUAL_BIND(_run_scene, "scene", "args");
668677
GDVIRTUAL_BIND(_enable_plugin);
669678
GDVIRTUAL_BIND(_disable_plugin);
670679

editor/plugins/editor_plugin.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ class EditorPlugin : public Node {
133133
GDVIRTUAL1(_set_window_layout, Ref<ConfigFile>)
134134
GDVIRTUAL1(_get_window_layout, Ref<ConfigFile>)
135135
GDVIRTUAL0R(bool, _build)
136+
GDVIRTUAL2R(Vector<String>, _run_scene, String, Vector<String>)
136137
GDVIRTUAL0(_enable_plugin)
137138
GDVIRTUAL0(_disable_plugin)
138139

@@ -202,6 +203,7 @@ class EditorPlugin : public Node {
202203
virtual void get_window_layout(Ref<ConfigFile> p_layout);
203204
virtual void edited_scene_changed() {} // if changes are pending in editor, apply them
204205
virtual bool build(); // builds with external tools. Returns true if safe to continue running scene.
206+
virtual Vector<String> run_scene(const String &p_scene, const Vector<String> &p_args);
205207

206208
EditorInterface *get_editor_interface();
207209
ScriptCreateDialog *get_script_create_dialog();

0 commit comments

Comments
 (0)