瀏覽代碼

Allow breakpoints in closed files

Paulb23 3 年之前
父節點
當前提交
44e260e247

+ 88 - 6
editor/plugins/script_editor_plugin.cpp

@@ -484,14 +484,32 @@ void ScriptEditor::_clear_execution(REF p_script) {
 void ScriptEditor::_set_breakpoint(REF p_script, int p_line, bool p_enabled) {
 void ScriptEditor::_set_breakpoint(REF p_script, int p_line, bool p_enabled) {
 	Ref<Script> script = Object::cast_to<Script>(*p_script);
 	Ref<Script> script = Object::cast_to<Script>(*p_script);
 	if (script.is_valid() && (script->has_source_code() || script->get_path().is_resource_file())) {
 	if (script.is_valid() && (script->has_source_code() || script->get_path().is_resource_file())) {
-		if (edit(p_script, p_line, 0, false)) {
-			editor->push_item(p_script.ptr());
-
-			ScriptEditorBase *se = _get_current_editor();
-			if (se) {
+		// Update if open.
+		for (int i = 0; i < tab_container->get_child_count(); i++) {
+			ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(i));
+			if (se && se->get_edited_resource()->get_path() == script->get_path()) {
 				se->set_breakpoint(p_line, p_enabled);
 				se->set_breakpoint(p_line, p_enabled);
+				return;
+			}
+		}
+
+		// Handle closed.
+		Dictionary state = script_editor_cache->get_value(script->get_path(), "state");
+		Array breakpoints;
+		if (state.has("breakpoints")) {
+			breakpoints = state["breakpoints"];
+		}
+
+		if (breakpoints.has(p_line)) {
+			if (!p_enabled) {
+				breakpoints.erase(p_line);
 			}
 			}
+		} else if (p_enabled) {
+			breakpoints.push_back(p_line);
 		}
 		}
+		state["breakpoints"] = breakpoints;
+		script_editor_cache->set_value(script->get_path(), "state", state);
+		EditorDebuggerNode::get_singleton()->set_breakpoint(script->get_path(), p_line + 1, false);
 	}
 	}
 }
 }
 
 
@@ -502,6 +520,34 @@ void ScriptEditor::_clear_breakpoints() {
 			se->clear_breakpoints();
 			se->clear_breakpoints();
 		}
 		}
 	}
 	}
