Sfoglia il codice sorgente

Move GDScript uninitialization to `GDScriptLanguage::finalize()`

Co-authored-by: Ricardo Buring <[email protected]>
Co-authored-by: kleonc <[email protected]>
Adam Scott 2 anni fa
parent
commit
88f3045301

+ 36 - 30
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;
 }
 

+ 19 - 11
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;
 }

+ 2 - 0
modules/gdscript/gdscript_cache.h

@@ -111,6 +111,8 @@ public:
 		return singleton->destructing;
 	};
 
+	static void clear();
+
 	GDScriptCache();
 	~GDScriptCache();
 };

+ 2 - 3
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);
 }

+ 2 - 3
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);
 }