diff --git a/modules/gdscript/gdscript_cache.cpp b/modules/gdscript/gdscript_cache.cpp index 7c9fba799d41..2b1184bcb95f 100644 --- a/modules/gdscript/gdscript_cache.cpp +++ b/modules/gdscript/gdscript_cache.cpp @@ -135,7 +135,9 @@ void GDScriptParserRef::clear() { GDScriptParserRef::~GDScriptParserRef() { clear(); - GDScriptCache::remove_parser(path); + if (!abandoned) { + GDScriptCache::remove_parser(path); + } } GDScriptCache *GDScriptCache::singleton = nullptr; @@ -183,6 +185,17 @@ void GDScriptCache::remove_script(const String &p_path) { return; } + if (HashMap>::Iterator E = singleton->abandoned_parser_map.find(p_path)) { + for (ObjectID parser_ref_id : E->value) { + Ref parser_ref{ ObjectDB::get_instance(parser_ref_id) }; + if (parser_ref.is_valid()) { + parser_ref->clear(); + } + } + } + + singleton->abandoned_parser_map.erase(p_path); + if (singleton->parser_map.has(p_path)) { singleton->parser_map[p_path]->clear(); } @@ -229,6 +242,13 @@ bool GDScriptCache::has_parser(const String &p_path) { void GDScriptCache::remove_parser(const String &p_path) { MutexLock lock(singleton->mutex); + + if (singleton->parser_map.has(p_path)) { + GDScriptParserRef *parser_ref = singleton->parser_map[p_path]; + parser_ref->abandoned = true; + singleton->abandoned_parser_map[p_path].push_back(parser_ref->get_instance_id()); + } + // Can't clear the parser because some other parser might be currently using it in the chain of calls. singleton->parser_map.erase(p_path); @@ -432,6 +452,17 @@ void GDScriptCache::clear() { singleton->parser_inverse_dependencies.clear(); + for (const KeyValue> &KV : singleton->abandoned_parser_map) { + for (ObjectID parser_ref_id : KV.value) { + Ref parser_ref{ ObjectDB::get_instance(parser_ref_id) }; + if (parser_ref.is_valid()) { + parser_ref->clear(); + } + } + } + + singleton->abandoned_parser_map.clear(); + RBSet> parser_map_refs; for (KeyValue &E : singleton->parser_map) { parser_map_refs.insert(E.value); diff --git a/modules/gdscript/gdscript_cache.h b/modules/gdscript/gdscript_cache.h index c927317e19a4..f7f2cd90e9e9 100644 --- a/modules/gdscript/gdscript_cache.h +++ b/modules/gdscript/gdscript_cache.h @@ -59,6 +59,7 @@ class GDScriptParserRef : public RefCounted { String path; uint32_t source_hash = 0; bool clearing = false; + bool abandoned = false; friend class GDScriptCache; friend class GDScript; @@ -79,6 +80,7 @@ class GDScriptParserRef : public RefCounted { class GDScriptCache { // String key is full path. HashMap parser_map; + HashMap> abandoned_parser_map; HashMap> shallow_gdscript_cache; HashMap> full_gdscript_cache; HashMap> static_gdscript_cache;