summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/io/resource_format_binary.cpp68
-rw-r--r--core/io/resource_loader.cpp36
-rw-r--r--core/io/resource_loader.h4
3 files changed, 79 insertions, 29 deletions
diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp
index ab460c5f4c..f71257fa76 100644
--- a/core/io/resource_format_binary.cpp
+++ b/core/io/resource_format_binary.cpp
@@ -749,44 +749,54 @@ Error ResourceLoaderBinary::load() {
String t = get_unicode_string();
Ref<Resource> res;
+ Resource *r = nullptr;
- if (cache_mode == ResourceFormatLoader::CACHE_MODE_REPLACE && ResourceCache::has(path)) {
- //use the existing one
- Ref<Resource> cached = ResourceCache::get_ref(path);
- if (cached->get_class() == t) {
- cached->reset_state();
- res = cached;
- }
+ MissingResource *missing_resource = nullptr;
+
+ if (main) {
+ res = ResourceLoader::get_resource_ref_override(local_path);
+ r = res.ptr();
}
+ if (!r) {
+ if (cache_mode == ResourceFormatLoader::CACHE_MODE_REPLACE && ResourceCache::has(path)) {
+ //use the existing one
+ Ref<Resource> cached = ResourceCache::get_ref(path);
+ if (cached->get_class() == t) {
+ cached->reset_state();
+ res = cached;
+ }
+ }
- MissingResource *missing_resource = nullptr;
+ if (res.is_null()) {
+ //did not replace
+
+ Object *obj = ClassDB::instantiate(t);
+ if (!obj) {
+ if (ResourceLoader::is_creating_missing_resources_if_class_unavailable_enabled()) {
+ //create a missing resource
+ missing_resource = memnew(MissingResource);
+ missing_resource->set_original_class(t);
+ missing_resource->set_recording_properties(true);
+ obj = missing_resource;
+ } else {
+ error = ERR_FILE_CORRUPT;
+ ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, local_path + ":Resource of unrecognized type in file: " + t + ".");
+ }
+ }
- if (res.is_null()) {
- //did not replace
-
- Object *obj = ClassDB::instantiate(t);
- if (!obj) {
- if (ResourceLoader::is_creating_missing_resources_if_class_unavailable_enabled()) {
- //create a missing resource
- missing_resource = memnew(MissingResource);
- missing_resource->set_original_class(t);
- missing_resource->set_recording_properties(true);
- obj = missing_resource;
- } else {
+ r = Object::cast_to<Resource>(obj);
+ if (!r) {
+ String obj_class = obj->get_class();
error = ERR_FILE_CORRUPT;
- ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, local_path + ":Resource of unrecognized type in file: " + t + ".");
+ memdelete(obj); //bye
+ ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, local_path + ":Resource type in resource field not a resource, type is: " + obj_class + ".");
}
- }
- Resource *r = Object::cast_to<Resource>(obj);
- if (!r) {
- String obj_class = obj->get_class();
- error = ERR_FILE_CORRUPT;
- memdelete(obj); //bye
- ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, local_path + ":Resource type in resource field not a resource, type is: " + obj_class + ".");
+ res = Ref<Resource>(r);
}
+ }
- res = Ref<Resource>(r);
+ if (r) {
if (!path.is_empty()) {
if (cache_mode != ResourceFormatLoader::CACHE_MODE_IGNORE) {
r->set_path(path, cache_mode == ResourceFormatLoader::CACHE_MODE_REPLACE); // If got here because the resource with same path has different type, replace it.
diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp
index eb3b117297..ed5e482296 100644
--- a/core/io/resource_loader.cpp
+++ b/core/io/resource_loader.cpp
@@ -272,6 +272,7 @@ Ref<Resource> ResourceLoader::_load(const String &p_path, const String &p_origin
}
load_paths_stack->resize(load_paths_stack->size() - 1);
+ res_ref_overrides.erase(load_nesting);
load_nesting--;
if (!res.is_null()) {
@@ -730,6 +731,40 @@ Ref<Resource> ResourceLoader::_load_complete_inner(LoadToken &p_load_token, Erro
}
}
+Ref<Resource> ResourceLoader::ensure_resource_ref_override_for_outer_load(const String &p_path, const String &p_res_type) {
+ ERR_FAIL_COND_V(load_nesting == 0, Ref<Resource>()); // It makes no sense to use this from nesting level 0.
+ const String &local_path = _validate_local_path(p_path);
+ HashMap<String, Ref<Resource>> &overrides = res_ref_overrides[load_nesting - 1];
+ HashMap<String, Ref<Resource>>::Iterator E = overrides.find(local_path);
+ if (E) {
+ return E->value;
+ } else {
+ Object *obj = ClassDB::instantiate(p_res_type);
+ ERR_FAIL_NULL_V(obj, Ref<Resource>());
+ Ref<Resource> res(obj);
+ if (!res.is_valid()) {
+ memdelete(obj);
+ ERR_FAIL_V(Ref<Resource>());
+ }
+ overrides[local_path] = res;
+ return res;
+ }
+}
+
+Ref<Resource> ResourceLoader::get_resource_ref_override(const String &p_path) {
+ DEV_ASSERT(p_path == _validate_local_path(p_path));
+ HashMap<int, HashMap<String, Ref<Resource>>>::Iterator E = res_ref_overrides.find(load_nesting);
+ if (!E) {
+ return nullptr;
+ }
+ HashMap<String, Ref<Resource>>::Iterator F = E->value.find(p_path);
+ if (!F) {
+ return nullptr;
+ }
+
+ return F->value;
+}
+
bool ResourceLoader::exists(const String &p_path, const String &p_type_hint) {
String local_path = _validate_local_path(p_path);
@@ -1222,6 +1257,7 @@ bool ResourceLoader::timestamp_on_load = false;
thread_local int ResourceLoader::load_nesting = 0;
thread_local WorkerThreadPool::TaskID ResourceLoader::caller_task_id = 0;
thread_local Vector<String> *ResourceLoader::load_paths_stack;
+thread_local HashMap<int, HashMap<String, Ref<Resource>>> ResourceLoader::res_ref_overrides;
template <>
thread_local uint32_t SafeBinaryMutex<ResourceLoader::BINARY_MUTEX_TAG>::count = 0;
diff --git a/core/io/resource_loader.h b/core/io/resource_loader.h
index 11abb4dc18..c48f39b5cc 100644
--- a/core/io/resource_loader.h
+++ b/core/io/resource_loader.h
@@ -187,6 +187,7 @@ private:
static thread_local int load_nesting;
static thread_local WorkerThreadPool::TaskID caller_task_id;
+ static thread_local HashMap<int, HashMap<String, Ref<Resource>>> res_ref_overrides; // Outermost key is nesting level.
static thread_local Vector<String> *load_paths_stack; // A pointer to avoid broken TLS implementations from double-running the destructor.
static SafeBinaryMutex<BINARY_MUTEX_TAG> thread_load_mutex;
static HashMap<String, ThreadLoadTask> thread_load_tasks;
@@ -272,6 +273,9 @@ public:
static void set_create_missing_resources_if_class_unavailable(bool p_enable);
_FORCE_INLINE_ static bool is_creating_missing_resources_if_class_unavailable_enabled() { return create_missing_resources_if_class_unavailable; }
+ static Ref<Resource> ensure_resource_ref_override_for_outer_load(const String &p_path, const String &p_res_type);
+ static Ref<Resource> get_resource_ref_override(const String &p_path);
+
static bool is_cleaning_tasks();
static void initialize();