Merge pull request #69506 from adamscott/move-gdscript-uninit-to-finalize
Move GDScript uninitialization to `GDScriptLanguage::finish()`
This commit is contained in:
commit
9bd7ad53f7
|
@ -2019,6 +2019,42 @@ Error GDScriptLanguage::execute_file(const String &p_path) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void GDScriptLanguage::finish() {
|
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() {
|
void GDScriptLanguage::profiling_start() {
|
||||||
|
@ -2530,36 +2566,6 @@ GDScriptLanguage::GDScriptLanguage() {
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
singleton = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -381,15 +381,15 @@ void GDScriptCache::clear_unreferenced_packed_scenes() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GDScriptCache::GDScriptCache() {
|
void GDScriptCache::clear() {
|
||||||
singleton = this;
|
if (singleton == nullptr) {
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
GDScriptCache::~GDScriptCache() {
|
MutexLock lock(singleton->mutex);
|
||||||
destructing = true;
|
|
||||||
|
|
||||||
RBSet<Ref<GDScriptParserRef>> parser_map_refs;
|
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);
|
parser_map_refs.insert(E.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -399,12 +399,20 @@ GDScriptCache::~GDScriptCache() {
|
||||||
}
|
}
|
||||||
|
|
||||||
parser_map_refs.clear();
|
parser_map_refs.clear();
|
||||||
parser_map.clear();
|
singleton->parser_map.clear();
|
||||||
shallow_gdscript_cache.clear();
|
singleton->shallow_gdscript_cache.clear();
|
||||||
full_gdscript_cache.clear();
|
singleton->full_gdscript_cache.clear();
|
||||||
|
|
||||||
packed_scene_cache.clear();
|
singleton->packed_scene_cache.clear();
|
||||||
packed_scene_dependencies.clear();
|
singleton->packed_scene_dependencies.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
GDScriptCache::GDScriptCache() {
|
||||||
|
singleton = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
GDScriptCache::~GDScriptCache() {
|
||||||
|
destructing = true;
|
||||||
|
clear();
|
||||||
singleton = nullptr;
|
singleton = nullptr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,6 +111,8 @@ public:
|
||||||
return singleton->destructing;
|
return singleton->destructing;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void clear();
|
||||||
|
|
||||||
GDScriptCache();
|
GDScriptCache();
|
||||||
~GDScriptCache();
|
~GDScriptCache();
|
||||||
};
|
};
|
||||||
|
|
|
@ -124,7 +124,6 @@ Shape2D::Shape2D(const RID &p_rid) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Shape2D::~Shape2D() {
|
Shape2D::~Shape2D() {
|
||||||
if (PhysicsServer2D::get_singleton() != nullptr) {
|
ERR_FAIL_NULL(PhysicsServer2D::get_singleton());
|
||||||
PhysicsServer2D::get_singleton()->free(shape);
|
PhysicsServer2D::get_singleton()->free(shape);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -128,7 +128,6 @@ Shape3D::Shape3D(RID p_shape) :
|
||||||
shape(p_shape) {}
|
shape(p_shape) {}
|
||||||
|
|
||||||
Shape3D::~Shape3D() {
|
Shape3D::~Shape3D() {
|
||||||
if (PhysicsServer3D::get_singleton() != nullptr) {
|
ERR_FAIL_NULL(PhysicsServer3D::get_singleton());
|
||||||
PhysicsServer3D::get_singleton()->free(shape);
|
PhysicsServer3D::get_singleton()->free(shape);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue