mirror of
https://github.com/godotengine/godot.git
synced 2024-09-20 06:22:24 +00:00
Don't rescan filesystem when duplicating
This commit is contained in:
parent
0a4aedb360
commit
1154a2c155
|
@ -2773,6 +2773,34 @@ void EditorFileSystem::reimport_file_with_custom_parameters(const String &p_file
|
|||
emit_signal(SNAME("resources_reimported"), reloads);
|
||||
}
|
||||
|
||||
void EditorFileSystem::_queue_refresh_filesystem() {
|
||||
if (refresh_queued) {
|
||||
return;
|
||||
}
|
||||
refresh_queued = true;
|
||||
get_tree()->connect(SNAME("process_frame"), callable_mp(this, &EditorFileSystem::_refresh_filesystem), CONNECT_ONE_SHOT);
|
||||
}
|
||||
|
||||
void EditorFileSystem::_refresh_filesystem() {
|
||||
for (EditorFileSystemDirectory *dir : folders_to_refresh) {
|
||||
dir->subdirs.sort_custom<DirectoryComparator>();
|
||||
}
|
||||
folders_to_refresh.clear();
|
||||
|
||||
if (!files_to_refresh.is_empty()) {
|
||||
update_files(files_to_refresh);
|
||||
files_to_refresh.clear();
|
||||
}
|
||||
|
||||
if (!reimport_files_to_refresh.is_empty()) {
|
||||
reimport_files(reimport_files_to_refresh);
|
||||
reimport_files_to_refresh.clear();
|
||||
}
|
||||
|
||||
emit_signal(SNAME("filesystem_changed"));
|
||||
refresh_queued = false;
|
||||
}
|
||||
|
||||
void EditorFileSystem::_reimport_thread(uint32_t p_index, ImportThreadData *p_import_data) {
|
||||
int current_max = p_import_data->reimport_from + int(p_index);
|
||||
p_import_data->max_index.exchange_if_greater(current_max);
|
||||
|
@ -3096,10 +3124,9 @@ Error EditorFileSystem::make_dir_recursive(const String &p_path, const String &p
|
|||
const String path = da->get_current_dir();
|
||||
EditorFileSystemDirectory *parent = get_filesystem_path(path);
|
||||
ERR_FAIL_NULL_V(parent, ERR_FILE_NOT_FOUND);
|
||||
folders_to_refresh.insert(parent);
|
||||
|
||||
const PackedStringArray folders = p_path.trim_prefix(path).trim_suffix("/").split("/");
|
||||
bool first = true;
|
||||
|
||||
for (const String &folder : folders) {
|
||||
const int current = parent->find_dir_index(folder);
|
||||
if (current > -1) {
|
||||
|
@ -3111,18 +3138,92 @@ Error EditorFileSystem::make_dir_recursive(const String &p_path, const String &p
|
|||
efd->parent = parent;
|
||||
efd->name = folder;
|
||||
parent->subdirs.push_back(efd);
|
||||
|
||||
if (first) {
|
||||
parent->subdirs.sort_custom<DirectoryComparator>();
|
||||
first = false;
|
||||
}
|
||||
parent = efd;
|
||||
}
|
||||
|
||||
emit_signal(SNAME("filesystem_changed"));
|
||||
_queue_refresh_filesystem();
|
||||
return OK;
|
||||
}
|
||||
|
||||
Error EditorFileSystem::copy_file(const String &p_from, const String &p_to) {
|
||||
Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_RESOURCES);
|
||||
if (FileAccess::exists(p_from + ".import")) {
|
||||
Error err = da->copy(p_from, p_to);
|
||||
if (err != OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// Remove uid from .import file to avoid conflict.
|
||||
Ref<ConfigFile> cfg;
|
||||
cfg.instantiate();
|
||||
cfg->load(p_from + ".import");
|
||||
cfg->erase_section_key("remap", "uid");
|
||||
err = cfg->save(p_to + ".import");
|
||||
if (err != OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
reimport_files_to_refresh.append(p_to);
|
||||
} else if (ResourceLoader::get_resource_uid(p_from) == ResourceUID::INVALID_ID) {
|
||||
// Files which do not use an uid can just be copied.
|
||||
Error err = da->copy(p_from, p_to);
|
||||
if (err != OK) {
|
||||
return err;
|
||||
}
|
||||
} else {
|
||||
// Load the resource and save it again in the new location (this generates a new UID).
|
||||
Error err;
|
||||
Ref<Resource> res = ResourceLoader::load(p_from, "", ResourceFormatLoader::CACHE_MODE_REUSE, &err);
|
||||
if (err == OK && res.is_valid()) {
|
||||
err = ResourceSaver::save(res, p_to, ResourceSaver::FLAG_COMPRESS);
|
||||
if (err != OK) {
|
||||
return err;
|
||||
}
|
||||
} else if (err != OK) {
|
||||
// When loading files like text files the error is OK but the resource is still null.
|
||||
// We can ignore such files.
|
||||
return err;
|
||||
}
|
||||
}
|
||||
files_to_refresh.append(p_to);
|
||||
|
||||
EditorFileSystemDirectory *parent = get_filesystem_path(p_to.get_base_dir());
|
||||
ERR_FAIL_NULL_V(parent, ERR_FILE_NOT_FOUND);
|
||||
folders_to_refresh.insert(parent);
|
||||
|
||||
EditorFileSystemDirectory::FileInfo *fi = memnew(EditorFileSystemDirectory::FileInfo);
|
||||
fi->file = p_to.get_file();
|
||||
parent->files.push_back(fi);
|
||||
|
||||
_queue_refresh_filesystem();
|
||||
return OK;
|
||||
}
|
||||
|
||||
void EditorFileSystem::copy_directory(const String &p_from, const String &p_to) {
|
||||
if (make_dir_recursive(p_to) != OK) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Recursively duplicate all files inside the folder.
|
||||
Ref<DirAccess> old_dir = DirAccess::open(p_from);
|
||||
ERR_FAIL_COND(old_dir.is_null());
|
||||
|
||||
Ref<FileAccess> file_access = FileAccess::create(FileAccess::ACCESS_RESOURCES);
|
||||
old_dir->set_include_navigational(false);
|
||||
old_dir->list_dir_begin();
|
||||
for (String f = old_dir->_get_next(); !f.is_empty(); f = old_dir->_get_next()) {
|
||||
if (f.get_extension() == "import") {
|
||||
continue;
|
||||
}
|
||||
if (old_dir->current_is_dir()) {
|
||||
copy_directory(p_from.path_join(f), p_to.path_join(f));
|
||||
} else {
|
||||
copy_file(p_from.path_join(f), p_to.path_join(f));
|
||||
}
|
||||
}
|
||||
_queue_refresh_filesystem();
|
||||
}
|
||||
|
||||
ResourceUID::ID EditorFileSystem::_resource_saver_get_resource_id_for_path(const String &p_path, bool p_generate) {
|
||||
if (!p_path.is_resource_file() || p_path.begins_with(ProjectSettings::get_singleton()->get_project_data_path())) {
|
||||
// Saved externally (configuration file) or internal file, do not assign an ID.
|
||||
|
|
|
@ -317,6 +317,14 @@ class EditorFileSystem : public Node {
|
|||
HashSet<String> group_file_cache;
|
||||
HashMap<String, String> file_icon_cache;
|
||||
|
||||
bool refresh_queued = false;
|
||||
HashSet<EditorFileSystemDirectory *> folders_to_refresh;
|
||||
PackedStringArray files_to_refresh;
|
||||
PackedStringArray reimport_files_to_refresh;
|
||||
|
||||
void _queue_refresh_filesystem();
|
||||
void _refresh_filesystem();
|
||||
|
||||
struct ImportThreadData {
|
||||
const ImportFile *reimport_files;
|
||||
int reimport_from;
|
||||
|
@ -371,6 +379,8 @@ public:
|
|||
void move_group_file(const String &p_path, const String &p_new_path);
|
||||
|
||||
Error make_dir_recursive(const String &p_path, const String &p_base_path = String());
|
||||
Error copy_file(const String &p_from, const String &p_to);
|
||||
void copy_directory(const String &p_from, const String &p_to);
|
||||
|
||||
static bool _should_skip_directory(const String &p_path);
|
||||
|
||||
|
|
|
@ -1530,76 +1530,19 @@ void FileSystemDock::_try_duplicate_item(const FileOrFolder &p_item, const Strin
|
|||
EditorNode::get_singleton()->add_io_error(TTR("Cannot move a folder into itself.") + "\n" + old_path + "\n");
|
||||
return;
|
||||
}
|
||||
Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_RESOURCES);
|
||||
|
||||
if (p_item.is_file) {
|
||||
print_verbose("Duplicating " + old_path + " -> " + new_path);
|
||||
|
||||
// Create the directory structure.
|
||||
da->make_dir_recursive(new_path.get_base_dir());
|
||||
EditorFileSystem::get_singleton()->make_dir_recursive(p_new_path.get_base_dir());
|
||||
|
||||
if (FileAccess::exists(old_path + ".import")) {
|
||||
Error err = da->copy(old_path, new_path);
|
||||
if (err != OK) {
|
||||
EditorNode::get_singleton()->add_io_error(TTR("Error duplicating:") + "\n" + old_path + ": " + error_names[err] + "\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove uid from .import file to avoid conflict.
|
||||
Ref<ConfigFile> cfg;
|
||||
cfg.instantiate();
|
||||
cfg->load(old_path + ".import");
|
||||
cfg->erase_section_key("remap", "uid");
|
||||
err = cfg->save(new_path + ".import");
|
||||
if (err != OK) {
|
||||
EditorNode::get_singleton()->add_io_error(TTR("Error duplicating:") + "\n" + old_path + ".import: " + error_names[err] + "\n");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// Files which do not use an uid can just be copied.
|
||||
if (ResourceLoader::get_resource_uid(old_path) == ResourceUID::INVALID_ID) {
|
||||
Error err = da->copy(old_path, new_path);
|
||||
if (err != OK) {
|
||||
EditorNode::get_singleton()->add_io_error(TTR("Error duplicating:") + "\n" + old_path + ": " + error_names[err] + "\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Load the resource and save it again in the new location (this generates a new UID).
|
||||
Error err;
|
||||
Ref<Resource> res = ResourceLoader::load(old_path, "", ResourceFormatLoader::CACHE_MODE_REUSE, &err);
|
||||
if (err == OK && res.is_valid()) {
|
||||
err = ResourceSaver::save(res, new_path, ResourceSaver::FLAG_COMPRESS);
|
||||
if (err != OK) {
|
||||
EditorNode::get_singleton()->add_io_error(TTR("Error duplicating:") + " " + vformat(TTR("Failed to save resource at %s: %s"), new_path, error_names[err]));
|
||||
}
|
||||
} else if (err != OK) {
|
||||
// When loading files like text files the error is OK but the resource is still null.
|
||||
// We can ignore such files.
|
||||
EditorNode::get_singleton()->add_io_error(TTR("Error duplicating:") + " " + vformat(TTR("Failed to load resource at %s: %s"), new_path, error_names[err]));
|
||||
}
|
||||
Error err = EditorFileSystem::get_singleton()->copy_file(old_path, new_path);
|
||||
if (err != OK) {
|
||||
EditorNode::get_singleton()->add_io_error(TTR("Error duplicating:") + "\n" + old_path + ": " + error_names[err] + "\n");
|
||||
}
|
||||
} else {
|
||||
da->make_dir(new_path);
|
||||
|
||||
// Recursively duplicate all files inside the folder.
|
||||
Ref<DirAccess> old_dir = DirAccess::open(old_path);
|
||||
ERR_FAIL_COND(old_dir.is_null());
|
||||
|
||||
Ref<FileAccess> file_access = FileAccess::create(FileAccess::ACCESS_RESOURCES);
|
||||
old_dir->set_include_navigational(false);
|
||||
old_dir->list_dir_begin();
|
||||
for (String f = old_dir->_get_next(); !f.is_empty(); f = old_dir->_get_next()) {
|
||||
if (f.get_extension() == "import") {
|
||||
continue;
|
||||
}
|
||||
if (file_access->file_exists(old_path + f)) {
|
||||
_try_duplicate_item(FileOrFolder(old_path + f, true), new_path + f);
|
||||
} else if (da->dir_exists(old_path + f)) {
|
||||
_try_duplicate_item(FileOrFolder(old_path + f, false), new_path + f);
|
||||
}
|
||||
}
|
||||
old_dir->list_dir_end();
|
||||
EditorFileSystem::get_singleton()->copy_directory(old_path, new_path);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1933,10 +1876,6 @@ void FileSystemDock::_duplicate_operation_confirm() {
|
|||
}
|
||||
|
||||
_try_duplicate_item(to_duplicate, new_path);
|
||||
|
||||
// Rescan everything.
|
||||
print_verbose("FileSystem: calling rescan.");
|
||||
_rescan();
|
||||
}
|
||||
|
||||
void FileSystemDock::_overwrite_dialog_action(bool p_overwrite) {
|
||||
|
|
Loading…
Reference in New Issue
Block a user