+
+	// Clear from closed scripts.
+	List<String> cached_editors;
+	script_editor_cache->get_sections(&cached_editors);
+	for (const String &E : cached_editors) {
+		Array breakpoints = _get_cached_breakpoints_for_script(E);
+		for (int i = 0; i < breakpoints.size(); i++) {
+			EditorDebuggerNode::get_singleton()->set_breakpoint(E, (int)breakpoints[i] + 1, false);
+		}
+
+		if (breakpoints.size() > 0) {
+			Dictionary state = script_editor_cache->get_value(E, "state");
+			state["breakpoints"] = Array();
+			script_editor_cache->set_value(E, "state", state);
+		}
+	}
+}
+
+Array ScriptEditor::_get_cached_breakpoints_for_script(const String &p_path) const {
+	if (!ResourceLoader::exists(p_path, "Script") || p_path.begins_with("local://") || !script_editor_cache->has_section_key(p_path, "state")) {
+		return Array();
+	}
+
+	Dictionary state = script_editor_cache->get_value(p_path, "state");
+	if (!state.has("breakpoints")) {
+		return Array();
+	}
+	return state["breakpoints"];
 }
 }
 
 
 ScriptEditorBase *ScriptEditor::_get_current_editor() const {
 ScriptEditorBase *ScriptEditor::_get_current_editor() const {
@@ -1599,6 +1645,7 @@ void ScriptEditor::notify_script_changed(const Ref<Script> &p_script) {
 }
 }
 
 
 void ScriptEditor::get_breakpoints(List<String> *p_breakpoints) {
 void ScriptEditor::get_breakpoints(List<String> *p_breakpoints) {
+	Set<String> loaded_scripts;
 	for (int i = 0; i < tab_container->get_child_count(); i++) {
 	for (int i = 0; i < tab_container->get_child_count(); i++) {
 		ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(i));
 		ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(i));
 		if (!se) {
 		if (!se) {
@@ -1611,6 +1658,7 @@ void ScriptEditor::get_breakpoints(List<String> *p_breakpoints) {
 		}
 		}
 
 
 		String base = script->get_path();
 		String base = script->get_path();
+		loaded_scripts.insert(base);
 		if (base.begins_with("local://") || base == "") {
 		if (base.begins_with("local://") || base == "") {
 			continue;
 			continue;
 		}
 		}
@@ -1620,6 +1668,20 @@ void ScriptEditor::get_breakpoints(List<String> *p_breakpoints) {
 			p_breakpoints->push_back(base + ":" + itos((int)bpoints[j] + 1));
 			p_breakpoints->push_back(base + ":" + itos((int)bpoints[j] + 1));
 		}
 		}
 	}
 	}
+
+	// Load breakpoints that are in closed scripts.
+	List<String> cached_editors;
+	script_editor_cache->get_sections(&cached_editors);
+	for (const String &E : cached_editors) {
+		if (loaded_scripts.has(E)) {
+			continue;
+		}
+
+		Array breakpoints = _get_cached_breakpoints_for_script(E);
+		for (int i = 0; i < breakpoints.size(); i++) {
+			p_breakpoints->push_back(E + ":" + itos((int)breakpoints[i] + 1));
+		}
+	}
 }
 }
 
 
 void ScriptEditor::_members_overview_selected(int p_idx) {
 void ScriptEditor::_members_overview_selected(int p_idx) {
@@ -2582,6 +2644,16 @@ void ScriptEditor::_files_moved(const String &p_old_file, const String &p_new_fi
 	Variant state = script_editor_cache->get_value(p_old_file, "state");
 	Variant state = script_editor_cache->get_value(p_old_file, "state");
 	script_editor_cache->erase_section(p_old_file);
 	script_editor_cache->erase_section(p_old_file);
 	script_editor_cache->set_value(p_new_file, "state", state);
 	script_editor_cache->set_value(p_new_file, "state", state);
+
+	// If Script, update breakpoints with debugger.
+	Array breakpoints = _get_cached_breakpoints_for_script(p_new_file);
+	for (int i = 0; i < breakpoints.size(); i++) {
+		int line = (int)breakpoints[i] + 1;
+		EditorDebuggerNode::get_singleton()->set_breakpoint(p_old_file, line, false);
+		if (!p_new_file.begins_with("local://") && ResourceLoader::exists(p_new_file, "Script")) {
+			EditorDebuggerNode::get_singleton()->set_breakpoint(p_new_file, line, true);
+		}
+	}
 	// This is saved later when we save the editor layout.
 	// This is saved later when we save the editor layout.
 }
 }
 
 
@@ -2597,8 +2669,12 @@ void ScriptEditor::_file_removed(const String &p_removed_file) {
 		}
 		}
 	}
 	}
 
 
-	// Check un-opened.
+	// Check closed.
 	if (script_editor_cache->has_section(p_removed_file)) {
 	if (script_editor_cache->has_section(p_removed_file)) {
+		Array breakpoints = _get_cached_breakpoints_for_script(p_removed_file);
+		for (int i = 0; i < breakpoints.size(); i++) {
+			EditorDebuggerNode::get_singleton()->set_breakpoint(p_removed_file, (int)breakpoints[i] + 1, false);
+		}
 		script_editor_cache->erase_section(p_removed_file);
 		script_editor_cache->erase_section(p_removed_file);
 	}
 	}
 }
 }
