From 8ac841a026c0fdb32351ba94570df9143eb1de11 Mon Sep 17 00:00:00 2001 From: Hilderin <81109165+Hilderin@users.noreply.github.com> Date: Fri, 14 Jun 2024 00:13:45 -0400 Subject: [PATCH] Fix Noticeable freeze after saving a scene #93104 --- editor/editor_file_system.cpp | 63 +++++++++++++++++++++++++++++++++++ editor/editor_file_system.h | 6 ++++ editor/filesystem_dock.cpp | 37 +++----------------- editor/filesystem_dock.h | 2 -- 4 files changed, 73 insertions(+), 35 deletions(-) diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp index a1e392cd7dd..4bca42bf8b8 100644 --- a/editor/editor_file_system.cpp +++ b/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 &p_script_paths) { bool updated = false; + bool update_files_icon_cache = false; + Vector 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 &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 &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 &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 &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 } } diff --git a/editor/editor_file_system.h b/editor/editor_file_system.h index cd95d5fb951..88cd67296b0 100644 --- a/editor/editor_file_system.h +++ b/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 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 group_file_cache; + HashMap file_icon_cache; struct ImportThreadData { const ImportFile *reimport_files; @@ -295,6 +298,9 @@ class EditorFileSystem : public Node { Vector> 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(); diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index f8a82187b9d..1ffc8df2ada 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -200,33 +200,6 @@ Ref 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::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 &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 &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 &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); diff --git a/editor/filesystem_dock.h b/editor/filesystem_dock.h index 3fbff3ef194..959ace8eba9 100644 --- a/editor/filesystem_dock.h +++ b/editor/filesystem_dock.h @@ -142,7 +142,6 @@ private: FILE_NEW_SCENE, }; - HashMap icon_cache; HashMap folder_colors; Dictionary assigned_folder_colors; @@ -250,7 +249,6 @@ private: void _reselect_items_selected_on_drag_begin(bool reset = false); Ref _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 &uncollapsed_paths, bool p_select_in_favorites, bool p_unfold_path = false); void _update_tree(const Vector &p_uncollapsed_paths = Vector(), 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);