diff options
author | Adam Scott <ascott.ca@gmail.com> | 2022-12-02 13:27:26 -0500 |
---|---|---|
committer | Adam Scott <ascott.ca@gmail.com> | 2022-12-06 09:35:39 -0500 |
commit | 88f3045301470fd13bbe3ade6537a1c1cb1227fe (patch) | |
tree | 1b14193cbf349ab4136fd5bd32fa61712daf9282 | |
parent | f3e6750a7e4702918e05f42b1376e30e652f2f90 (diff) |
Move GDScript uninitialization to `GDScriptLanguage::finalize()`
Co-authored-by: Ricardo Buring <ricardo.buring@gmail.com>
Co-authored-by: kleonc <9283098+kleonc@users.noreply.github.com>
-rw-r--r-- | modules/gdscript/gdscript.cpp | 66 | ||||
-rw-r--r-- | modules/gdscript/gdscript_cache.cpp | 30 | ||||
-rw-r--r-- | modules/gdscript/gdscript_cache.h | 2 | ||||
-rw-r--r-- | scene/resources/shape_2d.cpp | 5 | ||||
-rw-r--r-- | scene/resources/shape_3d.cpp | 5 |
5 files changed, 61 insertions, 47 deletions
diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index 60230257e0..c8195de640 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -2019,6 +2019,42 @@ Error GDScriptLanguage::execute_file(const String &p_path) { } void GDScriptLanguage::finish() { + if (_call_stack) { + memdelete_arr(_call_stack); + _call_stack = nullptr; + } + + // Clear the cache before parsing the script_list + GDScriptCache::clear(); + + // Clear dependencies between scripts, to ensure cyclic references are broken + // (to avoid leaks at exit). + SelfList<GDScript> *s = script_list.first(); + while (s) { + // This ensures the current script is not released before we can check + // what's the next one in the list (we can't get the next upfront because we + // don't know if the reference breaking will cause it -or any other after + // it, for that matter- to be released so the next one is not the same as + // before). + Ref<GDScript> scr = s->self(); + if (scr.is_valid()) { + for (KeyValue<StringName, GDScriptFunction *> &E : scr->member_functions) { + GDScriptFunction *func = E.value; + for (int i = 0; i < func->argument_types.size(); i++) { + func->argument_types.write[i].script_type_ref = Ref<Script>(); + } + func->return_type.script_type_ref = Ref<Script>(); + } + for (KeyValue<StringName, GDScript::MemberInfo> &E : scr->member_indices) { + E.value.data_type.script_type_ref = Ref<Script>(); + } + + // Clear backup for scripts that could slip out of the cyclic reference + // check + scr->clear(); + } + s = s->next(); + } } void GDScriptLanguage::profiling_start() { @@ -2530,36 +2566,6 @@ GDScriptLanguage::GDScriptLanguage() { } GDScriptLanguage::~GDScriptLanguage() { - if (_call_stack) { - memdelete_arr(_call_stack); - } - - // Clear dependencies between scripts, to ensure cyclic references are broken (to avoid leaks at exit). - SelfList<GDScript> *s = script_list.first(); - while (s) { - // This ensures the current script is not released before we can check what's the next one - // in the list (we can't get the next upfront because we don't know if the reference breaking - // will cause it -or any other after it, for that matter- to be released so the next one - // is not the same as before). - Ref<GDScript> scr = s->self(); - if (scr.is_valid()) { - for (KeyValue<StringName, GDScriptFunction *> &E : scr->member_functions) { - GDScriptFunction *func = E.value; - for (int i = 0; i < func->argument_types.size(); i++) { - func->argument_types.write[i].script_type_ref = Ref<Script>(); - } - func->return_type.script_type_ref = Ref<Script>(); - } - for (KeyValue<StringName, GDScript::MemberInfo> &E : scr->member_indices) { - E.value.data_type.script_type_ref = Ref<Script>(); - } - - // Clear backup for scripts that could slip out of the cyclic reference check - scr->clear(); - } - s = s->next(); - } - singleton = nullptr; } diff --git a/modules/gdscript/gdscript_cache.cpp b/modules/gdscript/gdscript_cache.cpp index 021504f242..699ce67933 100644 --- a/modules/gdscript/gdscript_cache.cpp +++ b/modules/gdscript/gdscript_cache.cpp @@ -381,15 +381,15 @@ void GDScriptCache::clear_unreferenced_packed_scenes() { } } -GDScriptCache::GDScriptCache() { - singleton = this; -} +void GDScriptCache::clear() { + if (singleton == nullptr) { + return; + } -GDScriptCache::~GDScriptCache() { - destructing = true; + MutexLock lock(singleton->mutex); RBSet<Ref<GDScriptParserRef>> parser_map_refs; - for (KeyValue<String, GDScriptParserRef *> &E : parser_map) { + for (KeyValue<String, GDScriptParserRef *> &E : singleton->parser_map) { parser_map_refs.insert(E.value); } @@ -399,12 +399,20 @@ GDScriptCache::~GDScriptCache() { } parser_map_refs.clear(); - parser_map.clear(); - shallow_gdscript_cache.clear(); - full_gdscript_cache.clear(); + singleton->parser_map.clear(); + singleton->shallow_gdscript_cache.clear(); + singleton->full_gdscript_cache.clear(); - packed_scene_cache.clear(); - packed_scene_dependencies.clear(); + singleton->packed_scene_cache.clear(); + singleton->packed_scene_dependencies.clear(); +} + +GDScriptCache::GDScriptCache() { + singleton = this; +} +GDScriptCache::~GDScriptCache() { + destructing = true; + clear(); singleton = nullptr; } diff --git a/modules/gdscript/gdscript_cache.h b/modules/gdscript/gdscript_cache.h index 2195932aa3..e7e1901d5d 100644 --- a/modules/gdscript/gdscript_cache.h +++ b/modules/gdscript/gdscript_cache.h @@ -111,6 +111,8 @@ public: return singleton->destructing; }; + static void clear(); + GDScriptCache(); ~GDScriptCache(); }; diff --git a/scene/resources/shape_2d.cpp b/scene/resources/shape_2d.cpp index 413670d23e..87c6c36ee9 100644 --- a/scene/resources/shape_2d.cpp +++ b/scene/resources/shape_2d.cpp @@ -124,7 +124,6 @@ Shape2D::Shape2D(const RID &p_rid) { } Shape2D::~Shape2D() { - if (PhysicsServer2D::get_singleton() != nullptr) { - PhysicsServer2D::get_singleton()->free(shape); - } + ERR_FAIL_NULL(PhysicsServer2D::get_singleton()); + PhysicsServer2D::get_singleton()->free(shape); } diff --git a/scene/resources/shape_3d.cpp b/scene/resources/shape_3d.cpp index 44f21d2a48..7992ba9fd4 100644 --- a/scene/resources/shape_3d.cpp +++ b/scene/resources/shape_3d.cpp @@ -128,7 +128,6 @@ Shape3D::Shape3D(RID p_shape) : shape(p_shape) {} Shape3D::~Shape3D() { - if (PhysicsServer3D::get_singleton() != nullptr) { - PhysicsServer3D::get_singleton()->free(shape); - } + ERR_FAIL_NULL(PhysicsServer3D::get_singleton()); + PhysicsServer3D::get_singleton()->free(shape); } |