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 Sep 23, 2024
1 parent 155fcd0 commit 24df9eb
Show file tree
Hide file tree
Showing 10 changed files with 64 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
31 changes: 30 additions & 1 deletion core/io/resource_loader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,10 +112,23 @@ 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 = file->get_line().to_int();
}
}
}
return uid;
}

bool ResourceFormatLoader::has_custom_uid_support() const {
bool custom = false;
GDVIRTUAL_CALL(_has_custom_uid_support, custom);
return custom;
}

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 @@ -199,6 +212,7 @@ void ResourceFormatLoader::_bind_methods() {
GDVIRTUAL_BIND(_get_resource_type, "path");
GDVIRTUAL_BIND(_get_resource_script_class, "path");
GDVIRTUAL_BIND(_get_resource_uid, "path");
GDVIRTUAL_BIND(_has_custom_uid_support);
GDVIRTUAL_BIND(_get_dependencies, "path", "add_types");
GDVIRTUAL_BIND(_rename_dependencies, "path", "renames");
GDVIRTUAL_BIND(_exists, "path");
Expand Down Expand Up @@ -1150,6 +1164,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
3 changes: 3 additions & 0 deletions core/io/resource_loader.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ class ResourceFormatLoader : public RefCounted {
GDVIRTUAL1RC(String, _get_resource_type, String)
GDVIRTUAL1RC(String, _get_resource_script_class, String)
GDVIRTUAL1RC(ResourceUID::ID, _get_resource_uid, String)
GDVIRTUAL0RC(bool, _has_custom_uid_support)
GDVIRTUAL2RC(Vector<String>, _get_dependencies, String, bool)
GDVIRTUAL1RC(Vector<String>, _get_classes_used, String)
GDVIRTUAL2RC(Error, _rename_dependencies, String, Dictionary)
Expand All @@ -81,6 +82,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 +240,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
7 changes: 7 additions & 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>
If [method _has_custom_uid_support] is implemented, this method must provide the unique ID for the resource.
</description>
</method>
<method name="_handles_type" qualifiers="virtual const">
Expand All @@ -67,6 +68,12 @@
[b]Note:[/b] Custom resource types defined by scripts aren't known by the [ClassDB], so you might just handle [code]"Resource"[/code] for them.
</description>
</method>
<method name="_has_custom_uid_support" qualifiers="virtual const">
<return type="bool" />
<description>
Set the resource to provide a custom UID source (otherwise the .uid file will be appended). Used together with [method _get_resource_uid].
</description>
</method>
<method name="_load" qualifiers="virtual const">
<return type="Variant" />
<param index="0" name="path" type="String" />
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)) {
// 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(itos(fi->uid));
}
}
}

if (fi->uid != 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 24df9eb

Please sign in to comment.