Ver código fonte

Merge pull request #1047 from Kehom/master

Unregister custom classes in reverse registration order
David Snopek 2 anos atrás
pai
commit
2377f7ec75
2 arquivos alterados com 9 adições e 3 exclusões
  1. 3 0
      include/godot_cpp/core/class_db.hpp
  2. 6 3
      src/core/class_db.cpp

+ 3 - 0
include/godot_cpp/core/class_db.hpp

@@ -105,6 +105,8 @@ private:
 	// This may only contain custom classes, not Godot classes
 	static std::unordered_map<StringName, ClassInfo> classes;
 	static std::unordered_map<StringName, const GDExtensionInstanceBindingCallbacks *> instance_binding_callbacks;
+	// Used to remember the custom class registration order.
+	static std::vector<StringName> class_register_order;
 
 	static MethodBind *bind_methodfi(uint32_t p_flags, MethodBind *p_bind, const MethodDefinition &method_name, const void **p_defs, int p_defcount);
 	static void initialize_class(const ClassInfo &cl);
@@ -178,6 +180,7 @@ void ClassDB::_register_class(bool p_virtual) {
 		cl.parent_ptr = &parent_it->second;
 	}
 	classes[cl.name] = cl;
+	class_register_order.push_back(cl.name);
 
 	// Register this class with Godot
 	GDExtensionClassCreationInfo class_info = {

+ 6 - 3
src/core/class_db.cpp

@@ -41,6 +41,7 @@ namespace godot {
 
 std::unordered_map<StringName, ClassDB::ClassInfo> ClassDB::classes;
 std::unordered_map<StringName, const GDExtensionInstanceBindingCallbacks *> ClassDB::instance_binding_callbacks;
+std::vector<StringName> ClassDB::class_register_order;
 GDExtensionInitializationLevel ClassDB::current_level = GDEXTENSION_INITIALIZATION_CORE;
 
 MethodDefinition D_METHOD(StringName p_name) {
@@ -348,13 +349,15 @@ void ClassDB::initialize(GDExtensionInitializationLevel p_level) {
 }
 
 void ClassDB::deinitialize(GDExtensionInitializationLevel p_level) {
-	for (const std::pair<StringName, ClassInfo> pair : classes) {
-		const ClassInfo &cl = pair.second;
+	for (std::vector<StringName>::reverse_iterator i = class_register_order.rbegin(); i != class_register_order.rend(); ++i) {
+		const StringName &name = *i;
+		const ClassInfo &cl = classes[name];
+
 		if (cl.level != p_level) {
 			continue;
 		}
 
-		internal::gdextension_interface_classdb_unregister_extension_class(internal::library, cl.name._native_ptr());
+		internal::gdextension_interface_classdb_unregister_extension_class(internal::library, name._native_ptr());
 
 		for (auto method : cl.method_map) {
 			memdelete(method.second);