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>
This commit is contained in:
Adam Scott
2022-12-02 13:27:26 -05:00
parent f3e6750a7e
commit 88f3045301
5 changed files with 61 additions and 47 deletions

View File

@ -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;
}