Browse Source

Allow to ignore debugger error breaks

kobewi 1 năm trước cách đây
mục cha
commit
7d82704f12

+ 2 - 1
core/debugger/engine_debugger.cpp

@@ -127,7 +127,7 @@ void EngineDebugger::iteration(uint64_t p_frame_ticks, uint64_t p_process_ticks,
 	singleton->poll_events(true);
 }
 
-void EngineDebugger::initialize(const String &p_uri, bool p_skip_breakpoints, const Vector<String> &p_breakpoints, void (*p_allow_focus_steal_fn)()) {
+void EngineDebugger::initialize(const String &p_uri, bool p_skip_breakpoints, bool p_ignore_error_breaks, const Vector<String> &p_breakpoints, void (*p_allow_focus_steal_fn)()) {
 	register_uri_handler("tcp://", RemoteDebuggerPeerTCP::create); // TCP is the default protocol. Platforms/modules can add more.
 	if (p_uri.is_empty()) {
 		return;
@@ -160,6 +160,7 @@ void EngineDebugger::initialize(const String &p_uri, bool p_skip_breakpoints, co
 	// There is a debugger, parse breakpoints.
 	ScriptDebugger *singleton_script_debugger = singleton->get_script_debugger();
 	singleton_script_debugger->set_skip_breakpoints(p_skip_breakpoints);
+	singleton_script_debugger->set_ignore_error_breaks(p_ignore_error_breaks);
 
 	for (int i = 0; i < p_breakpoints.size(); i++) {
 		const String &bp = p_breakpoints[i];

+ 1 - 1
core/debugger/engine_debugger.h

@@ -106,7 +106,7 @@ public:
 
 	_FORCE_INLINE_ static ScriptDebugger *get_script_debugger() { return script_debugger; }
 
-	static void initialize(const String &p_uri, bool p_skip_breakpoints, const Vector<String> &p_breakpoints, void (*p_allow_focus_steal_fn)());
+	static void initialize(const String &p_uri, bool p_skip_breakpoints, bool p_ignore_error_breaks, const Vector<String> &p_breakpoints, void (*p_allow_focus_steal_fn)());
 	static void deinitialize();
 	static void register_profiler(const StringName &p_name, const Profiler &p_profiler);
 	static void unregister_profiler(const StringName &p_name);

+ 22 - 9
core/debugger/remote_debugger.cpp

@@ -413,17 +413,24 @@ void RemoteDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) {
 	}
 
 	ScriptLanguage *script_lang = script_debugger->get_break_language();
-	const String error_str = script_lang ? script_lang->debug_get_error() : "";
-	Array msg;
-	msg.push_back(p_can_continue);
-	msg.push_back(error_str);
 	ERR_FAIL_NULL(script_lang);
-	msg.push_back(script_lang->debug_get_stack_level_count() > 0);
-	msg.push_back(Thread::get_caller_id());
-	if (allow_focus_steal_fn) {
-		allow_focus_steal_fn();
+	const bool can_break = !(p_is_error_breakpoint && script_debugger->is_ignoring_error_breaks());
+	const String error_str = script_lang ? script_lang->debug_get_error() : "";
+
+	if (can_break) {
+		Array msg;
+		msg.push_back(p_can_continue);
+		msg.push_back(error_str);
+		msg.push_back(script_lang->debug_get_stack_level_count() > 0);
+		msg.push_back(Thread::get_caller_id());
+		if (allow_focus_steal_fn) {
+			allow_focus_steal_fn();
+		}
+		send_message("debug_enter", msg);
+	} else {
+		ERR_PRINT(error_str);
+		return;
 	}
-	send_message("debug_enter", msg);
 
 	Input::MouseMode mouse_mode = Input::MOUSE_MODE_VISIBLE;
 
@@ -530,6 +537,9 @@ void RemoteDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) {
 			} else if (command == "set_skip_breakpoints") {
 				ERR_FAIL_COND(data.is_empty());
 				script_debugger->set_skip_breakpoints(data[0]);
+			} else if (command == "set_ignore_error_breaks") {
+				ERR_FAIL_COND(data.size() < 1);
+				script_debugger->set_ignore_error_breaks(data[0]);
 			} else if (command == "evaluate") {
 				String expression_str = data[0];
 				int frame = data[1];
@@ -669,6 +679,9 @@ Error RemoteDebugger::_core_capture(const String &p_cmd, const Array &p_data, bo
 	} else if (p_cmd == "set_skip_breakpoints") {
 		ERR_FAIL_COND_V(p_data.is_empty(), ERR_INVALID_DATA);
 		script_debugger->set_skip_breakpoints(p_data[0]);
+	} else if (p_cmd == "set_ignore_error_breaks") {
+		ERR_FAIL_COND_V(p_data.size() < 1, ERR_INVALID_DATA);
+		script_debugger->set_ignore_error_breaks(p_data[0]);
 	} else if (p_cmd == "break") {
 		script_debugger->debug(script_debugger->get_break_language());
 	} else {

+ 8 - 0
core/debugger/script_debugger.cpp

@@ -79,6 +79,14 @@ bool ScriptDebugger::is_skipping_breakpoints() {
 	return skip_breakpoints;
 }
 
+void ScriptDebugger::set_ignore_error_breaks(bool p_ignore) {
+	ignore_error_breaks = p_ignore;
+}
+
+bool ScriptDebugger::is_ignoring_error_breaks() {
+	return ignore_error_breaks;
+}
+
 void ScriptDebugger::debug(ScriptLanguage *p_lang, bool p_can_continue, bool p_is_error_breakpoint) {
 	ScriptLanguage *prev = break_lang;
 	break_lang = p_lang;

+ 3 - 0
core/debugger/script_debugger.h

@@ -39,6 +39,7 @@ class ScriptDebugger {
 	typedef ScriptLanguage::StackInfo StackInfo;
 
 	bool skip_breakpoints = false;
+	bool ignore_error_breaks = false;
 
 	HashMap<int, HashSet<StringName>> breakpoints;
 
@@ -63,6 +64,8 @@ public:
 	ScriptLanguage *get_break_language() { return break_lang; }
 	void set_skip_breakpoints(bool p_skip_breakpoints);
 	bool is_skipping_breakpoints();
+	void set_ignore_error_breaks(bool p_ignore);
+	bool is_ignoring_error_breaks();
 	void insert_breakpoint(int p_line, const StringName &p_source);
 	void remove_breakpoint(int p_line, const StringName &p_source);
 	_ALWAYS_INLINE_ bool is_breakpoint(int p_line, const StringName &p_source) const {

+ 4 - 0
editor/debugger/editor_debugger_node.cpp

@@ -615,6 +615,10 @@ bool EditorDebuggerNode::is_skip_breakpoints() const {
 	return get_current_debugger()->is_skip_breakpoints();
 }
 
+bool EditorDebuggerNode::is_ignore_error_breaks() const {
+	return get_default_debugger()->is_ignore_error_breaks();
+}
+
 void EditorDebuggerNode::set_breakpoint(const String &p_path, int p_line, bool p_enabled) {
 	breakpoints[Breakpoint(p_path, p_line)] = p_enabled;
 	_for_all(tabs, [&](ScriptEditorDebugger *dbg) {

+ 1 - 0
editor/debugger/editor_debugger_node.h

@@ -188,6 +188,7 @@ public:
 	bool get_debug_with_external_editor() { return debug_with_external_editor; }
 
 	bool is_skip_breakpoints() const;
+	bool is_ignore_error_breaks() const;
 	void set_breakpoint(const String &p_path, int p_line, bool p_enabled);
 	void set_breakpoints(const String &p_path, const Array &p_lines);
 	void reload_all_scripts();

+ 29 - 1
editor/debugger/script_editor_debugger.cpp

@@ -102,6 +102,19 @@ void ScriptEditorDebugger::debug_skip_breakpoints() {
 	_put_msg("set_skip_breakpoints", msg, debugging_thread_id != Thread::UNASSIGNED_ID ? debugging_thread_id : Thread::MAIN_ID);
 }
 
+void ScriptEditorDebugger::debug_ignore_error_breaks() {
+	ignore_error_breaks_value = !ignore_error_breaks_value;
+	if (ignore_error_breaks_value) {
+		ignore_error_breaks->set_button_icon(get_theme_icon(SNAME("NotificationDisabled"), SNAME("EditorIcons")));
+	} else {
+		ignore_error_breaks->set_button_icon(get_theme_icon(SNAME("Notification"), SNAME("EditorIcons")));
+	}
+
+	Array msg;
+	msg.push_back(ignore_error_breaks_value);
+	_put_msg("set_ignore_error_breaks", msg);
+}
+
 void ScriptEditorDebugger::debug_next() {
 	ERR_FAIL_COND(!is_breaked());
 
@@ -916,6 +929,11 @@ void ScriptEditorDebugger::_notification(int p_what) {
 			tabs->add_theme_style_override(SceneStringName(panel), get_theme_stylebox(SNAME("DebuggerPanel"), EditorStringName(EditorStyles)));
 
 			skip_breakpoints->set_button_icon(get_editor_theme_icon(skip_breakpoints_value ? SNAME("DebugSkipBreakpointsOn") : SNAME("DebugSkipBreakpointsOff")));
+			ignore_error_breaks->set_button_icon(get_editor_theme_icon(ignore_error_breaks_value ? SNAME("NotificationDisabled") : SNAME("Notification")));
+			ignore_error_breaks->add_theme_color_override("icon_normal_color", get_theme_color(SNAME("error_color"), SNAME("Editor")));
+			ignore_error_breaks->add_theme_color_override("icon_hover_color", get_theme_color(SNAME("error_color"), SNAME("Editor")));
+			ignore_error_breaks->add_theme_color_override("icon_pressed_color", get_theme_color(SNAME("error_color"), SNAME("Editor")));
+			ignore_error_breaks->add_theme_color_override("icon_focus_color", get_theme_color(SNAME("error_color"), SNAME("Editor")));
 			copy->set_button_icon(get_editor_theme_icon(SNAME("ActionCopy")));
 			step->set_button_icon(get_editor_theme_icon(SNAME("DebugStep")));
 			next->set_button_icon(get_editor_theme_icon(SNAME("DebugNext")));
@@ -1592,10 +1610,14 @@ void ScriptEditorDebugger::reload_scripts(const Vector<String> &p_script_paths)
 	_put_msg("reload_scripts", Variant(p_script_paths).operator Array(), debugging_thread_id != Thread::UNASSIGNED_ID ? debugging_thread_id : Thread::MAIN_ID);
 }
 
-bool ScriptEditorDebugger::is_skip_breakpoints() {
+bool ScriptEditorDebugger::is_skip_breakpoints() const {
 	return skip_breakpoints_value;
 }
 
+bool ScriptEditorDebugger::is_ignore_error_breaks() const {
+	return ignore_error_breaks_value;
+}
+
 void ScriptEditorDebugger::_error_activated() {
 	TreeItem *selected = error_tree->get_selected();
 
@@ -1895,6 +1917,12 @@ ScriptEditorDebugger::ScriptEditorDebugger() {
 		skip_breakpoints->set_tooltip_text(TTR("Skip Breakpoints"));
 		skip_breakpoints->connect(SceneStringName(pressed), callable_mp(this, &ScriptEditorDebugger::debug_skip_breakpoints));
 
+		ignore_error_breaks = memnew(Button);
+		ignore_error_breaks->set_flat(true);
+		ignore_error_breaks->set_tooltip_text(TTR("Ignore Error Breaks"));
+		hbc->add_child(ignore_error_breaks);
+		ignore_error_breaks->connect("pressed", callable_mp(this, &ScriptEditorDebugger::debug_ignore_error_breaks));
+
 		hbc->add_child(memnew(VSeparator));
 
 		copy = memnew(Button);

+ 5 - 1
editor/debugger/script_editor_debugger.h

@@ -113,6 +113,7 @@ private:
 	int warning_count;
 
 	bool skip_breakpoints_value = false;
+	bool ignore_error_breaks_value = false;
 	Ref<Script> stack_script;
 
 	TabContainer *tabs = nullptr;
@@ -120,6 +121,7 @@ private:
 	Label *reason = nullptr;
 
 	Button *skip_breakpoints = nullptr;
+	Button *ignore_error_breaks = nullptr;
 	Button *copy = nullptr;
 	Button *step = nullptr;
 	Button *next = nullptr;
@@ -261,6 +263,7 @@ public:
 	void stop();
 
 	void debug_skip_breakpoints();
+	void debug_ignore_error_breaks();
 	void debug_copy();
 
 	void debug_next();
@@ -308,7 +311,8 @@ public:
 	void reload_all_scripts();
 	void reload_scripts(const Vector<String> &p_script_paths);
 
-	bool is_skip_breakpoints();
+	bool is_skip_breakpoints() const;
+	bool is_ignore_error_breaks() const;
 
 	virtual Size2 get_minimum_size() const override;
 

+ 4 - 0
editor/editor_run.cpp

@@ -136,6 +136,10 @@ Error EditorRun::run(const String &p_scene, const String &p_write_movie, const V
 		args.push_back("--skip-breakpoints");
 	}
 
+	if (EditorDebuggerNode::get_singleton()->is_ignore_error_breaks()) {
+		args.push_back("--ignore-error-breaks");
+	}
+
 	if (!p_scene.is_empty()) {
 		args.push_back(p_scene);
 	}

+ 5 - 1
main/main.cpp

@@ -593,6 +593,7 @@ void Main::print_help(const char *p_binary) {
 	print_help_title("Debug options");
 	print_help_option("-d, --debug", "Debug (local stdout debugger).\n");
 	print_help_option("-b, --breakpoints", "Breakpoint list as source::line comma-separated pairs, no spaces (use %%20 instead).\n");
+	print_help_option("--ignore-error-breaks", "If debugger is connected, prevents sending error breakpoints.\n");
 	print_help_option("--profiling", "Enable profiling in the script debugger.\n");
 	print_help_option("--gpu-profile", "Show a GPU profile of the tasks that took the most time during frame rendering.\n");
 	print_help_option("--gpu-validation", "Enable graphics API validation layers for debugging.\n");
@@ -984,6 +985,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
 	bool test_rd_support = false;
 #endif
 	bool skip_breakpoints = false;
+	bool ignore_error_breaks = false;
 	String main_pack;
 	bool quiet_stdout = false;
 	int separate_thread_render = -1; // Tri-state: -1 = not set, 0 = false, 1 = true.
@@ -1734,6 +1736,8 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
 			OS::get_singleton()->disable_crash_handler();
 		} else if (arg == "--skip-breakpoints") {
 			skip_breakpoints = true;
+		} else if (I->get() == "--ignore-error-breaks") {
+			ignore_error_breaks = true;
 #ifndef XR_DISABLED
 		} else if (arg == "--xr-mode") {
 			if (N) {
@@ -1984,7 +1988,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
 	GLOBAL_DEF(PropertyInfo(Variant::INT, "network/limits/debugger/max_errors_per_second", PROPERTY_HINT_RANGE, "1,200,1,or_greater"), 400);
 	GLOBAL_DEF(PropertyInfo(Variant::INT, "network/limits/debugger/max_warnings_per_second", PROPERTY_HINT_RANGE, "1,200,1,or_greater"), 400);
 
-	EngineDebugger::initialize(debug_uri, skip_breakpoints, breakpoints, []() {
+	EngineDebugger::initialize(debug_uri, skip_breakpoints, ignore_error_breaks, breakpoints, []() {
 		if (editor_pid) {
 			DisplayServer::get_singleton()->enable_for_stealing_focus(editor_pid);
 		}