Browse Source

Prevent cache corruption when saving resources in the editor

Yuri Sizov 2 năm trước cách đây
mục cha
commit
496bd94c21
3 tập tin đã thay đổi với 22 bổ sung2 xóa
  1. 17 0
      editor/editor_node.cpp
  2. 1 0
      editor/editor_node.h
  3. 4 2
      modules/gdscript/gdscript.cpp

+ 17 - 0
editor/editor_node.cpp

@@ -1293,6 +1293,12 @@ void EditorNode::edit_resource(const Ref<Resource> &p_resource) {
 
 void EditorNode::save_resource_in_path(const Ref<Resource> &p_resource, const String &p_path) {
 	editor_data.apply_changes_in_editors();
+
+	if (saving_resources_in_path.has(p_resource)) {
+		return;
+	}
+	saving_resources_in_path.insert(p_resource);
+
 	int flg = 0;
 	if (EDITOR_GET("filesystem/on_save/compress_binary_resources")) {
 		flg |= ResourceSaver::FLAG_COMPRESS;
@@ -1307,10 +1313,16 @@ void EditorNode::save_resource_in_path(const Ref<Resource> &p_resource, const St
 		} else {
 			show_accept(TTR("Error saving resource!"), TTR("OK"));
 		}
+
+		saving_resources_in_path.erase(p_resource);
 		return;
 	}
 
 	((Resource *)p_resource.ptr())->set_path(path);
+	saving_resources_in_path.erase(p_resource);
+
+	_resource_saved(p_resource, path);
+
 	emit_signal(SNAME("resource_saved"), p_resource);
 	editor_data.notify_resource_saved(p_resource);
 }
@@ -6511,6 +6523,11 @@ void EditorNode::_renderer_selected(int p_which) {
 }
 
 void EditorNode::_resource_saved(Ref<Resource> p_resource, const String &p_path) {
+	if (singleton->saving_resources_in_path.has(p_resource)) {
+		// This is going to be handled by save_resource_in_path when the time is right.
+		return;
+	}
+
 	if (EditorFileSystem::get_singleton()) {
 		EditorFileSystem::get_singleton()->update_file(p_path);
 	}

+ 1 - 0
editor/editor_node.h

@@ -486,6 +486,7 @@ private:
 	Object *current = nullptr;
 
 	Ref<Resource> saving_resource;
+	HashSet<Ref<Resource>> saving_resources_in_path;
 
 	uint64_t update_spinner_step_msec = 0;
 	uint64_t update_spinner_step_frame = 0;

+ 4 - 2
modules/gdscript/gdscript.cpp

@@ -1010,12 +1010,14 @@ void GDScript::_bind_methods() {
 }
 
 void GDScript::set_path(const String &p_path, bool p_take_over) {
-	String old_path = path;
 	if (is_root_script()) {
 		Script::set_path(p_path, p_take_over);
 	}
-	this->path = p_path;
+
+	String old_path = path;
+	path = p_path;
 	GDScriptCache::move_script(old_path, p_path);
+
 	for (KeyValue<StringName, Ref<GDScript>> &kv : subclasses) {
 		kv.value->set_path(p_path, p_take_over);
 	}