diff --git a/core/io/file_access.cpp b/core/io/file_access.cpp index a762e24ff38..1cf388b33a7 100644 --- a/core/io/file_access.cpp +++ b/core/io/file_access.cpp @@ -59,9 +59,11 @@ bool FileAccess::exists(const String &p_name) { return true; } - // Using file_exists because it's faster then trying to open the file. - Ref ret = create_for_path(p_name); - return ret->file_exists(p_name); + Ref f = open(p_name, READ); + if (f.is_null()) { + return false; + } + return true; } void FileAccess::_set_access_type(AccessType p_access) { diff --git a/core/io/resource_importer.cpp b/core/io/resource_importer.cpp index 49ba7b03587..fcf4a727ca4 100644 --- a/core/io/resource_importer.cpp +++ b/core/io/resource_importer.cpp @@ -362,24 +362,6 @@ Variant ResourceFormatImporter::get_resource_metadata(const String &p_path) cons return pat.metadata; } - -Error ResourceFormatImporter::get_resource_import_info(const String &p_path, StringName &r_type, ResourceUID::ID &r_uid, String &r_import_group_file) const { - PathAndType pat; - Error err = _get_path_and_type(p_path, pat); - - if (err == OK) { - r_type = pat.type; - r_uid = pat.uid; - r_import_group_file = pat.group_file; - } else { - r_type = ""; - r_uid = ResourceUID::INVALID_ID; - r_import_group_file = ""; - } - - return err; -} - void ResourceFormatImporter::get_classes_used(const String &p_path, HashSet *r_classes) { PathAndType pat; Error err = _get_path_and_type(p_path, pat); diff --git a/core/io/resource_importer.h b/core/io/resource_importer.h index 4a38a7fb4ab..dbd9e70d16b 100644 --- a/core/io/resource_importer.h +++ b/core/io/resource_importer.h @@ -93,9 +93,6 @@ public: String get_import_settings_hash() const; String get_import_base_path(const String &p_for_file) const; - - Error get_resource_import_info(const String &p_path, StringName &r_type, ResourceUID::ID &r_uid, String &r_import_group_file) const; - ResourceFormatImporter(); }; diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp index 7299631fec4..c3c37aa89d5 100644 --- a/core/io/resource_loader.cpp +++ b/core/io/resource_loader.cpp @@ -957,39 +957,36 @@ String ResourceLoader::_path_remap(const String &p_path, bool *r_translation_rem new_path = path_remaps[new_path]; } else { // Try file remap. - // Usually, there's no remap file and FileAccess::exists() is faster then FileAccess::open(). - if (FileAccess::exists(new_path + ".remap")) { - Error err; - Ref f = FileAccess::open(new_path + ".remap", FileAccess::READ, &err); - if (f.is_valid()) { - VariantParser::StreamFile stream; - stream.f = f; + Error err; + Ref f = FileAccess::open(new_path + ".remap", FileAccess::READ, &err); + if (f.is_valid()) { + VariantParser::StreamFile stream; + stream.f = f; - String assign; - Variant value; - VariantParser::Tag next_tag; + String assign; + Variant value; + VariantParser::Tag next_tag; - int lines = 0; - String error_text; - while (true) { - assign = Variant(); - next_tag.fields.clear(); - next_tag.name = String(); + int lines = 0; + String error_text; + while (true) { + assign = Variant(); + next_tag.fields.clear(); + next_tag.name = String(); - err = VariantParser::parse_tag_assign_eof(&stream, lines, error_text, next_tag, assign, value, nullptr, true); - if (err == ERR_FILE_EOF) { - break; - } else if (err != OK) { - ERR_PRINT("Parse error: " + p_path + ".remap:" + itos(lines) + " error: " + error_text + "."); - break; - } + err = VariantParser::parse_tag_assign_eof(&stream, lines, error_text, next_tag, assign, value, nullptr, true); + if (err == ERR_FILE_EOF) { + break; + } else if (err != OK) { + ERR_PRINT("Parse error: " + p_path + ".remap:" + itos(lines) + " error: " + error_text + "."); + break; + } - if (assign == "path") { - new_path = value; - break; - } else if (next_tag.name != "remap") { - break; - } + if (assign == "path") { + new_path = value; + break; + } else if (next_tag.name != "remap") { + break; } } } diff --git a/doc/classes/EditorFileSystem.xml b/doc/classes/EditorFileSystem.xml index f3129ede650..08b40c78000 100644 --- a/doc/classes/EditorFileSystem.xml +++ b/doc/classes/EditorFileSystem.xml @@ -90,18 +90,6 @@ Emitted if at least one resource is reloaded when the filesystem is scanned. - - - - Emitted when a new scan of the project files has started. - - - - - - Emitted when a scan of the project files has ended. - - Emitted when the list of global script classes gets updated. diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp index 035e2dcd654..37e00bf0428 100644 --- a/editor/editor_file_system.cpp +++ b/editor/editor_file_system.cpp @@ -316,6 +316,8 @@ void EditorFileSystem::_scan_filesystem() { EditorProgressBG scan_progress("efs", "ScanFS", 1000); ScanProgress sp; + sp.low = 0; + sp.hi = 1; sp.progress = &scan_progress; new_filesystem = memnew(EditorFileSystemDirectory); @@ -323,8 +325,7 @@ void EditorFileSystem::_scan_filesystem() { Ref d = DirAccess::create(DirAccess::ACCESS_RESOURCES); d->change_dir("res://"); - - _scan_new_dir(new_filesystem, d, &sp, 1); + _scan_new_dir(new_filesystem, d, sp); dep_update_list.clear(); file_cache.clear(); //clear caches, no longer needed @@ -559,27 +560,15 @@ bool EditorFileSystem::_scan_import_support(const Vector &reimports) { return false; } -bool EditorFileSystem::_update_scan_actions(bool p_show_progress) { +bool EditorFileSystem::_update_scan_actions() { sources_changed.clear(); bool fs_changed = false; Vector reimports; Vector reloads; - HashMap import_group_files; - EditorProgress *editor_progress = nullptr; - if (p_show_progress && scan_actions.size() > 0) { - editor_progress = memnew(EditorProgress("_update_scan_actions", TTR("Scanning actions..."), scan_actions.size())); - editor_progress->step("", 0, true); - } - - int idx_action = 0; for (const ItemAction &ia : scan_actions) { - if (editor_progress) { - editor_progress->step(ia.file, idx_action, false); - } - idx_action++; switch (ia.action) { case ItemAction::ACTION_NONE: { } break; @@ -654,17 +643,10 @@ bool EditorFileSystem::_update_scan_actions(bool p_show_progress) { if (_test_for_reimport(full_path, false)) { //must reimport reimports.push_back(full_path); - if (!ia.import_group_file.is_empty()) { - import_group_files[full_path] = ia.import_group_file; - } Vector dependencies = _get_dependencies(full_path); for (const String &dependency_path : dependencies) { if (import_extensions.has(dependency_path.get_extension())) { reimports.push_back(dependency_path); - String import_groupe_file = ResourceFormatImporter::get_singleton()->get_import_group_file(dependency_path); - if (!ia.import_group_file.is_empty()) { - import_group_files[dependency_path] = import_groupe_file; - } } } } else { @@ -694,8 +676,6 @@ bool EditorFileSystem::_update_scan_actions(bool p_show_progress) { } } - memdelete_notnull(editor_progress); - if (_scan_extensions()) { //needs editor restart //extensions also may provide filetypes to be imported, so they must run before importing @@ -714,7 +694,7 @@ bool EditorFileSystem::_update_scan_actions(bool p_show_progress) { return true; } - _reimport_files_internal(reimports, &import_group_files); + reimport_files(reimports); } else { //reimport files will update the uid cache file so if nothing was reimported, update it manually ResourceUID::get_singleton()->update_cache(); @@ -745,10 +725,10 @@ void EditorFileSystem::scan() { } _update_extensions(); + if (!use_threads) { scanning = true; scan_total = 0; - emit_signal(SNAME("scan_started"), true); _scan_filesystem(); if (filesystem) { memdelete(filesystem); @@ -756,7 +736,7 @@ void EditorFileSystem::scan() { //file_type_cache.clear(); filesystem = new_filesystem; new_filesystem = nullptr; - _update_scan_actions(true); + _update_scan_actions(); scanning = false; _update_pending_script_classes(); _update_pending_scene_groups(); @@ -769,50 +749,28 @@ void EditorFileSystem::scan() { Thread::Settings s; scanning = true; scan_total = 0; - emit_signal(SNAME("scan_started"), true); s.priority = Thread::PRIORITY_LOW; thread.start(_thread_func, this, s); + //tree->hide(); + //progress->show(); } } -void EditorFileSystem::ScanProgress::increment() { - real++; - nb_file_to_scan--; - current = CLAMP(real / estimated, current, 1); - progress->step(current * 1000); - EditorFileSystem::singleton->scan_total = current; +void EditorFileSystem::ScanProgress::update(int p_current, int p_total) const { + float ratio = low + ((hi - low) / p_total) * p_current; + progress->step(ratio * 1000); + EditorFileSystem::singleton->scan_total = ratio; } -void EditorFileSystem::ScanProgress::update_estimated(int p_depth, int p_nb_sub_dirs, int p_nb_files) { - // The algorithm calculates an estimated value for the progress of scanning directories and files. - // It adjusts the estimate based on the number of directories and files discovered so far, - // and ensures the estimated value does not decrease drastically between updates. - float average = 10; - directories_processed++; - if (nb_dir_to_scan > 0) { - nb_dir_to_scan--; - } - nb_dir_to_scan += p_nb_sub_dirs; - nb_file_to_scan += p_nb_files; - - if (directories_processed > 2) { - average = (real + nb_file_to_scan) / directories_processed; - if (average < 10) { - average = 10; - } - } - - float old_estimated = estimated; - estimated = real + nb_file_to_scan + (nb_dir_to_scan * average * p_depth); - if (estimated < old_estimated * 0.95) { - estimated = old_estimated * 0.95; - } - if (estimated <= real + average) { - estimated = real + average; - } +EditorFileSystem::ScanProgress EditorFileSystem::ScanProgress::get_sub(int p_current, int p_total) const { + ScanProgress sp = *this; + float slice = (sp.hi - sp.low) / p_total; + sp.low += slice * p_current; + sp.hi = slice; + return sp; } -void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, Ref &da, ScanProgress *p_progress, int p_depth) { +void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, Ref &da, const ScanProgress &p_progress) { List dirs; List files; @@ -852,12 +810,11 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, Ref(); files.sort_custom(); - p_progress->update_estimated(p_depth, dirs.size(), files.size()); - + int total = dirs.size() + files.size(); int idx = 0; + for (List::Element *E = dirs.front(); E; E = E->next(), idx++) { - String name = E->get(); - if (da->change_dir(name) == OK) { + if (da->change_dir(E->get()) == OK) { String d = da->get_current_dir(); if (d == cd || !d.begins_with(cd)) { @@ -868,27 +825,38 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, Refparent = p_dir; efd->name = E->get(); - _scan_new_dir(efd, da, p_progress, p_depth + 1); + _scan_new_dir(efd, da, p_progress.get_sub(idx, total)); - // Folders are already sorted with FileNoCaseComparator. - p_dir->subdirs.push_back(efd); + int idx2 = 0; + for (int i = 0; i < p_dir->subdirs.size(); i++) { + if (efd->name.filenocasecmp_to(p_dir->subdirs[i]->name) < 0) { + break; + } + idx2++; + } + if (idx2 == p_dir->subdirs.size()) { + p_dir->subdirs.push_back(efd); + } else { + p_dir->subdirs.insert(idx2, efd); + } da->change_dir(".."); } } else { ERR_PRINT("Cannot go into subdir '" + E->get() + "'."); } + + p_progress.update(idx, total); } for (List::Element *E = files.front(); E; E = E->next(), idx++) { - String name = E->get(); - String ext = name.get_extension().to_lower(); + String ext = E->get().get_extension().to_lower(); if (!valid_extensions.has(ext)) { continue; //invalid } EditorFileSystemDirectory::FileInfo *fi = memnew(EditorFileSystemDirectory::FileInfo); - fi->file = name; + fi->file = E->get(); String path = cd.path_join(fi->file); @@ -916,6 +884,14 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, Refscript_class_extends = fc->script_class_extends; fi->script_class_icon_path = fc->script_class_icon_path; + if (revalidate_import_files && !ResourceFormatImporter::get_singleton()->are_import_settings_valid(path)) { + ItemAction ia; + ia.action = ItemAction::ACTION_FILE_TEST_REIMPORT; + ia.dir = p_dir; + ia.file = E->get(); + scan_actions.push_back(ia); + } + if (fc->type.is_empty()) { fi->type = ResourceLoader::get_resource_type(path); fi->resource_script_class = ResourceLoader::get_resource_script_class(path); @@ -924,23 +900,15 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, Refare_import_settings_valid(path)) { - ItemAction ia; - ia.action = ItemAction::ACTION_FILE_TEST_REIMPORT; - ia.dir = p_dir; - ia.file = E->get(); - ia.import_group_file = fi->import_group_file; - scan_actions.push_back(ia); - } - if (fc->uid == ResourceUID::INVALID_ID) { // imported files should always have a UID, so attempt to fetch it. fi->uid = ResourceLoader::get_resource_uid(path); } } else { - // Using get_resource_import_info() to prevent calling 3 times ResourceFormatImporter::_get_path_and_type. - ResourceFormatImporter::get_singleton()->get_resource_import_info(path, fi->type, fi->uid, fi->import_group_file); + fi->type = ResourceFormatImporter::get_singleton()->get_resource_type(path); + fi->uid = ResourceFormatImporter::get_singleton()->get_resource_uid(path); + fi->import_group_file = ResourceFormatImporter::get_singleton()->get_import_group_file(path); fi->script_class_name = _get_global_script_class(fi->type, path, &fi->script_class_extends, &fi->script_class_icon_path); fi->modified_time = 0; fi->import_modified_time = 0; @@ -950,7 +918,6 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, Refget(); - ia.import_group_file = fi->import_group_file; scan_actions.push_back(ia); } } else { @@ -1001,11 +968,11 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, Reffiles.push_back(fi); - p_progress->increment(); + p_progress.update(idx, total); } } -void EditorFileSystem::_scan_fs_changes(EditorFileSystemDirectory *p_dir, ScanProgress *p_progress) { +void EditorFileSystem::_scan_fs_changes(EditorFileSystemDirectory *p_dir, const ScanProgress &p_progress) { uint64_t current_mtime = FileAccess::get_modified_time(p_dir->get_path()); bool updated_dir = false; @@ -1061,7 +1028,7 @@ void EditorFileSystem::_scan_fs_changes(EditorFileSystemDirectory *p_dir, ScanPr efd->name = f; Ref d = DirAccess::create(DirAccess::ACCESS_RESOURCES); d->change_dir(cd.path_join(f)); - _scan_new_dir(efd, d, p_progress, 1); + _scan_new_dir(efd, d, p_progress.get_sub(1, 1)); ItemAction ia; ia.action = ItemAction::ACTION_DIR_ADD; @@ -1113,7 +1080,6 @@ void EditorFileSystem::_scan_fs_changes(EditorFileSystemDirectory *p_dir, ScanPr ia.action = ItemAction::ACTION_FILE_TEST_REIMPORT; ia.dir = p_dir; ia.file = f; - ia.import_group_file = fi->import_group_file; scan_actions.push_back(ia); } @@ -1164,7 +1130,6 @@ void EditorFileSystem::_scan_fs_changes(EditorFileSystemDirectory *p_dir, ScanPr ia.action = ItemAction::ACTION_FILE_TEST_REIMPORT; ia.dir = p_dir; ia.file = p_dir->files[i]->file; - ia.import_group_file = p_dir->files[i]->import_group_file; scan_actions.push_back(ia); } } else if (ResourceCache::has(path)) { //test for potential reload @@ -1214,7 +1179,9 @@ void EditorFileSystem::_thread_func_sources(void *_userdata) { EditorProgressBG pr("sources", TTR("ScanSources"), 1000); ScanProgress sp; sp.progress = ≺ - efs->_scan_fs_changes(efs->filesystem, &sp); + sp.hi = 1; + sp.low = 0; + efs->_scan_fs_changes(efs->filesystem, sp); } efs->scanning_changes_done.set(); } @@ -1237,9 +1204,10 @@ void EditorFileSystem::scan_changes() { EditorProgressBG pr("sources", TTR("ScanSources"), 1000); ScanProgress sp; sp.progress = ≺ + sp.hi = 1; + sp.low = 0; scan_total = 0; - emit_signal(SNAME("scan_started"), false); - _scan_fs_changes(filesystem, &sp); + _scan_fs_changes(filesystem, sp); bool changed = _update_scan_actions(); _update_pending_script_classes(); _update_pending_scene_groups(); @@ -1254,7 +1222,6 @@ void EditorFileSystem::scan_changes() { ERR_FAIL_COND(thread_sources.is_started()); set_process(true); scan_total = 0; - emit_signal(SNAME("scan_started"), false); Thread::Settings s; s.priority = Thread::PRIORITY_LOW; thread_sources.start(_thread_func_sources, this, s); @@ -1308,7 +1275,6 @@ void EditorFileSystem::_notification(int p_what) { if (thread_sources.is_started()) { thread_sources.wait_to_finish(); } - emit_signal(SNAME("scan_stopped"), false); bool changed = _update_scan_actions(); _update_pending_script_classes(); _update_pending_scene_groups(); @@ -1329,8 +1295,7 @@ void EditorFileSystem::_notification(int p_what) { filesystem = new_filesystem; new_filesystem = nullptr; thread.wait_to_finish(); - emit_signal(SNAME("scan_stopped"), true); - _update_scan_actions(true); + _update_scan_actions(); _update_pending_script_classes(); _update_pending_scene_groups(); emit_signal(SNAME("filesystem_changed")); @@ -1613,20 +1578,10 @@ String EditorFileSystem::_get_global_script_class(const String &p_type, const St return String(); } -void EditorFileSystem::_update_script_classes(bool p_show_progress) { +void EditorFileSystem::_update_script_classes() { update_script_mutex.lock(); - EditorProgress *ep = nullptr; - if (p_show_progress && update_script_paths.size() > 0) { - ep = memnew(EditorProgress("update_scripts_classes", TTR("(Re)importing Scripts"), update_script_paths.size() * 2)); - ep->step("", 0, true); - } - - int step_count = 0; for (const String &path : update_script_paths) { - if (ep) { - ep->step(TTR("Registering global classes..."), step_count++, false); - } EditorFileSystem::get_singleton()->register_global_class_script(path, path); } @@ -1635,10 +1590,6 @@ void EditorFileSystem::_update_script_classes(bool p_show_progress) { int index = -1; EditorFileSystemDirectory *efd = find_file(path, &index); - if (ep) { - ep->step(TTR("Updating documentation..."), step_count++, false); - } - if (!efd || index < 0) { // The file was removed continue; @@ -1659,8 +1610,6 @@ void EditorFileSystem::_update_script_classes(bool p_show_progress) { } } - memdelete_notnull(ep); - update_script_paths.clear(); update_script_mutex.unlock(); @@ -1677,9 +1626,9 @@ void EditorFileSystem::_update_script_classes(bool p_show_progress) { ResourceSaver::add_custom_savers(); } -void EditorFileSystem::_update_pending_script_classes(bool p_show_progress) { +void EditorFileSystem::_update_pending_script_classes() { if (!update_script_paths.is_empty()) { - _update_script_classes(p_show_progress); + _update_script_classes(); } else { // In case the class cache file was removed somehow, regenerate it. if (!FileAccess::exists(ScriptServer::get_global_class_cache_file_path())) { @@ -1719,7 +1668,7 @@ void EditorFileSystem::_update_scene_groups() { } if (ep) { - ep->step(TTR("Updating Scene Groups..."), step_count++, false); + ep->step(TTR("Updating Scene Groups..."), step_count++); } } @@ -1800,13 +1749,9 @@ void EditorFileSystem::update_files(const Vector &p_script_paths) { fs->files.remove_at(cpos); } - // Preventing update of scripts and scene groups while first scan. - // Some ResourceLoader resave files which invoke update_file while loading (ex: ResourceImporterCSVTranslation). - if (!first_scan) { - _update_pending_script_classes(); - _update_pending_scene_groups(); - call_deferred(SNAME("emit_signal"), "filesystem_changed"); // Update later. - } + _update_pending_script_classes(); + _update_pending_scene_groups(); + call_deferred(SNAME("emit_signal"), "filesystem_changed"); //update later return; } @@ -1877,13 +1822,9 @@ void EditorFileSystem::update_files(const Vector &p_script_paths) { } } - // Preventing update of scripts and scene groups while first scan. - // Some ResourceLoader resave files which invoke update_file while loading (ex: ResourceImporterCSVTranslation). - if (!first_scan) { - _update_pending_script_classes(); - _update_pending_scene_groups(); - call_deferred(SNAME("emit_signal"), "filesystem_changed"); // Update later. - } + _update_pending_script_classes(); + _update_pending_scene_groups(); + call_deferred(SNAME("emit_signal"), "filesystem_changed"); //update later } HashSet EditorFileSystem::get_valid_extensions() const { @@ -2404,152 +2345,132 @@ void EditorFileSystem::_reimport_thread(uint32_t p_index, ImportThreadData *p_im } void EditorFileSystem::reimport_files(const Vector &p_files) { - _reimport_files_internal(p_files, nullptr); -} - -void EditorFileSystem::_reimport_files_internal(const Vector &p_files, const HashMap *p_import_group_files) { ERR_FAIL_COND_MSG(importing, "Attempted to call reimport_files() recursively, this is not allowed."); importing = true; Vector reloads; - { - EditorProgress pr("reimport", TTR("(Re)Importing Assets"), p_files.size()); - pr.step("", 0, true); + EditorProgress pr("reimport", TTR("(Re)Importing Assets"), p_files.size()); - Vector reimport_files; - HashMap import_group_files = *p_import_group_files; + Vector reimport_files; - HashSet groups_to_reimport; + HashSet groups_to_reimport; - for (int i = 0; i < p_files.size(); i++) { - String file = p_files[i]; + for (int i = 0; i < p_files.size(); i++) { + String file = p_files[i]; - ResourceUID::ID uid = ResourceUID::get_singleton()->text_to_id(file); - if (uid != ResourceUID::INVALID_ID && ResourceUID::get_singleton()->has_id(uid)) { - file = ResourceUID::get_singleton()->get_id_path(uid); - } - - String group_file; - if (p_import_group_files) { - if (p_import_group_files->has(file)) { - group_file = (*p_import_group_files)[file]; - } - } else { - group_file = ResourceFormatImporter::get_singleton()->get_import_group_file(file); - } - - if (group_file_cache.has(file)) { - // Maybe the file itself is a group! - groups_to_reimport.insert(file); - // Groups do not belong to groups. - group_file = String(); - } else if (groups_to_reimport.has(file)) { - // Groups do not belong to groups. - group_file = String(); - } else if (!group_file.is_empty()) { - // It's a group file, add group to import and skip this file. - groups_to_reimport.insert(group_file); - } else { - // It's a regular file. - ImportFile ifile; - ifile.path = file; - ResourceFormatImporter::get_singleton()->get_import_order_threads_and_importer(file, ifile.order, ifile.threaded, ifile.importer); - reloads.push_back(file); - reimport_files.push_back(ifile); - } - - // Group may have changed, so also update group reference. - if (!p_import_group_files) { - EditorFileSystemDirectory *fs = nullptr; - int cpos = -1; - if (_find_file(file, &fs, cpos)) { - fs->files.write[cpos]->import_group_file = group_file; - } - } - - pr.step(TTR("Preparing files to reimport..."), i, false); + ResourceUID::ID uid = ResourceUID::get_singleton()->text_to_id(file); + if (uid != ResourceUID::INVALID_ID && ResourceUID::get_singleton()->has_id(uid)) { + file = ResourceUID::get_singleton()->get_id_path(uid); } - reimport_files.sort(); + String group_file = ResourceFormatImporter::get_singleton()->get_import_group_file(file); -#ifdef THREADS_ENABLED - bool use_multiple_threads = GLOBAL_GET("editor/import/use_multiple_threads"); -#else - bool use_multiple_threads = false; -#endif - - int from = 0; - for (int i = 0; i < reimport_files.size(); i++) { - if (groups_to_reimport.has(reimport_files[i].path)) { - continue; - } - - if (use_multiple_threads && reimport_files[i].threaded) { - if (i + 1 == reimport_files.size() || reimport_files[i + 1].importer != reimport_files[from].importer) { - if (from - i == 0) { - // Single file, do not use threads. - pr.step(reimport_files[i].path.get_file(), i, false); - _reimport_file(reimport_files[i].path); - } else { - Ref importer = ResourceFormatImporter::get_singleton()->get_importer_by_name(reimport_files[from].importer); - ERR_CONTINUE(importer.is_null()); - - importer->import_threaded_begin(); - - ImportThreadData tdata; - tdata.max_index.set(from); - tdata.reimport_from = from; - tdata.reimport_files = reimport_files.ptr(); - - WorkerThreadPool::GroupID group_task = WorkerThreadPool::get_singleton()->add_template_group_task(this, &EditorFileSystem::_reimport_thread, &tdata, i - from + 1, -1, false, vformat(TTR("Import resources of type: %s"), reimport_files[from].importer)); - int current_index = from - 1; - do { - if (current_index < tdata.max_index.get()) { - current_index = tdata.max_index.get(); - pr.step(reimport_files[current_index].path.get_file(), current_index, false); - } - OS::get_singleton()->delay_usec(1); - } while (!WorkerThreadPool::get_singleton()->is_group_task_completed(group_task)); - - WorkerThreadPool::get_singleton()->wait_for_group_task_completion(group_task); - - importer->import_threaded_end(); - } - - from = i + 1; - } - - } else { - pr.step(reimport_files[i].path.get_file(), i, false); - _reimport_file(reimport_files[i].path); - } + if (group_file_cache.has(file)) { + // Maybe the file itself is a group! + groups_to_reimport.insert(file); + // Groups do not belong to groups. + group_file = String(); + } else if (groups_to_reimport.has(file)) { + // Groups do not belong to groups. + group_file = String(); + } else if (!group_file.is_empty()) { + // It's a group file, add group to import and skip this file. + groups_to_reimport.insert(group_file); + } else { + // It's a regular file. + ImportFile ifile; + ifile.path = file; + ResourceFormatImporter::get_singleton()->get_import_order_threads_and_importer(file, ifile.order, ifile.threaded, ifile.importer); + reloads.push_back(file); + reimport_files.push_back(ifile); } - // Reimport groups. - - from = reimport_files.size(); - - if (groups_to_reimport.size()) { - HashMap> group_files; - _find_group_files(filesystem, group_files, groups_to_reimport); - for (const KeyValue> &E : group_files) { - pr.step(E.key.get_file(), from++, false); - Error err = _reimport_group(E.key, E.value); - reloads.push_back(E.key); - reloads.append_array(E.value); - if (err == OK) { - _reimport_file(E.key); - } - } + // Group may have changed, so also update group reference. + EditorFileSystemDirectory *fs = nullptr; + int cpos = -1; + if (_find_file(file, &fs, cpos)) { + fs->files.write[cpos]->import_group_file = group_file; } - - ResourceUID::get_singleton()->update_cache(); // After reimporting, update the cache. - - _save_filesystem_cache(); } - _update_pending_script_classes(true); + reimport_files.sort(); + +#ifdef THREADS_ENABLED + bool use_multiple_threads = GLOBAL_GET("editor/import/use_multiple_threads"); +#else + bool use_multiple_threads = false; +#endif + + int from = 0; + for (int i = 0; i < reimport_files.size(); i++) { + if (groups_to_reimport.has(reimport_files[i].path)) { + continue; + } + + if (use_multiple_threads && reimport_files[i].threaded) { + if (i + 1 == reimport_files.size() || reimport_files[i + 1].importer != reimport_files[from].importer) { + if (from - i == 0) { + // Single file, do not use threads. + pr.step(reimport_files[i].path.get_file(), i); + _reimport_file(reimport_files[i].path); + } else { + Ref importer = ResourceFormatImporter::get_singleton()->get_importer_by_name(reimport_files[from].importer); + ERR_CONTINUE(!importer.is_valid()); + + importer->import_threaded_begin(); + + ImportThreadData tdata; + tdata.max_index.set(from); + tdata.reimport_from = from; + tdata.reimport_files = reimport_files.ptr(); + + WorkerThreadPool::GroupID group_task = WorkerThreadPool::get_singleton()->add_template_group_task(this, &EditorFileSystem::_reimport_thread, &tdata, i - from + 1, -1, false, vformat(TTR("Import resources of type: %s"), reimport_files[from].importer)); + int current_index = from - 1; + do { + if (current_index < tdata.max_index.get()) { + current_index = tdata.max_index.get(); + pr.step(reimport_files[current_index].path.get_file(), current_index); + } + OS::get_singleton()->delay_usec(1); + } while (!WorkerThreadPool::get_singleton()->is_group_task_completed(group_task)); + + WorkerThreadPool::get_singleton()->wait_for_group_task_completion(group_task); + + importer->import_threaded_end(); + } + + from = i + 1; + } + + } else { + pr.step(reimport_files[i].path.get_file(), i); + _reimport_file(reimport_files[i].path); + } + } + + // Reimport groups. + + from = reimport_files.size(); + + if (groups_to_reimport.size()) { + HashMap> group_files; + _find_group_files(filesystem, group_files, groups_to_reimport); + for (const KeyValue> &E : group_files) { + pr.step(E.key.get_file(), from++); + Error err = _reimport_group(E.key, E.value); + reloads.push_back(E.key); + reloads.append_array(E.value); + if (err == OK) { + _reimport_file(E.key); + } + } + } + + ResourceUID::get_singleton()->update_cache(); // After reimporting, update the cache. + + _save_filesystem_cache(); + _update_pending_script_classes(); _update_pending_scene_groups(); importing = false; if (!is_scanning()) { @@ -2767,8 +2688,6 @@ void EditorFileSystem::_bind_methods() { ADD_SIGNAL(MethodInfo("sources_changed", PropertyInfo(Variant::BOOL, "exist"))); ADD_SIGNAL(MethodInfo("resources_reimported", PropertyInfo(Variant::PACKED_STRING_ARRAY, "resources"))); ADD_SIGNAL(MethodInfo("resources_reload", PropertyInfo(Variant::PACKED_STRING_ARRAY, "resources"))); - ADD_SIGNAL(MethodInfo("scan_started", PropertyInfo(Variant::BOOL, "complete_scan"))); - ADD_SIGNAL(MethodInfo("scan_stopped", PropertyInfo(Variant::BOOL, "complete_scan"))); } void EditorFileSystem::_update_extensions() { diff --git a/editor/editor_file_system.h b/editor/editor_file_system.h index ea839ec823d..cd95d5fb951 100644 --- a/editor/editor_file_system.h +++ b/editor/editor_file_system.h @@ -153,7 +153,6 @@ class EditorFileSystem : public Node { Action action = ACTION_NONE; EditorFileSystemDirectory *dir = nullptr; String file; - String import_group_file; EditorFileSystemDirectory *new_dir = nullptr; EditorFileSystemDirectory::FileInfo *new_file = nullptr; }; @@ -201,15 +200,11 @@ class EditorFileSystem : public Node { HashSet dep_update_list; struct ScanProgress { - int directories_processed = 0; - int nb_dir_to_scan = 0; - int nb_file_to_scan = 0; - float estimated = 0; - float real = 0; - float current = 0; - EditorProgressBG *progress = nullptr; - void increment(); - void update_estimated(int p_depth, int p_nb_dirs, int p_nb_files); + float low = 0; + float hi = 0; + mutable EditorProgressBG *progress = nullptr; + void update(int p_current, int p_total) const; + ScanProgress get_sub(int p_current, int p_total) const; }; void _save_filesystem_cache(); @@ -217,7 +212,7 @@ class EditorFileSystem : public Node { bool _find_file(const String &p_file, EditorFileSystemDirectory **r_d, int &r_file_pos) const; - void _scan_fs_changes(EditorFileSystemDirectory *p_dir, ScanProgress *p_progress); + void _scan_fs_changes(EditorFileSystemDirectory *p_dir, const ScanProgress &p_progress); void _delete_internal_files(const String &p_file); @@ -225,7 +220,7 @@ class EditorFileSystem : public Node { HashSet valid_extensions; HashSet import_extensions; - void _scan_new_dir(EditorFileSystemDirectory *p_dir, Ref &da, ScanProgress *p_progress, int p_depth); + void _scan_new_dir(EditorFileSystemDirectory *p_dir, Ref &da, const ScanProgress &p_progress); Thread thread_sources; bool scanning_changes = false; @@ -236,7 +231,7 @@ class EditorFileSystem : public Node { List sources_changed; List scan_actions; - bool _update_scan_actions(bool p_show_progress = false); + bool _update_scan_actions(); void _update_extensions(); @@ -262,8 +257,8 @@ class EditorFileSystem : public Node { Mutex update_script_mutex; HashSet update_script_paths; void _queue_update_script_class(const String &p_path); - void _update_script_classes(bool p_show_progress = false); - void _update_pending_script_classes(bool p_show_progress = false); + void _update_script_classes(); + void _update_pending_script_classes(); Mutex update_scene_mutex; HashSet update_scene_paths; @@ -291,7 +286,6 @@ class EditorFileSystem : public Node { SafeNumeric max_index; }; - void _reimport_files_internal(const Vector &p_files, const HashMap *p_import_group_files); void _reimport_thread(uint32_t p_index, ImportThreadData *p_import_data); static ResourceUID::ID _resource_saver_get_resource_id_for_path(const String &p_path, bool p_generate); diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index b58b3784145..94bd590fc19 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -5103,8 +5103,6 @@ void EditorNode::save_editor_layout_delayed() { } void EditorNode::_load_editor_layout() { - EditorProgress ep("loading_editor_layout", TTR("Loading editor"), 5); - ep.step("Loading editor layout...", 0, true); Ref config; config.instantiate(); Error err = config->load(EditorPaths::get_singleton()->get_project_settings_dir().path_join("editor_layout.cfg")); @@ -5126,19 +5124,11 @@ void EditorNode::_load_editor_layout() { return; } - ep.step("Loading docks...", 1, true); editor_dock_manager->load_docks_from_config(config, "docks"); - - ep.step("Reopening scenes...", 2, true); _load_open_scenes_from_config(config); - - ep.step("Loading central editor layout...", 3, true); _load_central_editor_layout_from_config(config); - ep.step("Loading plugin window layout...", 4, true); editor_data.set_plugin_window_layout(config); - - ep.step("Editor layout ready.", 5, true); } void EditorNode::_save_central_editor_layout_to_config(Ref p_config_file) { diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index 7d90da05c26..f8a82187b9d 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -550,8 +550,6 @@ void FileSystemDock::_notification(int p_what) { case NOTIFICATION_READY: { EditorFeatureProfileManager::get_singleton()->connect("current_feature_profile_changed", callable_mp(this, &FileSystemDock::_feature_profile_changed)); EditorFileSystem::get_singleton()->connect("filesystem_changed", callable_mp(this, &FileSystemDock::_fs_changed)); - EditorFileSystem::get_singleton()->connect("scan_started", callable_mp(this, &FileSystemDock::_scan_started)); - EditorFileSystem::get_singleton()->connect("scan_stopped", callable_mp(this, &FileSystemDock::_scan_stopped)); EditorResourcePreview::get_singleton()->connect("preview_invalidated", callable_mp(this, &FileSystemDock::_preview_invalidated)); button_file_list_display_mode->connect(SceneStringName(pressed), callable_mp(this, &FileSystemDock::_toggle_file_display)); @@ -568,7 +566,9 @@ void FileSystemDock::_notification(int p_what) { _update_display_mode(); - if (!EditorFileSystem::get_singleton()->is_scanning()) { + if (EditorFileSystem::get_singleton()->is_scanning()) { + _set_scanning_mode(); + } else { _update_tree(Vector(), true); } } break; @@ -1326,18 +1326,6 @@ void FileSystemDock::_fs_changed() { set_process(false); } -void FileSystemDock::_scan_started(bool p_complete_scan) { - if (p_complete_scan) { - _set_scanning_mode(); - } -} - -void FileSystemDock::_scan_stopped(bool p_complete_scan) { - if (p_complete_scan) { - _fs_changed(); - } -} - void FileSystemDock::_set_scanning_mode() { button_hist_prev->set_disabled(true); button_hist_next->set_disabled(true); @@ -2661,6 +2649,7 @@ bool FileSystemDock::_matches_all_search_tokens(const String &p_text) { } void FileSystemDock::_rescan() { + _set_scanning_mode(); EditorFileSystem::get_singleton()->scan(); } diff --git a/editor/filesystem_dock.h b/editor/filesystem_dock.h index 2e9e52fcf6e..3fbff3ef194 100644 --- a/editor/filesystem_dock.h +++ b/editor/filesystem_dock.h @@ -308,8 +308,6 @@ private: void _set_scanning_mode(); void _rescan(); - void _scan_started(bool p_complete_scan); - void _scan_stopped(bool p_complete_scan); void _change_split_mode(); void _split_dragged(int p_offset);