GDScript: Use pointer instead of references in cache

They are not supposed to be kept alive and this is cleaner and less
error-prone than unreferencing the elements.
This commit is contained in:
George Marques 2020-08-23 11:19:35 -03:00
parent 58f5c2bab6
commit d36d7e2a1c
No known key found for this signature in database
GPG Key ID: 046BD46A3201E43D
3 changed files with 9 additions and 15 deletions

View File

@ -603,10 +603,8 @@ Error GDScript::reload(bool p_keep_state) {
} }
if (!source_path.empty()) { if (!source_path.empty()) {
MutexLock lock(GDScriptCache::singleton->lock); MutexLock lock(GDScriptCache::singleton->lock);
Ref<GDScript> self(this);
if (!GDScriptCache::singleton->shallow_gdscript_cache.has(source_path)) { if (!GDScriptCache::singleton->shallow_gdscript_cache.has(source_path)) {
GDScriptCache::singleton->shallow_gdscript_cache[source_path] = self; GDScriptCache::singleton->shallow_gdscript_cache[source_path] = this;
self->unreference();
} }
} }
} }

View File

@ -127,7 +127,7 @@ Ref<GDScriptParserRef> GDScriptCache::get_parser(const String &p_path, GDScriptP
singleton->dependencies[p_owner].insert(p_path); singleton->dependencies[p_owner].insert(p_path);
} }
if (singleton->parser_map.has(p_path)) { if (singleton->parser_map.has(p_path)) {
ref = singleton->parser_map[p_path]; ref = Ref<GDScriptParserRef>(singleton->parser_map[p_path]);
} else { } else {
if (!FileAccess::exists(p_path)) { if (!FileAccess::exists(p_path)) {
r_error = ERR_FILE_NOT_FOUND; r_error = ERR_FILE_NOT_FOUND;
@ -137,8 +137,7 @@ Ref<GDScriptParserRef> GDScriptCache::get_parser(const String &p_path, GDScriptP
ref.instance(); ref.instance();
ref->parser = parser; ref->parser = parser;
ref->path = p_path; ref->path = p_path;
singleton->parser_map[p_path] = ref; singleton->parser_map[p_path] = ref.ptr();
ref->unreference();
} }
r_error = ref->raise_status(p_status); r_error = ref->raise_status(p_status);
@ -186,10 +185,7 @@ Ref<GDScript> GDScriptCache::get_shallow_script(const String &p_path, const Stri
script->set_script_path(p_path); script->set_script_path(p_path);
script->load_source_code(p_path); script->load_source_code(p_path);
singleton->shallow_gdscript_cache[p_path] = script; singleton->shallow_gdscript_cache[p_path] = script.ptr();
// The one in cache is not a hard reference: if the script dies somewhere else it's fine.
// Scripts remove themselves from cache when they die.
script->unreference();
return script; return script;
} }
@ -217,7 +213,7 @@ Ref<GDScript> GDScriptCache::get_full_script(const String &p_path, Error &r_erro
return script; return script;
} }
singleton->full_gdscript_cache[p_path] = script; singleton->full_gdscript_cache[p_path] = script.ptr();
singleton->shallow_gdscript_cache.erase(p_path); singleton->shallow_gdscript_cache.erase(p_path);
return script; return script;
@ -226,7 +222,7 @@ Ref<GDScript> GDScriptCache::get_full_script(const String &p_path, Error &r_erro
Error GDScriptCache::finish_compiling(const String &p_owner) { Error GDScriptCache::finish_compiling(const String &p_owner) {
// Mark this as compiled. // Mark this as compiled.
Ref<GDScript> script = get_shallow_script(p_owner); Ref<GDScript> script = get_shallow_script(p_owner);
singleton->full_gdscript_cache[p_owner] = script; singleton->full_gdscript_cache[p_owner] = script.ptr();
singleton->shallow_gdscript_cache.erase(p_owner); singleton->shallow_gdscript_cache.erase(p_owner);
Set<String> depends = singleton->dependencies[p_owner]; Set<String> depends = singleton->dependencies[p_owner];

View File

@ -70,9 +70,9 @@ public:
class GDScriptCache { class GDScriptCache {
// String key is full path. // String key is full path.
HashMap<String, Ref<GDScriptParserRef>> parser_map; HashMap<String, GDScriptParserRef *> parser_map;
HashMap<String, Ref<GDScript>> shallow_gdscript_cache; HashMap<String, GDScript *> shallow_gdscript_cache;
HashMap<String, Ref<GDScript>> full_gdscript_cache; HashMap<String, GDScript *> full_gdscript_cache;
HashMap<String, Set<String>> dependencies; HashMap<String, Set<String>> dependencies;
friend class GDScript; friend class GDScript;