Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix debugger behavior with multi-session debugging #82868

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
63 changes: 57 additions & 6 deletions editor/debugger/editor_debugger_node.cpp
Expand Up @@ -107,6 +107,8 @@ ScriptEditorDebugger *EditorDebuggerNode::_add_debugger() {
node->connect("remote_object_updated", callable_mp(this, &EditorDebuggerNode::_remote_object_updated).bind(id));
node->connect("remote_object_property_updated", callable_mp(this, &EditorDebuggerNode::_remote_object_property_updated).bind(id));
node->connect("remote_object_requested", callable_mp(this, &EditorDebuggerNode::_remote_object_requested).bind(id));
node->connect("set_breakpoint", callable_mp(this, &EditorDebuggerNode::_breakpoint_set_in_tree).bind(id));
node->connect("clear_breakpoints", callable_mp(this, &EditorDebuggerNode::_breakpoints_cleared_in_tree).bind(id));
node->connect("errors_cleared", callable_mp(this, &EditorDebuggerNode::_update_errors));

if (tabs->get_tab_count() > 0) {
Expand Down Expand Up @@ -168,6 +170,27 @@ void EditorDebuggerNode::_text_editor_stack_goto(const ScriptEditorDebugger *p_d
stack_script.unref(); // Why?!?
}

void EditorDebuggerNode::_text_editor_stack_clear(const ScriptEditorDebugger *p_debugger) {
String file = p_debugger->get_stack_script_file();
if (file.is_empty()) {
return;
}
if (file.is_resource_file()) {
stack_script = ResourceLoader::load(file);
} else {
// If the script is built-in, it can be opened only if the scene is loaded in memory.
int i = file.find("::");
int j = file.rfind("(", i);
if (j > -1) { // If the script is named, the string is "name (file)", so we need to extract the path.
file = file.substr(j + 1, file.find(")", i) - j - 1);
}
Ref<PackedScene> ps = ResourceLoader::load(file.get_slice("::", 0));
stack_script = ResourceLoader::load(file);
}
emit_signal(SNAME("clear_execution"), stack_script);
stack_script.unref(); // Why?!?
}

void EditorDebuggerNode::_bind_methods() {
// LiveDebug.
ClassDB::bind_method("live_debug_create_node", &EditorDebuggerNode::live_debug_create_node);
Expand All @@ -183,6 +206,8 @@ void EditorDebuggerNode::_bind_methods() {
ADD_SIGNAL(MethodInfo("clear_execution", PropertyInfo("script")));
ADD_SIGNAL(MethodInfo("breaked", PropertyInfo(Variant::BOOL, "reallydid"), PropertyInfo(Variant::BOOL, "can_debug")));
ADD_SIGNAL(MethodInfo("breakpoint_toggled", PropertyInfo(Variant::STRING, "path"), PropertyInfo(Variant::INT, "line"), PropertyInfo(Variant::BOOL, "enabled")));
ADD_SIGNAL(MethodInfo("breakpoint_set_in_tree", PropertyInfo("script"), PropertyInfo(Variant::INT, "line"), PropertyInfo(Variant::BOOL, "enabled"), PropertyInfo(Variant::INT, "debugger")));
ADD_SIGNAL(MethodInfo("breakpoints_cleared_in_tree", PropertyInfo(Variant::INT, "debugger")));
}

void EditorDebuggerNode::register_undo_redo(UndoRedo *p_undo_redo) {
Expand All @@ -198,6 +223,10 @@ ScriptEditorDebugger *EditorDebuggerNode::get_debugger(int p_id) const {
return Object::cast_to<ScriptEditorDebugger>(tabs->get_tab_control(p_id));
}

ScriptEditorDebugger *EditorDebuggerNode::get_previous_debugger() const {
return Object::cast_to<ScriptEditorDebugger>(tabs->get_tab_control(tabs->get_previous_tab()));
}

ScriptEditorDebugger *EditorDebuggerNode::get_current_debugger() const {
return Object::cast_to<ScriptEditorDebugger>(tabs->get_tab_control(tabs->get_current_tab()));
}
Expand Down Expand Up @@ -436,12 +465,18 @@ void EditorDebuggerNode::_debugger_changed(int p_tab) {
// Hopefully, in the future, we will have one inspector per debugger.
EditorNode::get_singleton()->push_item(nullptr);
}

if (get_previous_debugger()) {
_text_editor_stack_clear(get_previous_debugger());
}
if (remote_scene_tree->is_visible_in_tree()) {
get_current_debugger()->request_remote_tree();
}
if (get_current_debugger()->is_breaked()) {
_text_editor_stack_goto(get_current_debugger());
}

_break_state_changed();
}

void EditorDebuggerNode::set_script_debug_button(MenuButton *p_button) {
Expand Down Expand Up @@ -533,7 +568,7 @@ void EditorDebuggerNode::_breaked(bool p_breaked, bool p_can_debug, String p_mes
}

bool EditorDebuggerNode::is_skip_breakpoints() const {
return get_default_debugger()->is_skip_breakpoints();
return get_current_debugger()->is_skip_breakpoints();
}

void EditorDebuggerNode::set_breakpoint(const String &p_path, int p_line, bool p_enabled) {
Expand Down Expand Up @@ -565,23 +600,23 @@ void EditorDebuggerNode::reload_scripts() {
}

void EditorDebuggerNode::debug_next() {
get_default_debugger()->debug_next();
get_current_debugger()->debug_next();
}

void EditorDebuggerNode::debug_step() {
get_default_debugger()->debug_step();
get_current_debugger()->debug_step();
}

void EditorDebuggerNode::debug_break() {
get_default_debugger()->debug_break();
get_current_debugger()->debug_break();
}

void EditorDebuggerNode::debug_continue() {
get_default_debugger()->debug_continue();
get_current_debugger()->debug_continue();
}

String EditorDebuggerNode::get_var_value(const String &p_var) const {
return get_default_debugger()->get_var_value(p_var);
return get_current_debugger()->get_var_value(p_var);
}

// LiveEdit/Inspector
Expand Down Expand Up @@ -655,6 +690,22 @@ void EditorDebuggerNode::_save_node_requested(ObjectID p_id, const String &p_fil
get_current_debugger()->save_node(p_id, p_file);
}

void EditorDebuggerNode::_breakpoint_set_in_tree(Ref<RefCounted> p_script, int p_line, bool p_enabled, int p_debugger) {
if (p_debugger != tabs->get_current_tab()) {
return;
}

emit_signal(SNAME("breakpoint_set_in_tree"), p_script, p_line, p_enabled);
}

void EditorDebuggerNode::_breakpoints_cleared_in_tree(int p_debugger) {
if (p_debugger != tabs->get_current_tab()) {
return;
}

emit_signal(SNAME("breakpoints_cleared_in_tree"));
}

// Remote inspector/edit.
void EditorDebuggerNode::_method_changeds(void *p_ud, Object *p_base, const StringName &p_name, const Variant **p_args, int p_argcount) {
if (!singleton) {
Expand Down
5 changes: 5 additions & 0 deletions editor/debugger/editor_debugger_node.h
Expand Up @@ -138,11 +138,15 @@ class EditorDebuggerNode : public MarginContainer {
void _remote_object_requested(ObjectID p_id, int p_debugger);
void _save_node_requested(ObjectID p_id, const String &p_file, int p_debugger);

void _breakpoint_set_in_tree(Ref<RefCounted> p_script, int p_line, bool p_enabled, int p_debugger);
void _breakpoints_cleared_in_tree(int p_debugger);

void _clear_execution(Ref<RefCounted> p_script) {
emit_signal(SNAME("clear_execution"), p_script);
}

void _text_editor_stack_goto(const ScriptEditorDebugger *p_debugger);
void _text_editor_stack_clear(const ScriptEditorDebugger *p_debugger);
void _stack_frame_selected(int p_debugger);
void _error_selected(const String &p_file, int p_line, int p_debugger);
void _breaked(bool p_breaked, bool p_can_debug, String p_message, bool p_has_stackdump, int p_debugger);
Expand All @@ -159,6 +163,7 @@ class EditorDebuggerNode : public MarginContainer {
static EditorDebuggerNode *get_singleton() { return singleton; }
void register_undo_redo(UndoRedo *p_undo_redo);

ScriptEditorDebugger *get_previous_debugger() const;
ScriptEditorDebugger *get_current_debugger() const;
ScriptEditorDebugger *get_default_debugger() const;
ScriptEditorDebugger *get_debugger(int p_debugger) const;
Expand Down
4 changes: 2 additions & 2 deletions editor/plugins/script_editor_plugin.cpp
Expand Up @@ -4009,8 +4009,8 @@ ScriptEditor::ScriptEditor(WindowWrapper *p_wrapper) {
debugger->connect("set_execution", callable_mp(this, &ScriptEditor::_set_execution));
debugger->connect("clear_execution", callable_mp(this, &ScriptEditor::_clear_execution));
debugger->connect("breaked", callable_mp(this, &ScriptEditor::_breaked));
debugger->get_default_debugger()->connect("set_breakpoint", callable_mp(this, &ScriptEditor::_set_breakpoint));
debugger->get_default_debugger()->connect("clear_breakpoints", callable_mp(this, &ScriptEditor::_clear_breakpoints));
debugger->connect("breakpoint_set_in_tree", callable_mp(this, &ScriptEditor::_set_breakpoint));
debugger->connect("breakpoints_cleared_in_tree", callable_mp(this, &ScriptEditor::_clear_breakpoints));

menu_hb->add_spacer();

Expand Down