summaryrefslogtreecommitdiffstats
path: root/editor/debugger/script_editor_debugger.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'editor/debugger/script_editor_debugger.cpp')
-rw-r--r--editor/debugger/script_editor_debugger.cpp129
1 files changed, 90 insertions, 39 deletions
diff --git a/editor/debugger/script_editor_debugger.cpp b/editor/debugger/script_editor_debugger.cpp
index 178010d852..304beec681 100644
--- a/editor/debugger/script_editor_debugger.cpp
+++ b/editor/debugger/script_editor_debugger.cpp
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* script_editor_debugger.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* 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 */
-/* "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. */
-/*************************************************************************/
+/**************************************************************************/
+/* script_editor_debugger.cpp */
+/**************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/**************************************************************************/
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* 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 "script_editor_debugger.h"
@@ -46,6 +46,7 @@
#include "editor/editor_property_name_processor.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/inspector_dock.h"
#include "editor/plugins/canvas_item_editor_plugin.h"
#include "editor/plugins/editor_debugger_plugin.h"
#include "editor/plugins/node_3d_editor_plugin.h"
@@ -53,6 +54,7 @@
#include "scene/3d/camera_3d.h"
#include "scene/debugger/scene_debugger.h"
#include "scene/gui/dialogs.h"
+#include "scene/gui/grid_container.h"
#include "scene/gui/label.h"
#include "scene/gui/line_edit.h"
#include "scene/gui/margin_container.h"
@@ -306,6 +308,7 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da
String error = p_data[1];
bool has_stackdump = p_data[2];
breaked = true;
+ can_request_idle_draw = true;
can_debug = can_continue;
_update_buttons_state();
_set_reason_text(error, MESSAGE_ERROR);
@@ -317,6 +320,7 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da
tabs->set_current_tab(0);
}
profiler->set_enabled(false, false);
+ visual_profiler->set_enabled(false);
inspector->clear_cache(); // Take a chance to force remote objects update.
} else if (p_msg == "debug_exit") {
@@ -326,8 +330,12 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da
_update_buttons_state();
_set_reason_text(TTR("Execution resumed."), MESSAGE_SUCCESS);
emit_signal(SNAME("breaked"), false, false, "", false);
+
profiler->set_enabled(true, false);
profiler->disable_seeking();
+
+ visual_profiler->set_enabled(true);
+
} else if (p_msg == "set_pid") {
ERR_FAIL_COND(p_data.size() < 1);
remote_pid = p_data[0];
@@ -371,6 +379,8 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da
vmem_total->set_tooltip_text(TTR("Bytes:") + " " + itos(total));
vmem_total->set_text(String::humanize_size(total));
+ } else if (p_msg == "servers:drawn") {
+ can_request_idle_draw = true;
} else if (p_msg == "stack_dump") {
DebuggerMarshalls::ScriptStackDump stack;
stack.deserialize(p_data);
@@ -512,7 +522,7 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da
String error_title;
if (oe.callstack.size() > 0) {
// If available, use the script's stack in the error title.
- error_title = oe.callstack[oe.callstack.size() - 1].func + ": ";
+ error_title = _format_frame_text(&oe.callstack[0]) + ": ";
} else if (!oe.source_func.is_empty()) {
// Otherwise try to use the C++ source function.
error_title += oe.source_func + ": ";
@@ -523,13 +533,25 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da
error->set_text(1, error_title);
tooltip += " " + error_title + "\n";
+ // Find the language of the error's source file.
+ String source_language_name = "C++"; // Default value is the old hard-coded one.
+ const String source_file_extension = oe.source_file.get_extension();
+ for (int i = 0; i < ScriptServer::get_language_count(); ++i) {
+ ScriptLanguage *script_language = ScriptServer::get_language(i);
+ if (source_file_extension == script_language->get_extension()) {
+ source_language_name = script_language->get_name();
+ break;
+ }
+ }
+
if (!oe.error_descr.is_empty()) {
// Add item for C++ error condition.
TreeItem *cpp_cond = error_tree->create_item(error);
- cpp_cond->set_text(0, "<" + TTR("C++ Error") + ">");
+ // TRANSLATORS: %s is the name of a language, e.g. C++.
+ cpp_cond->set_text(0, "<" + vformat(TTR("%s Error"), source_language_name) + ">");
cpp_cond->set_text(1, oe.error);
cpp_cond->set_text_alignment(0, HORIZONTAL_ALIGNMENT_LEFT);
- tooltip += TTR("C++ Error:") + " " + oe.error + "\n";
+ tooltip += vformat(TTR("%s Error:"), source_language_name) + " " + oe.error + "\n";
if (source_is_project_file) {
cpp_cond->set_metadata(0, source_meta);
}
@@ -540,14 +562,18 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da
// Source of the error.
String source_txt = (source_is_project_file ? oe.source_file.get_file() : oe.source_file) + ":" + itos(oe.source_line);
if (!oe.source_func.is_empty()) {
- source_txt += " @ " + oe.source_func + "()";
+ source_txt += " @ " + oe.source_func;
+ if (!oe.source_func.ends_with(")")) {
+ source_txt += "()";
+ }
}
TreeItem *cpp_source = error_tree->create_item(error);
- cpp_source->set_text(0, "<" + (source_is_project_file ? TTR("Source") : TTR("C++ Source")) + ">");
+ // TRANSLATORS: %s is the name of a language, e.g. C++.
+ cpp_source->set_text(0, "<" + vformat(TTR("%s Source"), source_language_name) + ">");
cpp_source->set_text(1, source_txt);
cpp_source->set_text_alignment(0, HORIZONTAL_ALIGNMENT_LEFT);
- tooltip += (source_is_project_file ? TTR("Source:") : TTR("C++ Source:")) + " " + source_txt + "\n";
+ tooltip += vformat(TTR("%s Source:"), source_language_name) + " " + source_txt + "\n";
// Set metadata to highlight error line in scripts.
if (source_is_project_file) {
@@ -574,7 +600,7 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da
tooltip += TTR("Stack Trace:") + "\n";
}
- String frame_txt = infos[i].file.get_file() + ":" + itos(infos[i].line) + " @ " + infos[i].func + "()";
+ String frame_txt = _format_frame_text(&infos[i]);
tooltip += frame_txt + "\n";
stack_trace->set_text(1, frame_txt);
}
@@ -749,7 +775,16 @@ void ScriptEditorDebugger::_set_reason_text(const String &p_reason, MessageType
reason->add_theme_color_override("font_color", get_theme_color(SNAME("success_color"), SNAME("Editor")));
}
reason->set_text(p_reason);
- reason->set_tooltip_text(p_reason.word_wrap(80));
+
+ const PackedInt32Array boundaries = TS->string_get_word_breaks(p_reason, "", 80);
+ PackedStringArray lines;
+ for (int i = 0; i < boundaries.size(); i += 2) {
+ const int start = boundaries[i];
+ const int end = boundaries[i + 1];
+ lines.append(p_reason.substr(start, end - start + 1));
+ }
+
+ reason->set_tooltip_text(String("\n").join(lines));
}
void ScriptEditorDebugger::_notification(int p_what) {
@@ -811,8 +846,9 @@ void ScriptEditorDebugger::_notification(int p_what) {
msg.push_back(cam->get_far());
_put_msg("scene:override_camera_3D:transform", msg);
}
- if (breaked) {
+ if (breaked && can_request_idle_draw) {
_put_msg("servers:draw", Array());
+ can_request_idle_draw = false;
}
}
@@ -885,11 +921,20 @@ void ScriptEditorDebugger::_breakpoint_tree_clicked() {
}
}
+String ScriptEditorDebugger::_format_frame_text(const ScriptLanguage::StackInfo *info) {
+ String text = info->file.get_file() + ":" + itos(info->line) + " @ " + info->func;
+ if (!text.ends_with(")")) {
+ text += "()";
+ }
+ return text;
+}
+
void ScriptEditorDebugger::start(Ref<RemoteDebuggerPeer> p_peer) {
_clear_errors_list();
stop();
profiler->set_enabled(true, true);
+ visual_profiler->set_enabled(true);
peer = p_peer;
ERR_FAIL_COND(p_peer.is_null());
@@ -946,7 +991,11 @@ void ScriptEditorDebugger::stop() {
res_path_cache.clear();
profiler_signature.clear();
- profiler->set_enabled(true, false);
+ profiler->set_enabled(false, false);
+ profiler->set_pressed(false);
+
+ visual_profiler->set_enabled(false);
+ visual_profiler->set_pressed(false);
inspector->edit(nullptr);
_update_buttons_state();
@@ -1656,6 +1705,8 @@ ScriptEditorDebugger::ScriptEditorDebugger() {
add_child(tabs);
+ InspectorDock::get_inspector_singleton()->connect("object_id_selected", callable_mp(this, &ScriptEditorDebugger::_remote_object_selected));
+
{ //debugger
VBoxContainer *vbc = memnew(VBoxContainer);
vbc->set_name(TTR("Debugger"));