Browse Source

Merge pull request #93147 from Hilderin/fix-freeze-after-save

Fix noticeable freeze after saving a scene
Rémi Verschelde 1 year ago
parent
commit
31f3969c86
4 changed files with 73 additions and 35 deletions
  1. 63 0
      editor/editor_file_system.cpp
  2. 6 0
      editor/editor_file_system.h
  3. 4 33
      editor/filesystem_dock.cpp
  4. 0 2
      editor/filesystem_dock.h

+ 63 - 0
editor/editor_file_system.cpp

@@ -161,6 +161,10 @@ String EditorFileSystemDirectory::get_file_script_class_icon_path(int p_idx) con
 	return files[p_idx]->script_class_icon_path;
 }
 
+String EditorFileSystemDirectory::get_file_icon_path(int p_idx) const {
+	return files[p_idx]->icon_path;
+}
+
 StringName EditorFileSystemDirectory::get_file_type(int p_idx) const {
 	ERR_FAIL_INDEX_V(p_idx, files.size(), "");
 	return files[p_idx]->type;
@@ -740,6 +744,8 @@ void EditorFileSystem::scan() {
 		scanning = false;
 		_update_pending_script_classes();
 		_update_pending_scene_groups();
+		// Update all icons so they are loaded for the FileSystemDock.
+		_update_files_icon_path();
 		emit_signal(SNAME("filesystem_changed"));
 		emit_signal(SNAME("sources_changed"), sources_changed.size() > 0);
 		first_scan = false;
@@ -1298,6 +1304,8 @@ void EditorFileSystem::_notification(int p_what) {
 					_update_scan_actions();
 					_update_pending_script_classes();
 					_update_pending_scene_groups();
+					// Update all icons so they are loaded for the FileSystemDock.
+					_update_files_icon_path();
 					emit_signal(SNAME("filesystem_changed"));
 					emit_signal(SNAME("sources_changed"), sources_changed.size() > 0);
 					first_scan = false;
@@ -1578,6 +1586,43 @@ String EditorFileSystem::_get_global_script_class(const String &p_type, const St
 	return String();
 }
 
+void EditorFileSystem::_update_file_icon_path(EditorFileSystemDirectory::FileInfo *file_info) {
+	String icon_path;
+	if (file_info->script_class_icon_path.is_empty() && !file_info->deps.is_empty()) {
+		const String &script_path = file_info->deps[0]; // Assuming the first dependency is a script.
+		if (!script_path.is_empty()) {
+			String *cached = file_icon_cache.getptr(script_path);
+			if (cached) {
+				icon_path = *cached;
+			} else {
+				if (ClassDB::is_parent_class(ResourceLoader::get_resource_type(script_path), SNAME("Script"))) {
+					int script_file;
+					EditorFileSystemDirectory *efsd = find_file(script_path, &script_file);
+					if (efsd) {
+						icon_path = efsd->files[script_file]->script_class_icon_path;
+					}
+				}
+				file_icon_cache.insert(script_path, icon_path);
+			}
+		}
+	}
+
+	file_info->icon_path = icon_path;
+}
+
+void EditorFileSystem::_update_files_icon_path(EditorFileSystemDirectory *edp) {
+	if (!edp) {
+		edp = filesystem;
+		file_icon_cache.clear();
+	}
+	for (EditorFileSystemDirectory *sub_dir : edp->subdirs) {
+		_update_files_icon_path(sub_dir);
+	}
+	for (EditorFileSystemDirectory::FileInfo *fi : edp->files) {
+		_update_file_icon_path(fi);
+	}
+}
+
 void EditorFileSystem::_update_script_classes() {
 	update_script_mutex.lock();
 
@@ -1719,6 +1764,8 @@ void EditorFileSystem::update_file(const String &p_file) {
 
 void EditorFileSystem::update_files(const Vector<String> &p_script_paths) {
 	bool updated = false;
+	bool update_files_icon_cache = false;
+	Vector<EditorFileSystemDirectory::FileInfo *> files_to_update_icon_path;
 	for (const String &file : p_script_paths) {
 		ERR_CONTINUE(file.is_empty());
 		EditorFileSystemDirectory *fs = nullptr;
@@ -1741,6 +1788,9 @@ void EditorFileSystem::update_files(const Vector<String> &p_script_paths) {
 				}
 				if (ClassDB::is_parent_class(fs->files[cpos]->type, SNAME("Script"))) {
 					_queue_update_script_class(file);
+					if (!fs->files[cpos]->script_class_icon_path.is_empty()) {
+						update_files_icon_cache = true;
+					}
 				}
 				if (fs->files[cpos]->type == SNAME("PackedScene")) {
 					_queue_update_scene_groups(file);
@@ -1789,6 +1839,7 @@ void EditorFileSystem::update_files(const Vector<String> &p_script_paths) {
 				_save_late_updated_files(); //files need to be updated in the re-scan
 			}
 
+			const String old_script_class_icon_path = fs->files[cpos]->script_class_icon_path;
 			fs->files[cpos]->type = type;
 			fs->files[cpos]->resource_script_class = script_class;
 			fs->files[cpos]->uid = uid;
@@ -1816,6 +1867,11 @@ void EditorFileSystem::update_files(const Vector<String> &p_script_paths) {
 			if (fs->files[cpos]->type == SNAME("PackedScene")) {
 				_queue_update_scene_groups(file);
 			}
+			if (fs->files[cpos]->type == SNAME("Resource")) {
+				files_to_update_icon_path.push_back(fs->files[cpos]);
+			} else if (old_script_class_icon_path != fs->files[cpos]->script_class_icon_path) {
+				update_files_icon_cache = true;
+			}
 			updated = true;
 		}
 	}
@@ -1823,6 +1879,13 @@ void EditorFileSystem::update_files(const Vector<String> &p_script_paths) {
 	if (updated) {
 		_update_pending_script_classes();
 		_update_pending_scene_groups();
+		if (update_files_icon_cache) {
+			_update_files_icon_path();
+		} else {
+			for (EditorFileSystemDirectory::FileInfo *fi : files_to_update_icon_path) {
+				_update_file_icon_path(fi);
+			}
+		}
 		call_deferred(SNAME("emit_signal"), "filesystem_changed"); //update later
 	}
 }

+ 6 - 0
editor/editor_file_system.h

@@ -66,6 +66,7 @@ class EditorFileSystemDirectory : public Object {
 		String script_class_name;
 		String script_class_extends;
 		String script_class_icon_path;
+		String icon_path;
 	};
 
 	Vector<FileInfo *> files;
@@ -91,6 +92,7 @@ public:
 	String get_file_script_class_name(int p_idx) const; //used for scripts
 	String get_file_script_class_extends(int p_idx) const; //used for scripts
 	String get_file_script_class_icon_path(int p_idx) const; //used for scripts
+	String get_file_icon_path(int p_idx) const; //used for FileSystemDock
 
 	EditorFileSystemDirectory *get_parent();
 
@@ -279,6 +281,7 @@ class EditorFileSystem : public Node {
 	void _move_group_files(EditorFileSystemDirectory *efd, const String &p_group_file, const String &p_new_location);
 
 	HashSet<String> group_file_cache;
+	HashMap<String, String> file_icon_cache;
 
 	struct ImportThreadData {
 		const ImportFile *reimport_files;
@@ -295,6 +298,9 @@ class EditorFileSystem : public Node {
 
 	Vector<Ref<EditorFileSystemImportFormatSupportQuery>> import_support_queries;
 
+	void _update_file_icon_path(EditorFileSystemDirectory::FileInfo *file_info);
+	void _update_files_icon_path(EditorFileSystemDirectory *edp = nullptr);
+
 protected:
 	void _notification(int p_what);
 	static void _bind_methods();

+ 4 - 33
editor/filesystem_dock.cpp

@@ -200,33 +200,6 @@ Ref<Texture2D> FileSystemDock::_get_tree_item_icon(bool p_is_valid, const String
 	}
 }
 
-String FileSystemDock::_get_entry_script_icon(const EditorFileSystemDirectory *p_dir, int p_file) {
-	const PackedStringArray &deps = p_dir->get_file_deps(p_file);
-	if (deps.is_empty()) {
-		return String();
-	}
-
-	const String &script_path = deps[0]; // Assuming the first dependency is a script.
-	if (script_path.is_empty() || !ClassDB::is_parent_class(ResourceLoader::get_resource_type(script_path), SNAME("Script"))) {
-		return String();
-	}
-
-	String *cached = icon_cache.getptr(script_path);
-	if (cached) {
-		return *cached;
-	}
-
-	HashMap<String, String>::Iterator I;
-	int script_file;
-	EditorFileSystemDirectory *efsd = EditorFileSystem::get_singleton()->find_file(script_path, &script_file);
-	if (efsd) {
-		I = icon_cache.insert(script_path, efsd->get_file_script_class_icon_path(script_file));
-	} else {
-		I = icon_cache.insert(script_path, String());
-	}
-	return I->value;
-}
-
 bool FileSystemDock::_create_tree(TreeItem *p_parent, EditorFileSystemDirectory *p_dir, Vector<String> &uncollapsed_paths, bool p_select_in_favorites, bool p_unfold_path) {
 	bool parent_should_expand = false;
 
@@ -316,7 +289,7 @@ bool FileSystemDock::_create_tree(TreeItem *p_parent, EditorFileSystemDirectory
 			FileInfo fi;
 			fi.name = p_dir->get_file(i);
 			fi.type = p_dir->get_file_type(i);
-			fi.icon_path = _get_entry_script_icon(p_dir, i);
+			fi.icon_path = p_dir->get_file_icon_path(i);
 			fi.import_broken = !p_dir->get_file_import_is_valid(i);
 			fi.modified_time = p_dir->get_file_modified_time(i);
 
@@ -414,8 +387,6 @@ void FileSystemDock::_update_tree(const Vector<String> &p_uncollapsed_paths, boo
 	updating_tree = true;
 	TreeItem *root = tree->create_item();
 
-	icon_cache.clear();
-
 	// Handles the favorites.
 	TreeItem *favorites_item = tree->create_item(root);
 	favorites_item->set_icon(0, get_editor_theme_icon(SNAME("Favorites")));
@@ -463,7 +434,7 @@ void FileSystemDock::_update_tree(const Vector<String> &p_uncollapsed_paths, boo
 			int index;
 			EditorFileSystemDirectory *dir = EditorFileSystem::get_singleton()->find_file(favorite, &index);
 			if (dir) {
-				icon = _get_tree_item_icon(dir->get_file_import_is_valid(index), dir->get_file_type(index), _get_entry_script_icon(dir, index));
+				icon = _get_tree_item_icon(dir->get_file_import_is_valid(index), dir->get_file_type(index), dir->get_file_icon_path(index));
 			} else {
 				icon = get_editor_theme_icon(SNAME("File"));
 			}
@@ -1017,7 +988,7 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) {
 				fi.path = favorite;
 				if (efd) {
 					fi.type = efd->get_file_type(index);
-					fi.icon_path = _get_entry_script_icon(efd, index);
+					fi.icon_path = efd->get_file_icon_path(index);
 					fi.import_broken = !efd->get_file_import_is_valid(index);
 					fi.modified_time = efd->get_file_modified_time(index);
 				} else {
@@ -1110,7 +1081,7 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) {
 				fi.name = efd->get_file(i);
 				fi.path = directory.path_join(fi.name);
 				fi.type = efd->get_file_type(i);
-				fi.icon_path = _get_entry_script_icon(efd, i);
+				fi.icon_path = efd->get_file_icon_path(i);
 				fi.import_broken = !efd->get_file_import_is_valid(i);
 				fi.modified_time = efd->get_file_modified_time(i);
 

+ 0 - 2
editor/filesystem_dock.h

@@ -142,7 +142,6 @@ private:
 		FILE_NEW_SCENE,
 	};
 
-	HashMap<String, String> icon_cache;
 	HashMap<String, Color> folder_colors;
 	Dictionary assigned_folder_colors;
 
@@ -250,7 +249,6 @@ private:
 	void _reselect_items_selected_on_drag_begin(bool reset = false);
 
 	Ref<Texture2D> _get_tree_item_icon(bool p_is_valid, const String &p_file_type, const String &p_icon_path);
-	String _get_entry_script_icon(const EditorFileSystemDirectory *p_dir, int p_file);
 	bool _create_tree(TreeItem *p_parent, EditorFileSystemDirectory *p_dir, Vector<String> &uncollapsed_paths, bool p_select_in_favorites, bool p_unfold_path = false);
 	void _update_tree(const Vector<String> &p_uncollapsed_paths = Vector<String>(), bool p_uncollapse_root = false, bool p_select_in_favorites = false, bool p_unfold_path = false);
 	void _navigate_to_path(const String &p_path, bool p_select_in_favorites = false);