소스 검색

Fix creation (and godot-side deletion) of extended objects.

Proper initialization for godot-cpp classes with memnew.

Extension classes (i.e. the `GDCLASS` macro) behave differently from
regular wrapped classes, and requires Godot to initialize them during
object construction.

This commit update the GDCLASS macro to not create/destroy the instance
during the bindings callback, but during the extension callbacks.

When setting the object instance, the bindings instance is set to the
pointer of the extension instance so that it can later be retrieved
normally via `object_get_instance_bindings`.
Fabio Alessandrelli 3 년 전
부모
커밋
b4632e317d
2개의 변경된 파일15개의 추가작업 그리고 10개의 파일을 삭제
  1. 3 1
      godot-headers-temp/godot/gdnative_interface.h
  2. 12 9
      include/godot_cpp/classes/wrapped.hpp

+ 3 - 1
godot-headers-temp/godot/gdnative_interface.h

@@ -137,6 +137,7 @@ typedef void *GDNativeStringNamePtr;
 typedef void *GDNativeStringPtr;
 typedef void *GDNativeObjectPtr;
 typedef void *GDNativeTypePtr;
+typedef void *GDNativeExtensionPtr;
 typedef void *GDNativeMethodBindPtr;
 typedef int64_t GDNativeInt;
 typedef uint8_t GDNativeBool;
@@ -428,7 +429,8 @@ typedef struct {
 
 	/* CLASSDB */
 
-	GDNativeClassConstructor (*classdb_get_constructor)(const char *p_classname);
+	GDNativeClassConstructor (*classdb_get_constructor)(const char *p_classname, GDNativeExtensionPtr *r_extension);
+	GDNativeObjectPtr (*classdb_construct_object)(GDNativeClassConstructor p_constructor, GDNativeExtensionPtr p_extension);
 	GDNativeMethodBindPtr (*classdb_get_method_bind)(const char *p_classname, const char *p_methodname, GDNativeInt p_hash);
 	void *(*classdb_get_class_tag)(const char *p_classname);
 

+ 12 - 9
include/godot_cpp/classes/wrapped.hpp

@@ -137,20 +137,22 @@ public:
 	}                                                                                                                                                             \
                                                                                                                                                                   \
 	static void free(void *data, GDExtensionClassInstancePtr ptr) {                                                                                               \
-		Memory::free_static(reinterpret_cast<m_class *>(ptr));                                                                                                    \
+		if (ptr) {                                                                                                                                                \
+			m_class *cls = reinterpret_cast<m_class *>(ptr);                                                                                                      \
+			cls->~m_class();                                                                                                                                      \
+			::godot::Memory::free_static(cls);                                                                                                                    \
+		}                                                                                                                                                         \
 	}                                                                                                                                                             \
                                                                                                                                                                   \
 	static void set_object_instance(GDExtensionClassInstancePtr p_instance, GDNativeObjectPtr p_object_instance) {                                                \
-		reinterpret_cast<m_class *>(p_instance)->_owner = reinterpret_cast<GodotObject *>(p_object_instance);                                                     \
+		godot::internal::interface->object_set_instance_binding(p_object_instance, godot::internal::token, p_instance, &m_class::___binding_callbacks);           \
+		reinterpret_cast<m_class *>(p_instance)->_owner = reinterpret_cast<godot::GodotObject *>(p_object_instance);                                              \
 	}                                                                                                                                                             \
                                                                                                                                                                   \
 	static void *___binding_create_callback(void *p_token, void *p_instance) {                                                                                    \
-		m_class *result = new ("") m_class;                                                                                                                       \
-		result->_owner = reinterpret_cast<godot::GodotObject *>(p_instance);                                                                                      \
-		return result;                                                                                                                                            \
+		return nullptr;                                                                                                                                           \
 	}                                                                                                                                                             \
 	static void ___binding_free_callback(void *p_token, void *p_instance, void *p_binding) {                                                                      \
-		Memory::free_static(reinterpret_cast<m_class *>(p_binding));                                                                                              \
 	}                                                                                                                                                             \
 	static GDNativeBool ___binding_reference_callback(void *p_token, void *p_instance, GDNativeBool p_reference) {                                                \
 		return true;                                                                                                                                              \
@@ -162,9 +164,10 @@ public:
 	};                                                                                                                                                            \
                                                                                                                                                                   \
 	static m_class *_new() {                                                                                                                                      \
-		static GDNativeClassConstructor ___constructor = godot::internal::interface->classdb_get_constructor(#m_class);                                           \
+		static GDNativeExtensionPtr ___extension = nullptr;                                                                                                       \
+		static GDNativeClassConstructor ___constructor = godot::internal::interface->classdb_get_constructor(#m_class, &___extension);                            \
 		CHECK_CLASS_CONSTRUCTOR(___constructor, m_class);                                                                                                         \
-		GDNativeObjectPtr obj = ___constructor();                                                                                                                 \
+		GDNativeObjectPtr obj = godot::internal::interface->classdb_construct_object(___constructor, ___extension);                                               \
 		return reinterpret_cast<m_class *>(godot::internal::interface->object_get_instance_binding(obj, godot::internal::token, &m_class::___binding_callbacks)); \
 	}                                                                                                                                                             \
                                                                                                                                                                   \
@@ -205,7 +208,7 @@ public:
 		___binding_reference_callback,                                                                                                                            \
 	};                                                                                                                                                            \
 	static m_class *_new() {                                                                                                                                      \
-		static GDNativeClassConstructor ___constructor = godot::internal::interface->classdb_get_constructor(#m_class);                                           \
+		static GDNativeClassConstructor ___constructor = godot::internal::interface->classdb_get_constructor(#m_class, nullptr);                                  \
 		CHECK_CLASS_CONSTRUCTOR(___constructor, m_class);                                                                                                         \
 		GDNativeObjectPtr obj = ___constructor();                                                                                                                 \
 		return reinterpret_cast<m_class *>(godot::internal::interface->object_get_instance_binding(obj, godot::internal::token, &m_class::___binding_callbacks)); \