/*************************************************************************/ /* editor_debugger_node.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ /* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ /* "Software"), to deal in the Software without restriction, including */ /* without limitation the rights to use, copy, modify, merge, publish, */ /* distribute, sublicense, and/or sell copies of the Software, and to */ /* permit persons to whom the Software is furnished to do so, subject to */ /* the following conditions: */ /* */ /* The above copyright notice and this permission notice shall be */ /* included in all copies or substantial portions of the Software. */ /* */ /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ #include "editor_debugger_node.h" #include "editor/debugger/editor_debugger_tree.h" #include "editor/editor_log.h" #include "editor/editor_node.h" #include "editor/plugins/script_editor_plugin.h" template void _for_all(TabContainer *p_node, const Func &p_func) { for (int i = 0; i < p_node->get_tab_count(); i++) { ScriptEditorDebugger *dbg = Object::cast_to(p_node->get_tab_control(i)); ERR_FAIL_COND(!dbg); p_func(dbg); } } EditorDebuggerNode *EditorDebuggerNode::singleton = NULL; EditorDebuggerNode::EditorDebuggerNode() { if (!singleton) singleton = this; server.instance(); add_constant_override("margin_left", -EditorNode::get_singleton()->get_gui_base()->get_stylebox("BottomPanelDebuggerOverride", "EditorStyles")->get_margin(MARGIN_LEFT)); add_constant_override("margin_right", -EditorNode::get_singleton()->get_gui_base()->get_stylebox("BottomPanelDebuggerOverride", "EditorStyles")->get_margin(MARGIN_RIGHT)); tabs = memnew(TabContainer); tabs->set_tab_align(TabContainer::ALIGN_LEFT); tabs->set_tabs_visible(false); tabs->connect_compat("tab_changed", this, "_debugger_changed"); add_child(tabs); Ref empty; empty.instance(); tabs->add_style_override("panel", empty); auto_switch_remote_scene_tree = EDITOR_DEF("debugger/auto_switch_to_remote_scene_tree", false); _add_debugger(); // Remote scene tree remote_scene_tree = memnew(EditorDebuggerTree); remote_scene_tree->connect_compat("object_selected", this, "_remote_object_requested"); remote_scene_tree->connect_compat("save_node", this, "_save_node_requested"); EditorNode::get_singleton()->get_scene_tree_dock()->add_remote_tree_editor(remote_scene_tree); EditorNode::get_singleton()->get_scene_tree_dock()->connect_compat("remote_tree_selected", this, "request_remote_tree"); remote_scene_tree_timeout = EDITOR_DEF("debugger/remote_scene_tree_refresh_interval", 1.0); inspect_edited_object_timeout = EDITOR_DEF("debugger/remote_inspect_refresh_interval", 0.2); EditorNode *editor = EditorNode::get_singleton(); editor->get_undo_redo()->set_method_notify_callback(_method_changeds, this); editor->get_undo_redo()->set_property_notify_callback(_property_changeds, this); editor->get_pause_button()->connect_compat("pressed", this, "_paused"); } ScriptEditorDebugger *EditorDebuggerNode::_add_debugger() { ScriptEditorDebugger *node = memnew(ScriptEditorDebugger(EditorNode::get_singleton())); int id = tabs->get_tab_count(); node->connect_compat("stop_requested", this, "_debugger_wants_stop", varray(id)); node->connect_compat("stopped", this, "_debugger_stopped", varray(id)); node->connect_compat("stack_frame_selected", this, "_stack_frame_selected", varray(id)); node->connect_compat("error_selected", this, "_error_selected", varray(id)); node->connect_compat("clear_execution", this, "_clear_execution"); node->connect_compat("breaked", this, "_breaked", varray(id)); node->connect_compat("remote_tree_updated", this, "_remote_tree_updated", varray(id)); node->connect_compat("remote_object_updated", this, "_remote_object_updated", varray(id)); node->connect_compat("remote_object_property_updated", this, "_remote_object_property_updated", varray(id)); node->connect_compat("remote_object_requested", this, "_remote_object_requested", varray(id)); if (tabs->get_tab_count() > 0) { get_debugger(0)->clear_style(); } tabs->add_child(node); node->set_name("Session " + itos(tabs->get_tab_count())); if (tabs->get_tab_count() > 1) { node->clear_style(); tabs->set_tabs_visible(true); tabs->add_style_override("panel", EditorNode::get_singleton()->get_gui_base()->get_stylebox("DebuggerPanel", "EditorStyles")); } return node; } void EditorDebuggerNode::_stack_frame_selected(int p_debugger) { const ScriptEditorDebugger *dbg = get_debugger(p_debugger); ERR_FAIL_COND(!dbg); if (dbg != get_current_debugger()) return; _text_editor_stack_goto(dbg); } void EditorDebuggerNode::_error_selected(const String &p_file, int p_line, int p_debugger) { Ref