From d57846087b225d2d8b7e8dca5db0a3874924e448 Mon Sep 17 00:00:00 2001 From: Juan Date: Mon, 23 Sep 2024 10:42:18 +0200 Subject: [PATCH] Universalize UID support in all resource types Ensures all resource types support UIDs in a project. This is required to fix: * Scripts and many other resource types can't be referenced by UID and when refactored the references are lost. * Path export properties can't use UID for unsupported types. * Refactoring problems when files are moved outside the editor (this PR effectively fixes it). * Editor properly refreshing paths if they changed externally while opened (as example, git update). This needs to be addressed in a subsequent PR, but this one effectively sets the prerequisites. Resource types that do not support UID will get a .uid file appended to them (this includes .gd, .gdshader, .gdextension, etc. files). --- core/io/resource_format_binary.cpp | 4 ++++ core/io/resource_format_binary.h | 1 + core/io/resource_importer.cpp | 4 ++++ core/io/resource_importer.h | 1 + core/io/resource_loader.cpp | 28 +++++++++++++++++++++++- core/io/resource_loader.h | 2 ++ doc/classes/ResourceFormatLoader.xml | 1 + editor/editor_file_system.cpp | 9 ++++++++ editor/filesystem_dock.cpp | 7 ++++++ scene/resources/resource_format_text.cpp | 4 ++++ scene/resources/resource_format_text.h | 1 + 11 files changed, 61 insertions(+), 1 deletion(-) diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp index e6136603d40..ed11f96d034 100644 --- a/core/io/resource_format_binary.cpp +++ b/core/io/resource_format_binary.cpp @@ -1577,6 +1577,10 @@ ResourceUID::ID ResourceFormatLoaderBinary::get_resource_uid(const String &p_pat return loader.uid; } +bool ResourceFormatLoaderBinary::has_custom_uid_support() const { + return true; +} + /////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////// diff --git a/core/io/resource_format_binary.h b/core/io/resource_format_binary.h index 222e633e589..ec8d7ead5d2 100644 --- a/core/io/resource_format_binary.h +++ b/core/io/resource_format_binary.h @@ -118,6 +118,7 @@ public: virtual String get_resource_script_class(const String &p_path) const override; virtual void get_classes_used(const String &p_path, HashSet *r_classes) override; virtual ResourceUID::ID get_resource_uid(const String &p_path) const override; + virtual bool has_custom_uid_support() const override; virtual void get_dependencies(const String &p_path, List *p_dependencies, bool p_add_types = false) override; virtual Error rename_dependencies(const String &p_path, const HashMap &p_map) override; }; diff --git a/core/io/resource_importer.cpp b/core/io/resource_importer.cpp index e603f9dfde7..b7a14f2b880 100644 --- a/core/io/resource_importer.cpp +++ b/core/io/resource_importer.cpp @@ -387,6 +387,10 @@ ResourceUID::ID ResourceFormatImporter::get_resource_uid(const String &p_path) c return pat.uid; } +bool ResourceFormatImporter::has_custom_uid_support() const { + return true; +} + 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); diff --git a/core/io/resource_importer.h b/core/io/resource_importer.h index 3ca8f7c05d0..6655f4a5474 100644 --- a/core/io/resource_importer.h +++ b/core/io/resource_importer.h @@ -70,6 +70,7 @@ public: virtual bool handles_type(const String &p_type) const override; virtual String get_resource_type(const String &p_path) const override; virtual ResourceUID::ID get_resource_uid(const String &p_path) const override; + virtual bool has_custom_uid_support() const override; virtual Variant get_resource_metadata(const String &p_path) const; virtual bool is_import_valid(const String &p_path) const override; virtual void get_dependencies(const String &p_path, List *p_dependencies, bool p_add_types = false) override; diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp index 59de2879e23..4b54130021c 100644 --- a/core/io/resource_loader.cpp +++ b/core/io/resource_loader.cpp @@ -112,10 +112,21 @@ String ResourceFormatLoader::get_resource_script_class(const String &p_path) con ResourceUID::ID ResourceFormatLoader::get_resource_uid(const String &p_path) const { int64_t uid = ResourceUID::INVALID_ID; - GDVIRTUAL_CALL(_get_resource_uid, p_path, uid); + if (has_custom_uid_support()) { + GDVIRTUAL_CALL(_get_resource_uid, p_path, uid); + } else { + Ref file = FileAccess::open(p_path + ".uid", FileAccess::READ); + if (file.is_valid()) { + uid = ResourceUID::get_singleton()->text_to_id(file->get_line()); + } + } return uid; } +bool ResourceFormatLoader::has_custom_uid_support() const { + return GDVIRTUAL_IS_OVERRIDDEN(_get_resource_uid); +} + void ResourceFormatLoader::get_recognized_extensions_for_type(const String &p_type, List *p_extensions) const { if (p_type.is_empty() || handles_type(p_type)) { get_recognized_extensions(p_extensions); @@ -1159,6 +1170,21 @@ ResourceUID::ID ResourceLoader::get_resource_uid(const String &p_path) { return ResourceUID::INVALID_ID; } +bool ResourceLoader::has_custom_uid_support(const String &p_path) { + String local_path = _validate_local_path(p_path); + + for (int i = 0; i < loader_count; i++) { + if (!loader[i]->recognize_path(local_path)) { + continue; + } + if (loader[i]->has_custom_uid_support()) { + return true; + } + } + + return false; +} + String ResourceLoader::_path_remap(const String &p_path, bool *r_translation_remapped) { String new_path = p_path; diff --git a/core/io/resource_loader.h b/core/io/resource_loader.h index 0d802ed1f4f..1987312d462 100644 --- a/core/io/resource_loader.h +++ b/core/io/resource_loader.h @@ -81,6 +81,7 @@ public: virtual String get_resource_type(const String &p_path) const; virtual String get_resource_script_class(const String &p_path) const; virtual ResourceUID::ID get_resource_uid(const String &p_path) const; + virtual bool has_custom_uid_support() const; virtual void get_dependencies(const String &p_path, List *p_dependencies, bool p_add_types = false); virtual Error rename_dependencies(const String &p_path, const HashMap &p_map); virtual bool is_import_valid(const String &p_path) const { return true; } @@ -238,6 +239,7 @@ public: static String get_resource_type(const String &p_path); static String get_resource_script_class(const String &p_path); static ResourceUID::ID get_resource_uid(const String &p_path); + static bool has_custom_uid_support(const String &p_path); static void get_dependencies(const String &p_path, List *p_dependencies, bool p_add_types = false); static Error rename_dependencies(const String &p_path, const HashMap &p_map); static bool is_import_valid(const String &p_path); diff --git a/doc/classes/ResourceFormatLoader.xml b/doc/classes/ResourceFormatLoader.xml index 4e4adc86c41..cdbf8b3f9a5 100644 --- a/doc/classes/ResourceFormatLoader.xml +++ b/doc/classes/ResourceFormatLoader.xml @@ -57,6 +57,7 @@ + Should return the unique ID for the resource associated with the given path. If this method is not overridden, a [code].uid[/code] file is generated along with the resource file, containing the unique ID. diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp index 558eed98c63..0c284feb37a 100644 --- a/editor/editor_file_system.cpp +++ b/editor/editor_file_system.cpp @@ -1259,6 +1259,15 @@ void EditorFileSystem::_process_file_system(const ScannedDirectory *p_scan_dir, } } } + + if (fi->uid == ResourceUID::INVALID_ID && ResourceLoader::exists(path) && !ResourceLoader::has_custom_uid_support(path) && !FileAccess::exists(path + ".uid")) { + // Create a UID. + Ref f = FileAccess::open(path + ".uid", FileAccess::WRITE); + if (f.is_valid()) { + fi->uid = ResourceUID::get_singleton()->create_id(); + f->store_line(ResourceUID::get_singleton()->id_to_text(fi->uid)); + } + } } if (fi->uid != ResourceUID::INVALID_ID) { diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index 9b08d21bdc4..210249ebc99 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -1446,6 +1446,13 @@ void FileSystemDock::_try_move_item(const FileOrFolder &p_item, const String &p_ } } + if (p_item.is_file && FileAccess::exists(old_path + ".uid")) { + err = da->rename(old_path + ".uid", new_path + ".uid"); + if (err != OK) { + EditorNode::get_singleton()->add_io_error(TTR("Error moving:") + "\n" + old_path + ".uid\n"); + } + } + // Update scene if it is open. for (int i = 0; i < file_changed_paths.size(); ++i) { String new_item_path = p_item.is_file ? new_path : file_changed_paths[i].replace_first(old_path, new_path); diff --git a/scene/resources/resource_format_text.cpp b/scene/resources/resource_format_text.cpp index 535903a1b68..6e03fe25c9d 100644 --- a/scene/resources/resource_format_text.cpp +++ b/scene/resources/resource_format_text.cpp @@ -1526,6 +1526,10 @@ ResourceUID::ID ResourceFormatLoaderText::get_resource_uid(const String &p_path) return loader.get_uid(f); } +bool ResourceFormatLoaderText::has_custom_uid_support() const { + return true; +} + void ResourceFormatLoaderText::get_dependencies(const String &p_path, List *p_dependencies, bool p_add_types) { Ref f = FileAccess::open(p_path, FileAccess::READ); if (f.is_null()) { diff --git a/scene/resources/resource_format_text.h b/scene/resources/resource_format_text.h index 8397bc985fc..4c0bf3d9170 100644 --- a/scene/resources/resource_format_text.h +++ b/scene/resources/resource_format_text.h @@ -155,6 +155,7 @@ public: virtual String get_resource_type(const String &p_path) const override; virtual String get_resource_script_class(const String &p_path) const override; virtual ResourceUID::ID get_resource_uid(const String &p_path) const override; + virtual bool has_custom_uid_support() const override; virtual void get_dependencies(const String &p_path, List *p_dependencies, bool p_add_types = false) override; virtual Error rename_dependencies(const String &p_path, const HashMap &p_map) override;