1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-04 12:00:25 +00:00

Implement uid Resource references in VariantWriter

VariantWriter now writes the uid and the path into Resource() references.
This change will affect ConfigFile, used for .import or project settings.
This commit is contained in:
Lyuma
2025-05-28 05:45:38 -07:00
parent 42c7f14422
commit f948ab5366
2 changed files with 65 additions and 12 deletions

View File

@@ -565,6 +565,7 @@ Ref<Resource> ResourceLoader::load(const String &p_path, const String &p_type_hi
Ref<ResourceLoader::LoadToken> ResourceLoader::_load_start(const String &p_path, const String &p_type_hint, LoadThreadMode p_thread_mode, ResourceFormatLoader::CacheMode p_cache_mode, bool p_for_user) {
String local_path = _validate_local_path(p_path);
ERR_FAIL_COND_V(local_path.is_empty(), Ref<ResourceLoader::LoadToken>());
bool ignoring_cache = p_cache_mode == ResourceFormatLoader::CACHE_MODE_IGNORE || p_cache_mode == ResourceFormatLoader::CACHE_MODE_IGNORE_DEEP;

View File

@@ -32,6 +32,7 @@
#include "core/crypto/crypto_core.h"
#include "core/io/resource_loader.h"
#include "core/io/resource_uid.h"
#include "core/object/script_language.h"
#include "core/string/string_buffer.h"
@@ -1123,13 +1124,55 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
get_token(p_stream, token, line, r_err_str);
if (token.type == TK_STRING) {
String path = token.value;
Ref<Resource> res = ResourceLoader::load(path);
String uid_string;
get_token(p_stream, token, line, r_err_str);
if (path.begins_with("uid://")) {
uid_string = path;
path = "";
}
if (token.type == TK_COMMA) {
get_token(p_stream, token, line, r_err_str);
if (token.type != TK_STRING) {
r_err_str = "Expected string in Resource reference";
return ERR_PARSE_ERROR;
}
String extra_path = token.value;
if (extra_path.begins_with("uid://")) {
if (!uid_string.is_empty()) {
r_err_str = "Two uid:// paths in one Resource reference";
return ERR_PARSE_ERROR;
}
uid_string = extra_path;
} else {
if (!path.is_empty()) {
r_err_str = "Two non-uid paths in one Resource reference";
return ERR_PARSE_ERROR;
}
path = extra_path;
}
get_token(p_stream, token, line, r_err_str);
}
Ref<Resource> res;
if (!uid_string.is_empty()) {
ResourceUID::ID uid = ResourceUID::get_singleton()->text_to_id(uid_string);
if (uid != ResourceUID::INVALID_ID && ResourceUID::get_singleton()->has_id(uid)) {
const String id_path = ResourceUID::get_singleton()->get_id_path(uid);
if (!id_path.is_empty()) {
res = ResourceLoader::load(id_path);
}
}
}
if (res.is_null() && !path.is_empty()) {
res = ResourceLoader::load(path);
}
if (res.is_null()) {
r_err_str = "Can't load resource at path: " + path;
r_err_str = "Can't load resource at path: " + path + " with uid: " + uid_string;
return ERR_PARSE_ERROR;
}
get_token(p_stream, token, line, r_err_str);
if (token.type != TK_PARENTHESIS_CLOSE) {
r_err_str = "Expected ')'";
return ERR_PARSE_ERROR;
@@ -1960,6 +2003,16 @@ static String rtos_fix(double p_value, bool p_compat) {
return String::num_scientific(p_value);
}
static String encode_resource_reference(const String &path) {
ResourceUID::ID uid = ResourceLoader::get_resource_uid(path);
if (uid != ResourceUID::INVALID_ID) {
return "Resource(\"" + ResourceUID::get_singleton()->id_to_text(uid) +
"\", \"" + path.c_escape_multiline() + "\")";
} else {
return "Resource(\"" + path.c_escape_multiline() + "\")";
}
}
Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_string_func, void *p_store_string_ud, EncodeResourceFunc p_encode_res_func, void *p_encode_res_ud, int p_recursion_count, bool p_compat) {
switch (p_variant.get_type()) {
case Variant::NIL: {
@@ -2146,22 +2199,21 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
Ref<Resource> res = p_variant;
if (res.is_valid()) {
//is resource
String res_text;
//try external function
// Try external function.
if (p_encode_res_func) {
res_text = p_encode_res_func(p_encode_res_ud, res);
}
//try path because it's a file
// Try path, because it's a file.
if (res_text.is_empty() && res->get_path().is_resource_file()) {
//external resource
// External resource.
String path = res->get_path();
res_text = "Resource(\"" + path + "\")";
res_text = encode_resource_reference(path);
}
//could come up with some sort of text
// Could come up with some sort of text.
if (!res_text.is_empty()) {
p_store_string_func(p_store_string_ud, res_text);
break;
@@ -2209,7 +2261,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
resource_text = p_encode_res_func(p_encode_res_ud, key_script);
}
if (resource_text.is_empty() && key_script->get_path().is_resource_file()) {
resource_text = "Resource(\"" + key_script->get_path() + "\")";
resource_text = encode_resource_reference(key_script->get_path());
}
if (!resource_text.is_empty()) {
@@ -2238,7 +2290,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
resource_text = p_encode_res_func(p_encode_res_ud, value_script);
}
if (resource_text.is_empty() && value_script->get_path().is_resource_file()) {
resource_text = "Resource(\"" + value_script->get_path() + "\")";
resource_text = encode_resource_reference(value_script->get_path());
}
if (!resource_text.is_empty()) {
@@ -2310,7 +2362,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
resource_text = p_encode_res_func(p_encode_res_ud, script);
}
if (resource_text.is_empty() && script->get_path().is_resource_file()) {
resource_text = "Resource(\"" + script->get_path() + "\")";
resource_text = encode_resource_reference(script->get_path());
}
if (!resource_text.is_empty()) {