@@ -3025,6 +3101,12 @@ void ScriptEditor::set_window_layout(Ref<ConfigFile> p_layout) {
 
 
 		if (!FileAccess::exists(E)) {
 		if (!FileAccess::exists(E)) {
 			script_editor_cache->erase_section(E);
 			script_editor_cache->erase_section(E);
+			continue;
+		}
+
+		Array breakpoints = _get_cached_breakpoints_for_script(E);
+		for (int i = 0; i < breakpoints.size(); i++) {
+			EditorDebuggerNode::get_singleton()->set_breakpoint(E, (int)breakpoints[i] + 1, true);
 		}
 		}
 	}
 	}
 
 

+ 1 - 0
editor/plugins/script_editor_plugin.h

@@ -382,6 +382,7 @@ class ScriptEditor : public PanelContainer {
 	void _script_created(Ref<Script> p_script);
 	void _script_created(Ref<Script> p_script);
 	void _set_breakpoint(REF p_scrpt, int p_line, bool p_enabled);
 	void _set_breakpoint(REF p_scrpt, int p_line, bool p_enabled);
 	void _clear_breakpoints();
 	void _clear_breakpoints();
+	Array _get_cached_breakpoints_for_script(const String &p_path) const;
 
 
 	ScriptEditorBase *_get_current_editor() const;
 	ScriptEditorBase *_get_current_editor() const;
 	Array _get_open_script_editors() const;
 	Array _get_open_script_editors() const;

+ 1 - 1
editor/plugins/script_text_editor.cpp

@@ -1707,7 +1707,6 @@ void ScriptTextEditor::_enable_code_editor() {
 	code_editor->connect("show_warnings_panel", callable_mp(this, &ScriptTextEditor::_show_warnings_panel));
 	code_editor->connect("show_warnings_panel", callable_mp(this, &ScriptTextEditor::_show_warnings_panel));
 	code_editor->connect("validate_script", callable_mp(this, &ScriptTextEditor::_validate_script));
 	code_editor->connect("validate_script", callable_mp(this, &ScriptTextEditor::_validate_script));
 	code_editor->connect("load_theme_settings", callable_mp(this, &ScriptTextEditor::_load_theme_settings));
 	code_editor->connect("load_theme_settings", callable_mp(this, &ScriptTextEditor::_load_theme_settings));
-	code_editor->get_text_editor()->connect("breakpoint_toggled", callable_mp(this, &ScriptTextEditor::_breakpoint_toggled));
 	code_editor->get_text_editor()->connect("symbol_lookup", callable_mp(this, &ScriptTextEditor::_lookup_symbol));
 	code_editor->get_text_editor()->connect("symbol_lookup", callable_mp(this, &ScriptTextEditor::_lookup_symbol));
 	code_editor->get_text_editor()->connect("symbol_validate", callable_mp(this, &ScriptTextEditor::_validate_symbol));
 	code_editor->get_text_editor()->connect("symbol_validate", callable_mp(this, &ScriptTextEditor::_validate_symbol));
 	code_editor->get_text_editor()->connect("gutter_added", callable_mp(this, &ScriptTextEditor::_update_gutter_indexes));
 	code_editor->get_text_editor()->connect("gutter_added", callable_mp(this, &ScriptTextEditor::_update_gutter_indexes));
@@ -1847,6 +1846,7 @@ ScriptTextEditor::ScriptTextEditor() {
 
 
 	code_editor->get_text_editor()->set_draw_breakpoints_gutter(true);
 	code_editor->get_text_editor()->set_draw_breakpoints_gutter(true);
 	code_editor->get_text_editor()->set_draw_executing_lines_gutter(true);
 	code_editor->get_text_editor()->set_draw_executing_lines_gutter(true);
+	code_editor->get_text_editor()->connect("breakpoint_toggled", callable_mp(this, &ScriptTextEditor::_breakpoint_toggled));
 
 
 	connection_gutter = 1;
 	connection_gutter = 1;
 	code_editor->get_text_editor()->add_gutter(connection_gutter);
 	code_editor->get_text_editor()->add_gutter(connection_gutter);