summaryrefslogtreecommitdiffstats
path: root/core/io/resource_loader.cpp
diff options
context:
space:
mode:
authorPedro J. Estébanez <pedrojrulez@gmail.com>2024-06-25 14:12:40 +0200
committerPedro J. Estébanez <pedrojrulez@gmail.com>2024-06-26 17:44:32 +0200
commitc1391489e390c84b68ae66ecccf7a566cba87781 (patch)
treee80c8483d91deec352a6a48ab558b156a97a14b1 /core/io/resource_loader.cpp
parent6b281c0c07b07f2142b1fc8a6b3158091a9b124c (diff)
downloadredot-engine-c1391489e390c84b68ae66ecccf7a566cba87781.tar.gz
GDScript: Enhance handling of cyclic dependencies
Diffstat (limited to 'core/io/resource_loader.cpp')
-rw-r--r--core/io/resource_loader.cpp36
1 files changed, 36 insertions, 0 deletions
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;