Merge pull request #106902 from lyuma/config_file_uids

Implement UID references in VariantParser
This commit is contained in:
Rémi Verschelde 2025-06-09 00:44:32 +02:00
commit f759f52d8f
No known key found for this signature in database
GPG key ID: C3336907360768E1
2 changed files with 65 additions and 12 deletions

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()) {