diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp index 4ebd297ab9..ea7382cfbf 100644 --- a/core/io/resource_loader.cpp +++ b/core/io/resource_loader.cpp @@ -565,6 +565,7 @@ Ref ResourceLoader::load(const String &p_path, const String &p_type_hi Ref 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()); bool ignoring_cache = p_cache_mode == ResourceFormatLoader::CACHE_MODE_IGNORE || p_cache_mode == ResourceFormatLoader::CACHE_MODE_IGNORE_DEEP; diff --git a/core/variant/variant_parser.cpp b/core/variant/variant_parser.cpp index ea24eeae0e..58098585bb 100644 --- a/core/variant/variant_parser.cpp +++ b/core/variant/variant_parser.cpp @@ -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 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 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 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()) {