diff options
Diffstat (limited to 'editor/debugger')
25 files changed, 380 insertions, 145 deletions
diff --git a/editor/debugger/debug_adapter/debug_adapter_parser.cpp b/editor/debugger/debug_adapter/debug_adapter_parser.cpp index 485d58f4a3..ff4051fc67 100644 --- a/editor/debugger/debug_adapter/debug_adapter_parser.cpp +++ b/editor/debugger/debug_adapter/debug_adapter_parser.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 */ @@ -109,7 +109,7 @@ Dictionary DebugAdapterParser::prepare_error_response(const Dictionary &p_params case DAP::ErrorType::UNKNOWN: default: error = "unknown"; - error_desc = "An unknown error has ocurred when processing the request."; + error_desc = "An unknown error has occurred when processing the request."; break; } @@ -412,7 +412,7 @@ Dictionary DebugAdapterParser::req_scopes(const Dictionary &p_params) const { } Dictionary DebugAdapterParser::req_variables(const Dictionary &p_params) const { - // If _remaining_vars > 0, the debugee is still sending a stack dump to the editor. + // If _remaining_vars > 0, the debuggee is still sending a stack dump to the editor. if (DebugAdapterProtocol::get_singleton()->_remaining_vars > 0) { return Dictionary(); } diff --git a/editor/debugger/debug_adapter/debug_adapter_parser.h b/editor/debugger/debug_adapter/debug_adapter_parser.h index 4c93464e39..f458151e17 100644 --- a/editor/debugger/debug_adapter/debug_adapter_parser.h +++ b/editor/debugger/debug_adapter/debug_adapter_parser.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 */ diff --git a/editor/debugger/debug_adapter/debug_adapter_protocol.cpp b/editor/debugger/debug_adapter/debug_adapter_protocol.cpp index 2e0e6cb7c8..babe8af8bc 100644 --- a/editor/debugger/debug_adapter/debug_adapter_protocol.cpp +++ b/editor/debugger/debug_adapter/debug_adapter_protocol.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 */ @@ -192,10 +192,12 @@ int DebugAdapterProtocol::parse_variant(const Variant &p_var) { case Variant::VECTOR2I: { int id = variable_id++; Vector2 vec = p_var; + const String type_scalar = Variant::get_type_name(p_var.get_type() == Variant::VECTOR2 ? Variant::FLOAT : Variant::INT); DAP::Variable x, y; x.name = "x"; y.name = "y"; - x.type = y.type = Variant::get_type_name(p_var.get_type() == Variant::VECTOR2 ? Variant::FLOAT : Variant::INT); + x.type = type_scalar; + y.type = type_scalar; x.value = rtos(vec.x); y.value = rtos(vec.y); @@ -209,12 +211,16 @@ int DebugAdapterProtocol::parse_variant(const Variant &p_var) { case Variant::RECT2I: { int id = variable_id++; Rect2 rect = p_var; + const String type_scalar = Variant::get_type_name(p_var.get_type() == Variant::RECT2 ? Variant::FLOAT : Variant::INT); DAP::Variable x, y, w, h; x.name = "x"; y.name = "y"; w.name = "w"; h.name = "h"; - x.type = y.type = w.type = h.type = Variant::get_type_name(p_var.get_type() == Variant::RECT2 ? Variant::FLOAT : Variant::INT); + x.type = type_scalar; + y.type = type_scalar; + w.type = type_scalar; + h.type = type_scalar; x.value = rtos(rect.position.x); y.value = rtos(rect.position.y); w.value = rtos(rect.size.x); @@ -232,11 +238,14 @@ int DebugAdapterProtocol::parse_variant(const Variant &p_var) { case Variant::VECTOR3I: { int id = variable_id++; Vector3 vec = p_var; + const String type_scalar = Variant::get_type_name(p_var.get_type() == Variant::VECTOR3 ? Variant::FLOAT : Variant::INT); DAP::Variable x, y, z; x.name = "x"; y.name = "y"; z.name = "z"; - x.type = y.type = z.type = Variant::get_type_name(p_var.get_type() == Variant::VECTOR3 ? Variant::FLOAT : Variant::INT); + x.type = type_scalar; + y.type = type_scalar; + z.type = type_scalar; x.value = rtos(vec.x); y.value = rtos(vec.y); z.value = rtos(vec.z); @@ -251,11 +260,14 @@ int DebugAdapterProtocol::parse_variant(const Variant &p_var) { case Variant::TRANSFORM2D: { int id = variable_id++; Transform2D transform = p_var; + const String type_vec2 = Variant::get_type_name(Variant::VECTOR2); DAP::Variable x, y, origin; x.name = "x"; y.name = "y"; origin.name = "origin"; - x.type = y.type = origin.type = Variant::get_type_name(Variant::VECTOR2); + x.type = type_vec2; + y.type = type_vec2; + origin.type = type_vec2; x.value = transform.elements[0]; y.value = transform.elements[1]; origin.value = transform.elements[2]; @@ -291,12 +303,16 @@ int DebugAdapterProtocol::parse_variant(const Variant &p_var) { case Variant::QUATERNION: { int id = variable_id++; Quaternion quat = p_var; + const String type_float = Variant::get_type_name(Variant::FLOAT); DAP::Variable x, y, z, w; x.name = "x"; y.name = "y"; z.name = "z"; w.name = "w"; - x.type = y.type = z.type = w.type = Variant::get_type_name(Variant::FLOAT); + x.type = type_float; + y.type = type_float; + z.type = type_float; + w.type = type_float; x.value = rtos(quat.x); y.value = rtos(quat.y); z.value = rtos(quat.z); @@ -313,10 +329,12 @@ int DebugAdapterProtocol::parse_variant(const Variant &p_var) { case Variant::AABB: { int id = variable_id++; AABB aabb = p_var; + const String type_vec3 = Variant::get_type_name(Variant::VECTOR3); DAP::Variable position, size; position.name = "position"; size.name = "size"; - position.type = size.type = Variant::get_type_name(Variant::VECTOR3); + position.type = type_vec3; + size.type = type_vec3; position.value = aabb.position; size.value = aabb.size; position.variablesReference = parse_variant(aabb.position); @@ -331,11 +349,14 @@ int DebugAdapterProtocol::parse_variant(const Variant &p_var) { case Variant::BASIS: { int id = variable_id++; Basis basis = p_var; + const String type_vec2 = Variant::get_type_name(Variant::VECTOR2); DAP::Variable x, y, z; x.name = "x"; y.name = "y"; z.name = "z"; - x.type = y.type = z.type = Variant::get_type_name(Variant::VECTOR2); + x.type = type_vec2; + y.type = type_vec2; + z.type = type_vec2; x.value = basis.elements[0]; y.value = basis.elements[1]; z.value = basis.elements[2]; @@ -372,12 +393,16 @@ int DebugAdapterProtocol::parse_variant(const Variant &p_var) { case Variant::COLOR: { int id = variable_id++; Color color = p_var; + const String type_float = Variant::get_type_name(Variant::FLOAT); DAP::Variable r, g, b, a; r.name = "r"; g.name = "g"; b.name = "b"; a.name = "a"; - r.type = g.type = b.type = a.type = Variant::get_type_name(Variant::FLOAT); + r.type = type_float; + g.type = type_float; + b.type = type_float; + a.type = type_float; r.value = rtos(color.r); g.value = rtos(color.g); b.value = rtos(color.b); diff --git a/editor/debugger/debug_adapter/debug_adapter_protocol.h b/editor/debugger/debug_adapter/debug_adapter_protocol.h index d4291992bf..b54a5f1f3f 100644 --- a/editor/debugger/debug_adapter/debug_adapter_protocol.h +++ b/editor/debugger/debug_adapter/debug_adapter_protocol.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 */ diff --git a/editor/debugger/debug_adapter/debug_adapter_server.cpp b/editor/debugger/debug_adapter/debug_adapter_server.cpp index 4775e2c8b0..ffbbf66015 100644 --- a/editor/debugger/debug_adapter/debug_adapter_server.cpp +++ b/editor/debugger/debug_adapter/debug_adapter_server.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 */ diff --git a/editor/debugger/debug_adapter/debug_adapter_server.h b/editor/debugger/debug_adapter/debug_adapter_server.h index c449403cc2..a2b01f92c6 100644 --- a/editor/debugger/debug_adapter/debug_adapter_server.h +++ b/editor/debugger/debug_adapter/debug_adapter_server.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 */ diff --git a/editor/debugger/debug_adapter/debug_adapter_types.h b/editor/debugger/debug_adapter/debug_adapter_types.h index 5156c91d14..77b70909b3 100644 --- a/editor/debugger/debug_adapter/debug_adapter_types.h +++ b/editor/debugger/debug_adapter/debug_adapter_types.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 */ diff --git a/editor/debugger/editor_debugger_inspector.cpp b/editor/debugger/editor_debugger_inspector.cpp index e53f66e72e..38bdbe2870 100644 --- a/editor/debugger/editor_debugger_inspector.cpp +++ b/editor/debugger/editor_debugger_inspector.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 */ @@ -55,9 +55,14 @@ bool EditorDebuggerRemoteObject::_get(const StringName &p_name, Variant &r_ret) } void EditorDebuggerRemoteObject::_get_property_list(List<PropertyInfo> *p_list) const { - p_list->clear(); //sorry, no want category - for (const PropertyInfo &E : prop_list) { - p_list->push_back(E); + p_list->clear(); // Sorry, no want category. + for (const PropertyInfo &prop : prop_list) { + if (prop.name == "script") { + // Skip the script property, it's always added by the non-virtual method. + continue; + } + + p_list->push_back(prop); } } @@ -257,13 +262,26 @@ void EditorDebuggerInspector::add_stack_variable(const Array &p_array) { variables->prop_values[type + n] = v; variables->update(); edit(variables); + + // To prevent constantly resizing when using filtering. + int size_x = get_size().x; + if (size_x > get_custom_minimum_size().x) { + set_custom_minimum_size(Size2(size_x, 0)); + } } void EditorDebuggerInspector::clear_stack_variables() { variables->clear(); variables->update(); + set_custom_minimum_size(Size2(0, 0)); } String EditorDebuggerInspector::get_stack_variable(const String &p_var) { - return variables->get_variant(p_var); + for (Map<StringName, Variant>::Element *E = variables->prop_values.front(); E; E = E->next()) { + String v = E->key().operator String(); + if (v.get_slice("/", 1) == p_var) { + return variables->get_variant(v); + } + } + return String(); } diff --git a/editor/debugger/editor_debugger_inspector.h b/editor/debugger/editor_debugger_inspector.h index 6648c99c03..5cdc4417d0 100644 --- a/editor/debugger/editor_debugger_inspector.h +++ b/editor/debugger/editor_debugger_inspector.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 */ diff --git a/editor/debugger/editor_debugger_node.cpp b/editor/debugger/editor_debugger_node.cpp index 188f5708aa..79853b6809 100644 --- a/editor/debugger/editor_debugger_node.cpp +++ b/editor/debugger/editor_debugger_node.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 */ @@ -59,7 +59,7 @@ EditorDebuggerNode::EditorDebuggerNode() { add_theme_constant_override("margin_right", -EditorNode::get_singleton()->get_gui_base()->get_theme_stylebox(SNAME("BottomPanelDebuggerOverride"), SNAME("EditorStyles"))->get_margin(SIDE_RIGHT)); tabs = memnew(TabContainer); - tabs->set_tab_align(TabContainer::ALIGN_LEFT); + tabs->set_tab_alignment(TabContainer::ALIGNMENT_LEFT); tabs->set_tabs_visible(false); tabs->connect("tab_changed", callable_mp(this, &EditorDebuggerNode::_debugger_changed)); add_child(tabs); @@ -75,8 +75,8 @@ EditorDebuggerNode::EditorDebuggerNode() { remote_scene_tree = memnew(EditorDebuggerTree); remote_scene_tree->connect("object_selected", callable_mp(this, &EditorDebuggerNode::_remote_object_requested)); remote_scene_tree->connect("save_node", callable_mp(this, &EditorDebuggerNode::_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("remote_tree_selected", callable_mp(this, &EditorDebuggerNode::request_remote_tree)); + SceneTreeDock::get_singleton()->add_remote_tree_editor(remote_scene_tree); + SceneTreeDock::get_singleton()->connect("remote_tree_selected", callable_mp(this, &EditorDebuggerNode::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); @@ -95,6 +95,7 @@ ScriptEditorDebugger *EditorDebuggerNode::_add_debugger() { node->connect("stopped", callable_mp(this, &EditorDebuggerNode::_debugger_stopped), varray(id)); node->connect("stack_frame_selected", callable_mp(this, &EditorDebuggerNode::_stack_frame_selected), varray(id)); node->connect("error_selected", callable_mp(this, &EditorDebuggerNode::_error_selected), varray(id)); + node->connect("breakpoint_selected", callable_mp(this, &EditorDebuggerNode::_error_selected), varray(id)); node->connect("clear_execution", callable_mp(this, &EditorDebuggerNode::_clear_execution)); node->connect("breaked", callable_mp(this, &EditorDebuggerNode::_breaked), varray(id)); node->connect("remote_tree_updated", callable_mp(this, &EditorDebuggerNode::_remote_tree_updated), varray(id)); @@ -183,6 +184,11 @@ ScriptEditorDebugger *EditorDebuggerNode::get_default_debugger() const { return Object::cast_to<ScriptEditorDebugger>(tabs->get_tab_control(0)); } +String EditorDebuggerNode::get_server_uri() const { + ERR_FAIL_COND_V(server.is_null(), ""); + return server->get_uri(); +} + Error EditorDebuggerNode::start(const String &p_uri) { stop(); ERR_FAIL_COND_V(p_uri.find("://") < 0, ERR_INVALID_PARAMETER); @@ -265,15 +271,20 @@ void EditorDebuggerNode::_notification(int p_what) { if (error_count == 0 && warning_count == 0) { debugger_button->set_text(TTR("Debugger")); + debugger_button->remove_theme_color_override("font_color"); debugger_button->set_icon(Ref<Texture2D>()); } else { debugger_button->set_text(TTR("Debugger") + " (" + itos(error_count + warning_count) + ")"); if (error_count >= 1 && warning_count >= 1) { debugger_button->set_icon(get_theme_icon(SNAME("ErrorWarning"), SNAME("EditorIcons"))); + // Use error color to represent the highest level of severity reported. + debugger_button->add_theme_color_override("font_color", get_theme_color(SNAME("error_color"), SNAME("Editor"))); } else if (error_count >= 1) { debugger_button->set_icon(get_theme_icon(SNAME("Error"), SNAME("EditorIcons"))); + debugger_button->add_theme_color_override("font_color", get_theme_color(SNAME("error_color"), SNAME("Editor"))); } else { debugger_button->set_icon(get_theme_icon(SNAME("Warning"), SNAME("EditorIcons"))); + debugger_button->add_theme_color_override("font_color", get_theme_color(SNAME("warning_color"), SNAME("Editor"))); } } last_error_count = error_count; @@ -321,10 +332,10 @@ void EditorDebuggerNode::_notification(int p_what) { // Switch to remote tree view if so desired. auto_switch_remote_scene_tree = (bool)EditorSettings::get_singleton()->get("debugger/auto_switch_to_remote_scene_tree"); if (auto_switch_remote_scene_tree) { - EditorNode::get_singleton()->get_scene_tree_dock()->show_remote_tree(); + SceneTreeDock::get_singleton()->show_remote_tree(); } // Good to go. - EditorNode::get_singleton()->get_scene_tree_dock()->show_tab_buttons(); + SceneTreeDock::get_singleton()->show_tab_buttons(); debugger->set_editor_remote_tree(remote_scene_tree); debugger->start(server->take_connection()); // Send breakpoints. @@ -350,8 +361,8 @@ void EditorDebuggerNode::_debugger_stopped(int p_id) { if (!found) { EditorNode::get_singleton()->get_pause_button()->set_pressed(false); EditorNode::get_singleton()->get_pause_button()->set_disabled(true); - EditorNode::get_singleton()->get_scene_tree_dock()->hide_remote_tree(); - EditorNode::get_singleton()->get_scene_tree_dock()->hide_tab_buttons(); + SceneTreeDock::get_singleton()->hide_remote_tree(); + SceneTreeDock::get_singleton()->hide_tab_buttons(); EditorNode::get_singleton()->notify_all_debug_sessions_exited(); } } @@ -565,7 +576,7 @@ void EditorDebuggerNode::_remote_object_property_updated(ObjectID p_id, const St if (obj->remote_object_id != p_id) { return; } - EditorNode::get_singleton()->get_inspector()->update_property(p_property); + InspectorDock::get_inspector_singleton()->update_property(p_property); } } diff --git a/editor/debugger/editor_debugger_node.h b/editor/debugger/editor_debugger_node.h index 4d9e846834..6fcdbf5f73 100644 --- a/editor/debugger/editor_debugger_node.h +++ b/editor/debugger/editor_debugger_node.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 */ @@ -188,8 +188,9 @@ public: void set_camera_override(CameraOverride p_override); CameraOverride get_camera_override(); - Error start(const String &p_uri = "tcp://"); + String get_server_uri() const; + Error start(const String &p_uri = "tcp://"); void stop(); void add_debugger_plugin(const Ref<Script> &p_script); diff --git a/editor/debugger/editor_debugger_server.cpp b/editor/debugger/editor_debugger_server.cpp index 8c3833af50..bce131a5fe 100644 --- a/editor/debugger/editor_debugger_server.cpp +++ b/editor/debugger/editor_debugger_server.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 */ @@ -41,15 +41,18 @@ class EditorDebuggerServerTCP : public EditorDebuggerServer { private: Ref<TCPServer> server; + String endpoint; public: static EditorDebuggerServer *create(const String &p_protocol); - virtual void poll() {} - virtual Error start(const String &p_uri); - virtual void stop(); - virtual bool is_active() const; - virtual bool is_connection_available() const; - virtual Ref<RemoteDebuggerPeer> take_connection(); + + virtual void poll() override {} + virtual String get_uri() const override; + virtual Error start(const String &p_uri) override; + virtual void stop() override; + virtual bool is_active() const override; + virtual bool is_connection_available() const override; + virtual Ref<RemoteDebuggerPeer> take_connection() override; EditorDebuggerServerTCP(); }; @@ -63,21 +66,42 @@ EditorDebuggerServerTCP::EditorDebuggerServerTCP() { server.instantiate(); } +String EditorDebuggerServerTCP::get_uri() const { + return endpoint; +} + Error EditorDebuggerServerTCP::start(const String &p_uri) { - int bind_port = (int)EditorSettings::get_singleton()->get("network/debug/remote_port"); + // Default host and port String bind_host = (String)EditorSettings::get_singleton()->get("network/debug/remote_host"); + int bind_port = (int)EditorSettings::get_singleton()->get("network/debug/remote_port"); + + // Optionally override if (!p_uri.is_empty() && p_uri != "tcp://") { String scheme, path; Error err = p_uri.parse_url(scheme, bind_host, bind_port, path); ERR_FAIL_COND_V(err != OK, ERR_INVALID_PARAMETER); ERR_FAIL_COND_V(!bind_host.is_valid_ip_address() && bind_host != "*", ERR_INVALID_PARAMETER); } - const Error err = server->listen(bind_port, bind_host); - if (err != OK) { - EditorNode::get_log()->add_message(String("Error listening on port ") + itos(bind_port), EditorLog::MSG_TYPE_ERROR); - return err; + + // Try listening on ports + const int max_attempts = 5; + for (int attempt = 1;; ++attempt) { + const Error err = server->listen(bind_port, bind_host); + if (err == OK) { + break; + } + if (attempt >= max_attempts) { + EditorNode::get_log()->add_message(vformat("Cannot listen on port %d, remote debugging unavailable.", bind_port), EditorLog::MSG_TYPE_ERROR); + return err; + } + int last_port = bind_port++; + EditorNode::get_log()->add_message(vformat("Cannot listen on port %d, trying %d instead.", last_port, bind_port), EditorLog::MSG_TYPE_WARNING); } - return err; + + // Endpoint that the client should connect to + endpoint = vformat("tcp://%s:%d", bind_host, bind_port); + + return OK; } void EditorDebuggerServerTCP::stop() { diff --git a/editor/debugger/editor_debugger_server.h b/editor/debugger/editor_debugger_server.h index 844d1a9e5a..bda4a1ce7d 100644 --- a/editor/debugger/editor_debugger_server.h +++ b/editor/debugger/editor_debugger_server.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 */ @@ -47,8 +47,10 @@ public: static void register_protocol_handler(const String &p_protocol, CreateServerFunc p_func); static EditorDebuggerServer *create(const String &p_protocol); + + virtual String get_uri() const = 0; virtual void poll() = 0; - virtual Error start(const String &p_uri = "") = 0; + virtual Error start(const String &p_uri) = 0; virtual void stop() = 0; virtual bool is_active() const = 0; virtual bool is_connection_available() const = 0; diff --git a/editor/debugger/editor_debugger_tree.cpp b/editor/debugger/editor_debugger_tree.cpp index 1feab98948..29d0014b8a 100644 --- a/editor/debugger/editor_debugger_tree.cpp +++ b/editor/debugger/editor_debugger_tree.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 */ @@ -107,7 +107,7 @@ void EditorDebuggerTree::_scene_tree_rmb_selected(const Vector2 &p_position) { item_menu->clear(); item_menu->add_icon_item(get_theme_icon(SNAME("CreateNewSceneFrom"), SNAME("EditorIcons")), TTR("Save Branch as Scene"), ITEM_MENU_SAVE_REMOTE_NODE); item_menu->add_icon_item(get_theme_icon(SNAME("CopyNodePath"), SNAME("EditorIcons")), TTR("Copy Node Path"), ITEM_MENU_COPY_NODE_PATH); - item_menu->set_position(get_screen_transform().xform(get_local_mouse_position())); + item_menu->set_position(get_screen_position() + get_local_mouse_position()); item_menu->popup(); } @@ -128,7 +128,7 @@ void EditorDebuggerTree::_scene_tree_rmb_selected(const Vector2 &p_position) { void EditorDebuggerTree::update_scene_tree(const SceneDebuggerTree *p_tree, int p_debugger) { updating_scene_tree = true; const String last_path = get_selected_path(); - const String filter = EditorNode::get_singleton()->get_scene_tree_dock()->get_filter(); + const String filter = SceneTreeDock::get_singleton()->get_filter(); bool filter_changed = filter != last_filter; TreeItem *scroll_item = nullptr; diff --git a/editor/debugger/editor_debugger_tree.h b/editor/debugger/editor_debugger_tree.h index 13193344f1..58af52b01f 100644 --- a/editor/debugger/editor_debugger_tree.h +++ b/editor/debugger/editor_debugger_tree.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 */ diff --git a/editor/debugger/editor_network_profiler.cpp b/editor/debugger/editor_network_profiler.cpp index d4385630be..698e950f57 100644 --- a/editor/debugger/editor_network_profiler.cpp +++ b/editor/debugger/editor_network_profiler.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 */ @@ -60,7 +60,7 @@ void EditorNetworkProfiler::_update_frame() { TreeItem *node = counters_display->create_item(root); for (int j = 0; j < counters_display->get_columns(); ++j) { - node->set_text_align(j, j > 0 ? TreeItem::ALIGN_RIGHT : TreeItem::ALIGN_LEFT); + node->set_text_alignment(j, j > 0 ? HORIZONTAL_ALIGNMENT_RIGHT : HORIZONTAL_ALIGNMENT_LEFT); } node->set_text(0, E.value.node_path); @@ -149,7 +149,7 @@ EditorNetworkProfiler::EditorNetworkProfiler() { incoming_bandwidth_text = memnew(LineEdit); incoming_bandwidth_text->set_editable(false); incoming_bandwidth_text->set_custom_minimum_size(Size2(120, 0) * EDSCALE); - incoming_bandwidth_text->set_align(LineEdit::Align::ALIGN_RIGHT); + incoming_bandwidth_text->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_RIGHT); hb->add_child(incoming_bandwidth_text); Control *down_up_spacer = memnew(Control); @@ -163,7 +163,7 @@ EditorNetworkProfiler::EditorNetworkProfiler() { outgoing_bandwidth_text = memnew(LineEdit); outgoing_bandwidth_text->set_editable(false); outgoing_bandwidth_text->set_custom_minimum_size(Size2(120, 0) * EDSCALE); - outgoing_bandwidth_text->set_align(LineEdit::Align::ALIGN_RIGHT); + outgoing_bandwidth_text->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_RIGHT); hb->add_child(outgoing_bandwidth_text); // Set initial texts in the incoming/outgoing bandwidth labels diff --git a/editor/debugger/editor_network_profiler.h b/editor/debugger/editor_network_profiler.h index 8c1da1cb2d..320dd2a826 100644 --- a/editor/debugger/editor_network_profiler.h +++ b/editor/debugger/editor_network_profiler.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 */ diff --git a/editor/debugger/editor_performance_profiler.cpp b/editor/debugger/editor_performance_profiler.cpp index 08ed675d16..56d1e7cee9 100644 --- a/editor/debugger/editor_performance_profiler.cpp +++ b/editor/debugger/editor_performance_profiler.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 */ @@ -132,14 +132,14 @@ void EditorPerformanceProfiler::_monitor_draw() { rect.size -= graph_style_box->get_minimum_size(); Color draw_color = get_theme_color(SNAME("accent_color"), SNAME("Editor")); draw_color.set_hsv(Math::fmod(hue_shift * float(current.frame_index), 0.9f), draw_color.get_s() * 0.9f, draw_color.get_v() * value_multiplier, 0.6f); - monitor_draw->draw_string(graph_font, rect.position + Point2(0, graph_font->get_ascent(font_size)), current.item->get_text(0), HALIGN_LEFT, rect.size.x, font_size, draw_color); + monitor_draw->draw_string(graph_font, rect.position + Point2(0, graph_font->get_ascent(font_size)), current.item->get_text(0), HORIZONTAL_ALIGNMENT_LEFT, rect.size.x, font_size, draw_color); draw_color.a = 0.9f; float value_position = rect.size.width - graph_font->get_string_size(current.item->get_text(1), font_size).width; if (value_position < 0) { value_position = 0; } - monitor_draw->draw_string(graph_font, rect.position + Point2(value_position, graph_font->get_ascent(font_size)), current.item->get_text(1), HALIGN_LEFT, rect.size.x, font_size, draw_color); + monitor_draw->draw_string(graph_font, rect.position + Point2(value_position, graph_font->get_ascent(font_size)), current.item->get_text(1), HORIZONTAL_ALIGNMENT_LEFT, rect.size.x, font_size, draw_color); rect.position.y += graph_font->get_height(font_size); rect.size.height -= graph_font->get_height(font_size); @@ -152,12 +152,12 @@ void EditorPerformanceProfiler::_monitor_draw() { Color horizontal_line_color; horizontal_line_color.set_hsv(draw_color.get_h(), draw_color.get_s() * 0.5f, draw_color.get_v() * 0.5f, 0.3f); monitor_draw->draw_line(rect.position, rect.position + Vector2(rect.size.width, 0), horizontal_line_color, Math::round(EDSCALE)); - monitor_draw->draw_string(graph_font, rect.position + Vector2(0, graph_font->get_ascent(font_size)), _create_label(current.max, current.type), HALIGN_LEFT, rect.size.width, font_size, horizontal_line_color); + monitor_draw->draw_string(graph_font, rect.position + Vector2(0, graph_font->get_ascent(font_size)), _create_label(current.max, current.type), HORIZONTAL_ALIGNMENT_LEFT, rect.size.width, font_size, horizontal_line_color); for (int j = 0; j < line_count; j++) { Vector2 y_offset = Vector2(0, rect.size.height * (1.0f - float(j) / float(line_count))); monitor_draw->draw_line(rect.position + y_offset, rect.position + Vector2(rect.size.width, 0) + y_offset, horizontal_line_color, Math::round(EDSCALE)); - monitor_draw->draw_string(graph_font, rect.position - Vector2(0, graph_font->get_descent(font_size)) + y_offset, _create_label(current.max * float(j) / float(line_count), current.type), HALIGN_LEFT, rect.size.width, font_size, horizontal_line_color); + monitor_draw->draw_string(graph_font, rect.position - Vector2(0, graph_font->get_descent(font_size)) + y_offset, _create_label(current.max * float(j) / float(line_count), current.type), HORIZONTAL_ALIGNMENT_LEFT, rect.size.width, font_size, horizontal_line_color); } } @@ -191,7 +191,7 @@ void EditorPerformanceProfiler::_monitor_draw() { if (text_top_left_position.y < 0) { text_top_left_position.y = h2 + MARKER_MARGIN; } - monitor_draw->draw_string(graph_font, rect.position + text_top_left_position + Point2(0, graph_font->get_ascent(font_size)), label, HALIGN_LEFT, rect.size.x, font_size, line_color); + monitor_draw->draw_string(graph_font, rect.position + text_top_left_position + Point2(0, graph_font->get_ascent(font_size)), label, HORIZONTAL_ALIGNMENT_LEFT, rect.size.x, font_size, line_color); } prev = h2; e = e->next(); @@ -249,7 +249,7 @@ TreeItem *EditorPerformanceProfiler::_create_monitor_item(const StringName &p_mo void EditorPerformanceProfiler::_marker_input(const Ref<InputEvent> &p_event) { Ref<InputEventMouseButton> mb = p_event; - if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_LEFT) { + if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == MouseButton::LEFT) { Vector<StringName> active; for (OrderedHashMap<StringName, Monitor>::Element i = monitors.front(); i; i = i.next()) { if (i.value().item->is_checked(0)) { @@ -378,8 +378,8 @@ EditorPerformanceProfiler::EditorPerformanceProfiler() { info_message = memnew(Label); info_message->set_text(TTR("Pick one or more items from the list to display the graph.")); - info_message->set_valign(Label::VALIGN_CENTER); - info_message->set_align(Label::ALIGN_CENTER); + info_message->set_vertical_alignment(VERTICAL_ALIGNMENT_CENTER); + info_message->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER); info_message->set_autowrap_mode(Label::AUTOWRAP_WORD_SMART); info_message->set_custom_minimum_size(Size2(100 * EDSCALE, 0)); info_message->set_anchors_and_offsets_preset(PRESET_WIDE, PRESET_MODE_KEEP_SIZE, 8 * EDSCALE); diff --git a/editor/debugger/editor_performance_profiler.h b/editor/debugger/editor_performance_profiler.h index ea3404b208..998ecc5bb6 100644 --- a/editor/debugger/editor_performance_profiler.h +++ b/editor/debugger/editor_performance_profiler.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 */ diff --git a/editor/debugger/editor_profiler.cpp b/editor/debugger/editor_profiler.cpp index 2fe7cd7886..d5e825a26c 100644 --- a/editor/debugger/editor_profiler.cpp +++ b/editor/debugger/editor_profiler.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 */ @@ -355,7 +355,7 @@ void EditorProfiler::_update_frame() { item->set_metadata(0, it.signature); item->set_metadata(1, it.script); item->set_metadata(2, it.line); - item->set_text_align(2, TreeItem::ALIGN_RIGHT); + item->set_text_alignment(2, HORIZONTAL_ALIGNMENT_RIGHT); item->set_tooltip(0, it.name + "\n" + it.script + ":" + itos(it.line)); float time = dtime == DISPLAY_SELF_TIME ? it.self : it.total; @@ -438,7 +438,7 @@ void EditorProfiler::_graph_tex_input(const Ref<InputEvent> &p_ev) { Ref<InputEventMouseMotion> mm = p_ev; if ( - (mb.is_valid() && mb->get_button_index() == MOUSE_BUTTON_LEFT && mb->is_pressed()) || + (mb.is_valid() && mb->get_button_index() == MouseButton::LEFT && mb->is_pressed()) || (mm.is_valid())) { int x = me->get_position().x - 1; x = x * frame_metrics.size() / graph->get_size().width; @@ -453,7 +453,7 @@ void EditorProfiler::_graph_tex_input(const Ref<InputEvent> &p_ev) { x = frame_metrics.size() - 1; } - if (mb.is_valid() || mm->get_button_mask() & MOUSE_BUTTON_MASK_LEFT) { + if (mb.is_valid() || (mm->get_button_mask() & MouseButton::MASK_LEFT) != MouseButton::NONE) { updating_frame = true; if (x < total_metrics) @@ -645,7 +645,7 @@ EditorProfiler::EditorProfiler() { variables->connect("item_edited", callable_mp(this, &EditorProfiler::_item_edited)); graph = memnew(TextureRect); - graph->set_expand(true); + graph->set_ignore_texture_size(true); graph->set_mouse_filter(MOUSE_FILTER_STOP); graph->connect("draw", callable_mp(this, &EditorProfiler::_graph_tex_draw)); graph->connect("gui_input", callable_mp(this, &EditorProfiler::_graph_tex_input)); diff --git a/editor/debugger/editor_profiler.h b/editor/debugger/editor_profiler.h index 8880824b87..45f7ac39c1 100644 --- a/editor/debugger/editor_profiler.h +++ b/editor/debugger/editor_profiler.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 */ diff --git a/editor/debugger/editor_visual_profiler.cpp b/editor/debugger/editor_visual_profiler.cpp index f25f18b7e4..3cb5d3513d 100644 --- a/editor/debugger/editor_visual_profiler.cpp +++ b/editor/debugger/editor_visual_profiler.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 */ @@ -462,7 +462,7 @@ void EditorVisualProfiler::_graph_tex_draw() { graph->draw_line(Vector2(0, frame_y), Vector2(half_width, frame_y), Color(1, 1, 1, 0.3)); String limit_str = String::num(graph_limit, 2); - graph->draw_string(font, Vector2(half_width - font->get_string_size(limit_str, font_size).x - 2, frame_y - 2), limit_str, HALIGN_LEFT, -1, font_size, Color(1, 1, 1, 0.6)); + graph->draw_string(font, Vector2(half_width - font->get_string_size(limit_str, font_size).x - 2, frame_y - 2), limit_str, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, Color(1, 1, 1, 0.6)); } if (graph_height_gpu > 0) { @@ -473,11 +473,11 @@ void EditorVisualProfiler::_graph_tex_draw() { graph->draw_line(Vector2(half_width, frame_y), Vector2(graph->get_size().x, frame_y), Color(1, 1, 1, 0.3)); String limit_str = String::num(graph_limit, 2); - graph->draw_string(font, Vector2(half_width * 2 - font->get_string_size(limit_str, font_size).x - 2, frame_y - 2), limit_str, HALIGN_LEFT, -1, font_size, Color(1, 1, 1, 0.6)); + graph->draw_string(font, Vector2(half_width * 2 - font->get_string_size(limit_str, font_size).x - 2, frame_y - 2), limit_str, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, Color(1, 1, 1, 0.6)); } - graph->draw_string(font, Vector2(font->get_string_size("X", font_size).x, font->get_ascent(font_size) + 2), "CPU:", HALIGN_LEFT, -1, font_size, Color(1, 1, 1, 0.8)); - graph->draw_string(font, Vector2(font->get_string_size("X", font_size).x + graph->get_size().width / 2, font->get_ascent(font_size) + 2), "GPU:", HALIGN_LEFT, -1, font_size, Color(1, 1, 1, 0.8)); + graph->draw_string(font, Vector2(font->get_string_size("X", font_size).x, font->get_ascent(font_size) + 2), "CPU:", HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, Color(1, 1, 1, 0.8)); + graph->draw_string(font, Vector2(font->get_string_size("X", font_size).x + graph->get_size().width / 2, font->get_ascent(font_size) + 2), "GPU:", HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, Color(1, 1, 1, 0.8)); /* if (hover_metric != -1 && frame_metrics[hover_metric].valid) { @@ -517,7 +517,7 @@ void EditorVisualProfiler::_graph_tex_input(const Ref<InputEvent> &p_ev) { Ref<InputEventMouseMotion> mm = p_ev; if ( - (mb.is_valid() && mb->get_button_index() == MOUSE_BUTTON_LEFT && mb->is_pressed()) || + (mb.is_valid() && mb->get_button_index() == MouseButton::LEFT && mb->is_pressed()) || (mm.is_valid())) { int half_w = graph->get_size().width / 2; int x = me->get_position().x; @@ -549,7 +549,7 @@ void EditorVisualProfiler::_graph_tex_input(const Ref<InputEvent> &p_ev) { hover_metric = -1; } - if (mb.is_valid() || mm->get_button_mask() & MOUSE_BUTTON_MASK_LEFT) { + if (mb.is_valid() || (mm->get_button_mask() & MouseButton::MASK_LEFT) != MouseButton::NONE) { //cursor_metric=x; updating_frame = true; @@ -786,7 +786,7 @@ EditorVisualProfiler::EditorVisualProfiler() { variables->connect("cell_selected", callable_mp(this, &EditorVisualProfiler::_item_selected)); graph = memnew(TextureRect); - graph->set_expand(true); + graph->set_ignore_texture_size(true); graph->set_mouse_filter(MOUSE_FILTER_STOP); //graph->set_ignore_mouse(false); graph->connect("draw", callable_mp(this, &EditorVisualProfiler::_graph_tex_draw)); diff --git a/editor/debugger/editor_visual_profiler.h b/editor/debugger/editor_visual_profiler.h index 6b04fdbafc..55ba725ae8 100644 --- a/editor/debugger/editor_visual_profiler.h +++ b/editor/debugger/editor_visual_profiler.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 */ diff --git a/editor/debugger/script_editor_debugger.cpp b/editor/debugger/script_editor_debugger.cpp index a312c161a8..ee844fff64 100644 --- a/editor/debugger/script_editor_debugger.cpp +++ b/editor/debugger/script_editor_debugger.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 */ @@ -79,7 +79,7 @@ void ScriptEditorDebugger::_put_msg(String p_message, Array p_data) { void ScriptEditorDebugger::debug_copy() { String msg = reason->get_text(); - if (msg == "") { + if (msg.is_empty()) { return; } DisplayServer::get_singleton()->clipboard_set(msg); @@ -312,7 +312,7 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da if (is_move_to_foreground()) { DisplayServer::get_singleton()->window_move_to_foreground(); } - if (error != "") { + if (!error.is_empty()) { tabs->set_current_tab(0); } profiler->set_enabled(false); @@ -499,7 +499,7 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da error->set_icon(0, get_theme_icon(oe.warning ? "Warning" : "Error", "EditorIcons")); error->set_text(0, time); - error->set_text_align(0, TreeItem::ALIGN_LEFT); + error->set_text_alignment(0, HORIZONTAL_ALIGNMENT_LEFT); const Color color = get_theme_color(oe.warning ? SNAME("warning_color") : SNAME("error_color"), SNAME("Editor")); error->set_custom_color(0, color); @@ -524,7 +524,7 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da TreeItem *cpp_cond = error_tree->create_item(error); cpp_cond->set_text(0, "<" + TTR("C++ Error") + ">"); cpp_cond->set_text(1, oe.error); - cpp_cond->set_text_align(0, TreeItem::ALIGN_LEFT); + cpp_cond->set_text_alignment(0, HORIZONTAL_ALIGNMENT_LEFT); tooltip += TTR("C++ Error:") + " " + oe.error + "\n"; if (source_is_project_file) { cpp_cond->set_metadata(0, source_meta); @@ -542,7 +542,7 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da TreeItem *cpp_source = error_tree->create_item(error); cpp_source->set_text(0, "<" + (source_is_project_file ? TTR("Source") : TTR("C++ Source")) + ">"); cpp_source->set_text(1, source_txt); - cpp_source->set_text_align(0, TreeItem::ALIGN_LEFT); + cpp_source->set_text_alignment(0, HORIZONTAL_ALIGNMENT_LEFT); tooltip += (source_is_project_file ? TTR("Source:") : TTR("C++ Source:")) + " " + source_txt + "\n"; // Set metadata to highlight error line in scripts. @@ -565,7 +565,7 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da if (i == 0) { stack_trace->set_text(0, "<" + TTR("Stack Trace") + ">"); - stack_trace->set_text_align(0, TreeItem::ALIGN_LEFT); + stack_trace->set_text_alignment(0, HORIZONTAL_ALIGNMENT_LEFT); error->set_metadata(0, meta); tooltip += TTR("Stack Trace:") + "\n"; } @@ -578,6 +578,12 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da error->set_tooltip(0, tooltip); error->set_tooltip(1, tooltip); + if (warning_count == 0 && error_count == 0) { + expand_all_button->set_disabled(false); + collapse_all_button->set_disabled(false); + clear_button->set_disabled(false); + } + if (oe.warning) { warning_count++; } else { @@ -782,8 +788,10 @@ void ScriptEditorDebugger::_notification(int p_what) { le_clear->connect("pressed", callable_mp(this, &ScriptEditorDebugger::_live_edit_clear)); error_tree->connect("item_selected", callable_mp(this, &ScriptEditorDebugger::_error_selected)); error_tree->connect("item_activated", callable_mp(this, &ScriptEditorDebugger::_error_activated)); + breakpoints_tree->connect("item_activated", callable_mp(this, &ScriptEditorDebugger::_breakpoint_tree_clicked)); vmem_refresh->set_icon(get_theme_icon(SNAME("Reload"), SNAME("EditorIcons"))); vmem_export->set_icon(get_theme_icon(SNAME("Save"), SNAME("EditorIcons"))); + search->set_right_icon(get_theme_icon(SNAME("Search"), SNAME("EditorIcons"))); reason->add_theme_color_override("font_color", get_theme_color(SNAME("error_color"), SNAME("Editor"))); @@ -858,6 +866,7 @@ void ScriptEditorDebugger::_notification(int p_what) { docontinue->set_icon(get_theme_icon(SNAME("DebugContinue"), SNAME("EditorIcons"))); vmem_refresh->set_icon(get_theme_icon(SNAME("Reload"), SNAME("EditorIcons"))); vmem_export->set_icon(get_theme_icon(SNAME("Save"), SNAME("EditorIcons"))); + search->set_right_icon(get_theme_icon(SNAME("Search"), SNAME("EditorIcons"))); } break; } } @@ -887,6 +896,13 @@ void ScriptEditorDebugger::_clear_breakpoints() { emit_signal("clear_breakpoints"); } +void ScriptEditorDebugger::_breakpoint_tree_clicked() { + TreeItem *selected = breakpoints_tree->get_selected(); + if (selected->has_meta("line")) { + emit_signal(SNAME("breakpoint_selected"), selected->get_parent()->get_text(0), int(selected->get_meta("line"))); + } +} + void ScriptEditorDebugger::start(Ref<RemoteDebuggerPeer> p_peer) { _clear_errors_list(); stop(); @@ -1077,7 +1093,7 @@ void ScriptEditorDebugger::_method_changed(Object *p_base, const StringName &p_n Resource *res = Object::cast_to<Resource>(p_base); - if (res && res->get_path() != String()) { + if (res && !res->get_path().is_empty()) { String respath = res->get_path(); int pathid = _get_res_path_cache(respath); @@ -1105,9 +1121,9 @@ void ScriptEditorDebugger::_property_changed(Object *p_base, const StringName &p NodePath path = editor->get_edited_scene()->get_path_to(node); int pathid = _get_node_path_cache(path); - if (p_value.is_ref()) { + if (p_value.is_ref_counted()) { Ref<Resource> res = p_value; - if (res.is_valid() && res->get_path() != String()) { + if (res.is_valid() && !res->get_path().is_empty()) { Array msg; msg.push_back(pathid); msg.push_back(p_property); @@ -1127,13 +1143,13 @@ void ScriptEditorDebugger::_property_changed(Object *p_base, const StringName &p Resource *res = Object::cast_to<Resource>(p_base); - if (res && res->get_path() != String()) { + if (res && !res->get_path().is_empty()) { String respath = res->get_path(); int pathid = _get_res_path_cache(respath); - if (p_value.is_ref()) { + if (p_value.is_ref_counted()) { Ref<Resource> res2 = p_value; - if (res2.is_valid() && res2->get_path() != String()) { + if (res2.is_valid() && !res2->get_path().is_empty()) { Array msg; msg.push_back(pathid); msg.push_back(p_property); @@ -1345,6 +1361,45 @@ void ScriptEditorDebugger::set_breakpoint(const String &p_path, int p_line, bool msg.push_back(p_line); msg.push_back(p_enabled); _put_msg("breakpoint", msg); + + TreeItem *path_item = breakpoints_tree->search_item_text(p_path); + if (path_item == nullptr) { + if (!p_enabled) { + return; + } + path_item = breakpoints_tree->create_item(); + path_item->set_text(0, p_path); + } + + int idx = 0; + TreeItem *breakpoint_item; + for (breakpoint_item = path_item->get_first_child(); breakpoint_item; breakpoint_item = breakpoint_item->get_next()) { + if ((int)breakpoint_item->get_meta("line") < p_line) { + idx++; + continue; + } + + if ((int)breakpoint_item->get_meta("line") == p_line) { + break; + } + } + + if (breakpoint_item == nullptr) { + if (!p_enabled) { + return; + } + breakpoint_item = breakpoints_tree->create_item(path_item, idx); + breakpoint_item->set_meta("line", p_line); + breakpoint_item->set_text(0, vformat(TTR("Line %d"), p_line)); + return; + } + + if (!p_enabled) { + path_item->remove_child(breakpoint_item); + if (path_item->get_first_child() == nullptr) { + breakpoints_tree->get_root()->remove_child(path_item); + } + } } void ScriptEditorDebugger::reload_scripts() { @@ -1404,12 +1459,34 @@ void ScriptEditorDebugger::_clear_errors_list() { error_tree->clear(); error_count = 0; warning_count = 0; + update_tabs(); + + expand_all_button->set_disabled(true); + collapse_all_button->set_disabled(true); + clear_button->set_disabled(true); +} + +void ScriptEditorDebugger::_breakpoints_item_rmb_selected(const Vector2 &p_pos) { + breakpoints_menu->clear(); + breakpoints_menu->set_size(Size2(1, 1)); + + const TreeItem *selected = breakpoints_tree->get_selected(); + String file = selected->get_text(0); + if (selected->has_meta("line")) { + breakpoints_menu->add_icon_item(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), TTR("Delete Breakpoint"), ACTION_DELETE_BREAKPOINT); + file = selected->get_parent()->get_text(0); + } + breakpoints_menu->add_icon_item(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), TTR("Delete All Breakpoints in: ") + file, ACTION_DELETE_BREAKPOINTS_IN_FILE); + breakpoints_menu->add_icon_item(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), TTR("Delete All Breakpoints"), ACTION_DELETE_ALL_BREAKPOINTS); + + breakpoints_menu->set_position(breakpoints_tree->get_global_position() + p_pos); + breakpoints_menu->popup(); } // Right click on specific file(s) or folder(s). void ScriptEditorDebugger::_error_tree_item_rmb_selected(const Vector2 &p_pos) { item_menu->clear(); - item_menu->set_size(Size2(1, 1)); + item_menu->reset_size(); if (error_tree->is_anything_selected()) { item_menu->add_icon_item(get_theme_icon(SNAME("ActionCopy"), SNAME("EditorIcons")), TTR("Copy Error"), ACTION_COPY_ERROR); @@ -1417,7 +1494,7 @@ void ScriptEditorDebugger::_error_tree_item_rmb_selected(const Vector2 &p_pos) { } if (item_menu->get_item_count() > 0) { - item_menu->set_position(error_tree->get_global_position() + p_pos); + item_menu->set_position(error_tree->get_screen_position() + p_pos); item_menu->popup(); } } @@ -1480,6 +1557,29 @@ void ScriptEditorDebugger::_item_menu_id_pressed(int p_option) { line_number)); } } break; + case ACTION_DELETE_BREAKPOINT: { + const TreeItem *selected = breakpoints_tree->get_selected(); + _set_breakpoint(selected->get_parent()->get_text(0), selected->get_meta("line"), false); + } break; + case ACTION_DELETE_BREAKPOINTS_IN_FILE: { + TreeItem *file_item = breakpoints_tree->get_selected(); + if (file_item->has_meta("line")) { + file_item = file_item->get_parent(); + } + + // Store first else we will be removing as we loop. + List<int> lines; + for (TreeItem *breakpoint_item = file_item->get_first_child(); breakpoint_item; breakpoint_item = breakpoint_item->get_next()) { + lines.push_back(breakpoint_item->get_meta("line")); + } + + for (const int &line : lines) { + _set_breakpoint(file_item->get_text(0), line, false); + } + } break; + case ACTION_DELETE_ALL_BREAKPOINTS: { + _clear_breakpoints(); + } break; } } @@ -1506,6 +1606,7 @@ void ScriptEditorDebugger::_bind_methods() { ADD_SIGNAL(MethodInfo("stop_requested")); ADD_SIGNAL(MethodInfo("stack_frame_selected", PropertyInfo(Variant::INT, "frame"))); ADD_SIGNAL(MethodInfo("error_selected", PropertyInfo(Variant::INT, "error"))); + ADD_SIGNAL(MethodInfo("breakpoint_selected", PropertyInfo("script"), PropertyInfo(Variant::INT, "line"))); ADD_SIGNAL(MethodInfo("set_execution", PropertyInfo("script"), PropertyInfo(Variant::INT, "line"))); ADD_SIGNAL(MethodInfo("clear_execution", PropertyInfo("script"))); ADD_SIGNAL(MethodInfo("breaked", PropertyInfo(Variant::BOOL, "reallydid"), PropertyInfo(Variant::BOOL, "can_debug"), PropertyInfo(Variant::STRING, "reason"), PropertyInfo(Variant::BOOL, "has_stackdump"))); @@ -1563,7 +1664,7 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) { editor = p_editor; tabs = memnew(TabContainer); - tabs->set_tab_align(TabContainer::ALIGN_LEFT); + tabs->set_tab_alignment(TabContainer::ALIGNMENT_LEFT); tabs->add_theme_style_override("panel", editor->get_gui_base()->get_theme_stylebox(SNAME("DebuggerPanel"), SNAME("EditorStyles"))); tabs->connect("tab_changed", callable_mp(this, &ScriptEditorDebugger::_tab_changed)); @@ -1633,9 +1734,15 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) { docontinue->set_shortcut(ED_GET_SHORTCUT("debugger/continue")); docontinue->connect("pressed", callable_mp(this, &ScriptEditorDebugger::debug_continue)); + HSplitContainer *parent_sc = memnew(HSplitContainer); + vbc->add_child(parent_sc); + parent_sc->set_v_size_flags(SIZE_EXPAND_FILL); + parent_sc->set_split_offset(500 * EDSCALE); + HSplitContainer *sc = memnew(HSplitContainer); - vbc->add_child(sc); sc->set_v_size_flags(SIZE_EXPAND_FILL); + sc->set_h_size_flags(SIZE_EXPAND_FILL); + parent_sc->add_child(sc); stack_dump = memnew(Tree); stack_dump->set_allow_reselect(true); @@ -1647,43 +1754,78 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) { stack_dump->connect("cell_selected", callable_mp(this, &ScriptEditorDebugger::_stack_dump_frame_selected)); sc->add_child(stack_dump); + VBoxContainer *inspector_vbox = memnew(VBoxContainer); + inspector_vbox->set_h_size_flags(SIZE_EXPAND_FILL); + sc->add_child(inspector_vbox); + + HBoxContainer *tools_hb = memnew(HBoxContainer); + inspector_vbox->add_child(tools_hb); + + search = memnew(LineEdit); + search->set_h_size_flags(Control::SIZE_EXPAND_FILL); + search->set_placeholder(TTR("Filter stack variables")); + search->set_clear_button_enabled(true); + tools_hb->add_child(search); + inspector = memnew(EditorDebuggerInspector); inspector->set_h_size_flags(SIZE_EXPAND_FILL); + inspector->set_v_size_flags(SIZE_EXPAND_FILL); inspector->set_enable_capitalize_paths(false); inspector->set_read_only(true); inspector->connect("object_selected", callable_mp(this, &ScriptEditorDebugger::_remote_object_selected)); inspector->connect("object_edited", callable_mp(this, &ScriptEditorDebugger::_remote_object_edited)); inspector->connect("object_property_updated", callable_mp(this, &ScriptEditorDebugger::_remote_object_property_updated)); - sc->add_child(inspector); + inspector->register_text_enter(search); + inspector->set_use_filter(true); + inspector_vbox->add_child(inspector); + + breakpoints_tree = memnew(Tree); + breakpoints_tree->set_h_size_flags(SIZE_EXPAND_FILL); + breakpoints_tree->set_column_titles_visible(true); + breakpoints_tree->set_column_title(0, TTR("Breakpoints")); + breakpoints_tree->set_allow_reselect(true); + breakpoints_tree->set_allow_rmb_select(true); + breakpoints_tree->set_hide_root(true); + breakpoints_tree->connect("item_rmb_selected", callable_mp(this, &ScriptEditorDebugger::_breakpoints_item_rmb_selected)); + breakpoints_tree->create_item(); + + parent_sc->add_child(breakpoints_tree); tabs->add_child(dbg); + + breakpoints_menu = memnew(PopupMenu); + breakpoints_menu->connect("id_pressed", callable_mp(this, &ScriptEditorDebugger::_item_menu_id_pressed)); + breakpoints_tree->add_child(breakpoints_menu); } { //errors errors_tab = memnew(VBoxContainer); errors_tab->set_name(TTR("Errors")); - HBoxContainer *errhb = memnew(HBoxContainer); - errors_tab->add_child(errhb); + HBoxContainer *error_hbox = memnew(HBoxContainer); + errors_tab->add_child(error_hbox); - Button *expand_all = memnew(Button); - expand_all->set_text(TTR("Expand All")); - expand_all->connect("pressed", callable_mp(this, &ScriptEditorDebugger::_expand_errors_list)); - errhb->add_child(expand_all); + expand_all_button = memnew(Button); + expand_all_button->set_text(TTR("Expand All")); + expand_all_button->set_disabled(true); + expand_all_button->connect("pressed", callable_mp(this, &ScriptEditorDebugger::_expand_errors_list)); + error_hbox->add_child(expand_all_button); - Button *collapse_all = memnew(Button); - collapse_all->set_text(TTR("Collapse All")); - collapse_all->connect("pressed", callable_mp(this, &ScriptEditorDebugger::_collapse_errors_list)); - errhb->add_child(collapse_all); + collapse_all_button = memnew(Button); + collapse_all_button->set_text(TTR("Collapse All")); + collapse_all_button->set_disabled(true); + collapse_all_button->connect("pressed", callable_mp(this, &ScriptEditorDebugger::_collapse_errors_list)); + error_hbox->add_child(collapse_all_button); Control *space = memnew(Control); space->set_h_size_flags(SIZE_EXPAND_FILL); - errhb->add_child(space); - - clearbutton = memnew(Button); - clearbutton->set_text(TTR("Clear")); - clearbutton->set_h_size_flags(0); - clearbutton->connect("pressed", callable_mp(this, &ScriptEditorDebugger::_clear_errors_list)); - errhb->add_child(clearbutton); + error_hbox->add_child(space); + + clear_button = memnew(Button); + clear_button->set_text(TTR("Clear")); + clear_button->set_h_size_flags(0); + clear_button->set_disabled(true); + clear_button->connect("pressed", callable_mp(this, &ScriptEditorDebugger::_clear_errors_list)); + error_hbox->add_child(clear_button); error_tree = memnew(Tree); error_tree->set_columns(2); diff --git a/editor/debugger/script_editor_debugger.h b/editor/debugger/script_editor_debugger.h index 1c1c0fd3e5..c061e7c61e 100644 --- a/editor/debugger/script_editor_debugger.h +++ b/editor/debugger/script_editor_debugger.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 */ @@ -81,6 +81,9 @@ private: enum Actions { ACTION_COPY_ERROR, ACTION_OPEN_SOURCE, + ACTION_DELETE_BREAKPOINT, + ACTION_DELETE_BREAKPOINTS_IN_FILE, + ACTION_DELETE_ALL_BREAKPOINTS, }; AcceptDialog *msgdialog; @@ -94,9 +97,14 @@ private: VBoxContainer *errors_tab; Tree *error_tree; - Button *clearbutton; + Button *expand_all_button; + Button *collapse_all_button; + Button *clear_button; PopupMenu *item_menu; + Tree *breakpoints_tree; + PopupMenu *breakpoints_menu; + EditorFileDialog *file_dialog; enum FileDialogPurpose { SAVE_MONITORS_CSV, @@ -132,6 +140,7 @@ private: LineEdit *vmem_total; Tree *stack_dump; + LineEdit *search = nullptr; EditorDebuggerInspector *inspector; SceneDebuggerTree *scene_tree; @@ -195,6 +204,7 @@ private: void _clear_errors_list(); + void _breakpoints_item_rmb_selected(const Vector2 &p_pos); void _error_tree_item_rmb_selected(const Vector2 &p_pos); void _item_menu_id_pressed(int p_option); void _tab_changed(int p_tab); @@ -208,6 +218,8 @@ private: void _set_breakpoint(const String &p_path, const int &p_line, const bool &p_enabled); void _clear_breakpoints(); + void _breakpoint_tree_clicked(); + protected: void _notification(int p_what); static void _bind_methods(); |