Do not attempt deleting local cache in Resource::_teardown_duplicate_from_variant.

This commit is contained in:
Pāvels Nadtočajevs 2025-11-26 09:59:07 +02:00
parent 9f5309a2a4
commit e815a8f899
No known key found for this signature in database
GPG key ID: 8413210218EF35D2
2 changed files with 12 additions and 2 deletions

View file

@ -368,11 +368,14 @@ Ref<Resource> Resource::_duplicate(const DuplicateParams &p_params) const {
ERR_FAIL_COND_V_MSG(p_params.local_scene && p_params.subres_mode != RESOURCE_DEEP_DUPLICATE_MAX, Ref<Resource>(), "Duplication for local-to-scene can't specify a deep duplicate mode."); ERR_FAIL_COND_V_MSG(p_params.local_scene && p_params.subres_mode != RESOURCE_DEEP_DUPLICATE_MAX, Ref<Resource>(), "Duplication for local-to-scene can't specify a deep duplicate mode.");
DuplicateRemapCacheT *remap_cache_backup = thread_duplicate_remap_cache; DuplicateRemapCacheT *remap_cache_backup = thread_duplicate_remap_cache;
bool remap_cache_needs_deallocation_backup = thread_duplicate_remap_cache_needs_deallocation;
// These are for avoiding potential duplicates that can happen in custom code // These are for avoiding potential duplicates that can happen in custom code
// from participating in the same duplication session (remap cache). // from participating in the same duplication session (remap cache).
#define BEFORE_USER_CODE thread_duplicate_remap_cache = nullptr; #define BEFORE_USER_CODE thread_duplicate_remap_cache = nullptr;
#define AFTER_USER_CODE thread_duplicate_remap_cache = remap_cache_backup; #define AFTER_USER_CODE \
thread_duplicate_remap_cache = remap_cache_backup; \
thread_duplicate_remap_cache_needs_deallocation = remap_cache_needs_deallocation_backup;
List<PropertyInfo> plist; List<PropertyInfo> plist;
get_property_list(&plist); get_property_list(&plist);
@ -434,7 +437,9 @@ Ref<Resource> Resource::duplicate_for_local_scene(Node *p_for_scene, DuplicateRe
#endif #endif
DuplicateRemapCacheT *remap_cache_backup = thread_duplicate_remap_cache; DuplicateRemapCacheT *remap_cache_backup = thread_duplicate_remap_cache;
bool remap_cache_needs_deallocation_backup = thread_duplicate_remap_cache_needs_deallocation;
thread_duplicate_remap_cache = &p_remap_cache; thread_duplicate_remap_cache = &p_remap_cache;
thread_duplicate_remap_cache_needs_deallocation = false;
DuplicateParams params; DuplicateParams params;
params.deep = true; params.deep = true;
@ -442,6 +447,7 @@ Ref<Resource> Resource::duplicate_for_local_scene(Node *p_for_scene, DuplicateRe
const Ref<Resource> &dupe = _duplicate(params); const Ref<Resource> &dupe = _duplicate(params);
thread_duplicate_remap_cache = remap_cache_backup; thread_duplicate_remap_cache = remap_cache_backup;
thread_duplicate_remap_cache_needs_deallocation = remap_cache_needs_deallocation_backup;
return dupe; return dupe;
} }
@ -504,6 +510,7 @@ Ref<Resource> Resource::duplicate(bool p_deep) const {
bool started_session = false; bool started_session = false;
if (!thread_duplicate_remap_cache) { if (!thread_duplicate_remap_cache) {
thread_duplicate_remap_cache = &remap_cache; thread_duplicate_remap_cache = &remap_cache;
thread_duplicate_remap_cache_needs_deallocation = false;
started_session = true; started_session = true;
} }
@ -526,6 +533,7 @@ Ref<Resource> Resource::duplicate_deep(ResourceDeepDuplicateMode p_deep_subresou
bool started_session = false; bool started_session = false;
if (!thread_duplicate_remap_cache) { if (!thread_duplicate_remap_cache) {
thread_duplicate_remap_cache = &remap_cache; thread_duplicate_remap_cache = &remap_cache;
thread_duplicate_remap_cache_needs_deallocation = false;
started_session = true; started_session = true;
} }
@ -571,6 +579,7 @@ Ref<Resource> Resource::_duplicate_from_variant(bool p_deep, ResourceDeepDuplica
} }
} else { } else {
thread_duplicate_remap_cache = memnew(DuplicateRemapCacheT); thread_duplicate_remap_cache = memnew(DuplicateRemapCacheT);
thread_duplicate_remap_cache_needs_deallocation = true;
} }
DuplicateParams params; DuplicateParams params;
@ -583,7 +592,7 @@ Ref<Resource> Resource::_duplicate_from_variant(bool p_deep, ResourceDeepDuplica
} }
void Resource::_teardown_duplicate_from_variant() { void Resource::_teardown_duplicate_from_variant() {
if (thread_duplicate_remap_cache) { if (thread_duplicate_remap_cache && thread_duplicate_remap_cache_needs_deallocation) {
memdelete(thread_duplicate_remap_cache); memdelete(thread_duplicate_remap_cache);
thread_duplicate_remap_cache = nullptr; thread_duplicate_remap_cache = nullptr;
} }

View file

@ -94,6 +94,7 @@ private:
using DuplicateRemapCacheT = HashMap<Ref<Resource>, Ref<Resource>>; using DuplicateRemapCacheT = HashMap<Ref<Resource>, Ref<Resource>>;
static thread_local inline DuplicateRemapCacheT *thread_duplicate_remap_cache = nullptr; static thread_local inline DuplicateRemapCacheT *thread_duplicate_remap_cache = nullptr;
static thread_local inline bool thread_duplicate_remap_cache_needs_deallocation = true;
Variant _duplicate_recursive(const Variant &p_variant, const DuplicateParams &p_params, uint32_t p_usage = 0) const; Variant _duplicate_recursive(const Variant &p_variant, const DuplicateParams &p_params, uint32_t p_usage = 0) const;
void _find_sub_resources(const Variant &p_variant, HashSet<Ref<Resource>> &p_resources_found); void _find_sub_resources(const Variant &p_variant, HashSet<Ref<Resource>> &p_resources_found);