Skip to content

Commit 022d702

Browse files
committed
Merge pull request #94678 from rune-scape/clear-abandoned-parser-refs
GDScriptCache: Clear abandoned parser refs
2 parents 77e18da + 86b23d0 commit 022d702

File tree

2 files changed

+34
-1
lines changed

2 files changed

+34
-1
lines changed

modules/gdscript/gdscript_cache.cpp

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,9 @@ void GDScriptParserRef::clear() {
135135

136136
GDScriptParserRef::~GDScriptParserRef() {
137137
clear();
138-
GDScriptCache::remove_parser(path);
138+
if (!abandoned) {
139+
GDScriptCache::remove_parser(path);
140+
}
139141
}
140142

141143
GDScriptCache *GDScriptCache::singleton = nullptr;
@@ -183,6 +185,17 @@ void GDScriptCache::remove_script(const String &p_path) {
183185
return;
184186
}
185187

188+
if (HashMap<String, Vector<ObjectID>>::Iterator E = singleton->abandoned_parser_map.find(p_path)) {
189+
for (ObjectID parser_ref_id : E->value) {
190+
Ref<GDScriptParserRef> parser_ref{ ObjectDB::get_instance(parser_ref_id) };
191+
if (parser_ref.is_valid()) {
192+
parser_ref->clear();
193+
}
194+
}
195+
}
196+
197+
singleton->abandoned_parser_map.erase(p_path);
198+
186199
if (singleton->parser_map.has(p_path)) {
187200
singleton->parser_map[p_path]->clear();
188201
}
@@ -229,6 +242,13 @@ bool GDScriptCache::has_parser(const String &p_path) {
229242

230243
void GDScriptCache::remove_parser(const String &p_path) {
231244
MutexLock lock(singleton->mutex);
245+
246+
if (singleton->parser_map.has(p_path)) {
247+
GDScriptParserRef *parser_ref = singleton->parser_map[p_path];
248+
parser_ref->abandoned = true;
249+
singleton->abandoned_parser_map[p_path].push_back(parser_ref->get_instance_id());
250+
}
251+
232252
// Can't clear the parser because some other parser might be currently using it in the chain of calls.
233253
singleton->parser_map.erase(p_path);
234254

@@ -432,6 +452,17 @@ void GDScriptCache::clear() {
432452

433453
singleton->parser_inverse_dependencies.clear();
434454

455+
for (const KeyValue<String, Vector<ObjectID>> &KV : singleton->abandoned_parser_map) {
456+
for (ObjectID parser_ref_id : KV.value) {
457+
Ref<GDScriptParserRef> parser_ref{ ObjectDB::get_instance(parser_ref_id) };
458+
if (parser_ref.is_valid()) {
459+
parser_ref->clear();
460+
}
461+
}
462+
}
463+
464+
singleton->abandoned_parser_map.clear();
465+
435466
RBSet<Ref<GDScriptParserRef>> parser_map_refs;
436467
for (KeyValue<String, GDScriptParserRef *> &E : singleton->parser_map) {
437468
parser_map_refs.insert(E.value);

modules/gdscript/gdscript_cache.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ class GDScriptParserRef : public RefCounted {
5959
String path;
6060
uint32_t source_hash = 0;
6161
bool clearing = false;
62+
bool abandoned = false;
6263

6364
friend class GDScriptCache;
6465
friend class GDScript;
@@ -79,6 +80,7 @@ class GDScriptParserRef : public RefCounted {
7980
class GDScriptCache {
8081
// String key is full path.
8182
HashMap<String, GDScriptParserRef *> parser_map;
83+
HashMap<String, Vector<ObjectID>> abandoned_parser_map;
8284
HashMap<String, Ref<GDScript>> shallow_gdscript_cache;
8385
HashMap<String, Ref<GDScript>> full_gdscript_cache;
8486
HashMap<String, Ref<GDScript>> static_gdscript_cache;

0 commit comments

Comments
 (0)