Skip to content

Commit

Permalink
Universalize UID support in all resource types
Browse files Browse the repository at this point in the history
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 refresh 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).

FAQ:

**Why not using metafiles instead to make it more generic?**

1. There has no need for metafiles. Most resource types contain metadata on their own.
2. The .uid files are only used by the editor and are effectively gone on export, as this information is moved to the uid database. As such they are unsuitable as metafiles.
  • Loading branch information
reduz committed Oct 7, 2024
1 parent 155fcd0 commit 6ec0a79
Show file tree
Hide file tree
Showing 11 changed files with 75 additions and 1 deletion.
4 changes: 4 additions & 0 deletions core/io/resource_format_binary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1574,6 +1574,10 @@ ResourceUID::ID ResourceFormatLoaderBinary::get_resource_uid(const String &p_pat
return loader.uid;
}

bool ResourceFormatLoaderBinary::has_custom_uid_support() const {
return true;
}

///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
Expand Down
1 change: 1 addition & 0 deletions core/io/resource_format_binary.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ class ResourceFormatLoaderBinary : public ResourceFormatLoader {
virtual String get_resource_script_class(const String &p_path) const override;
virtual void get_classes_used(const String &p_path, HashSet<StringName> *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<String> *p_dependencies, bool p_add_types = false) override;
virtual Error rename_dependencies(const String &p_path, const HashMap<String, String> &p_map) override;
};
Expand Down
4 changes: 4 additions & 0 deletions core/io/resource_importer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions core/io/resource_importer.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ class ResourceFormatImporter : public ResourceFormatLoader {
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<String> *p_dependencies, bool p_add_types = false) override;
Expand Down
28 changes: 27 additions & 1 deletion core/io/resource_loader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 (!GDVIRTUAL_CALL(_get_resource_uid, p_path, uid)) {
if (!has_custom_uid_support()) {
Ref<FileAccess> 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<String> *p_extensions) const {
if (p_type.is_empty() || handles_type(p_type)) {
get_recognized_extensions(p_extensions);
Expand Down Expand Up @@ -1150,6 +1161,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;

Expand Down
2 changes: 2 additions & 0 deletions core/io/resource_loader.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ class ResourceFormatLoader : public RefCounted {
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<String> *p_dependencies, bool p_add_types = false);
virtual Error rename_dependencies(const String &p_path, const HashMap<String, String> &p_map);
virtual bool is_import_valid(const String &p_path) const { return true; }
Expand Down Expand Up @@ -238,6 +239,7 @@ class ResourceLoader {
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<String> *p_dependencies, bool p_add_types = false);
static Error rename_dependencies(const String &p_path, const HashMap<String, String> &p_map);
static bool is_import_valid(const String &p_path);
Expand Down
1 change: 1 addition & 0 deletions doc/classes/ResourceFormatLoader.xml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
<return type="int" />
<param index="0" name="path" type="String" />
<description>
Implement for resource loaders that provide UIDs in a customized way. Leave alone for ".uid" files to be generated along the resource file.
</description>
</method>
<method name="_handles_type" qualifiers="virtual const">
Expand Down
9 changes: 9 additions & 0 deletions editor/editor_file_system.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1138,6 +1138,15 @@ void EditorFileSystem::_process_file_system(const ScannedDirectory *p_scan_dir,
}
}
}

if (fi->uid == ResourceUID::INVALID_ID && !ResourceLoader::has_custom_uid_support(path) && ResourceLoader::exists(path) && !FileAccess::exists(path + ".uid")) {
// Create a UID
Ref<FileAccess> 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) {
Expand Down
21 changes: 21 additions & 0 deletions editor/filesystem_dock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1485,6 +1485,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);
Expand Down Expand Up @@ -1555,6 +1562,20 @@ void FileSystemDock::_try_duplicate_item(const FileOrFolder &p_item, const Strin
EditorNode::get_singleton()->add_io_error(TTR("Error duplicating:") + "\n" + old_path + ".import: " + error_names[err] + "\n");
return;
}
} else if (FileAccess::exists(old_path + ".uid")) { // uses UID
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;
}

// Create new UID
Ref<FileAccess> f = FileAccess::open(new_path + ".uid", FileAccess::WRITE);
if (f.is_valid()) {
ResourceUID::ID id = ResourceUID::get_singleton()->create_id();
f->store_line(ResourceUID::get_singleton()->id_to_text(id));
}

} else {
// Files which do not use an uid can just be copied.
if (ResourceLoader::get_resource_uid(old_path) == ResourceUID::INVALID_ID) {
Expand Down
4 changes: 4 additions & 0 deletions scene/resources/resource_format_text.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1529,6 +1529,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<String> *p_dependencies, bool p_add_types) {
Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::READ);
if (f.is_null()) {
Expand Down
1 change: 1 addition & 0 deletions scene/resources/resource_format_text.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ class ResourceFormatLoaderText : public ResourceFormatLoader {
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<String> *p_dependencies, bool p_add_types = false) override;
virtual Error rename_dependencies(const String &p_path, const HashMap<String, String> &p_map) override;

Expand Down

0 comments on commit 6ec0a79

Please sign in to comment.