From f724bd1880ba9633e3f2dd530775dc0535d9cc17 Mon Sep 17 00:00:00 2001 From: Fabio Alessandrelli Date: Tue, 21 Sep 2021 03:54:50 +0200 Subject: [PATCH 1/2] [Core] Add ClassDB functions to retrieve/construct extensions. Calling the constructor alone is not enough if the class to be instantiated is not a base class. This commit adds two functions, one for retrieving the the extension class reference, the other to construct an instance using the constructor and the extension class reference. --- core/extension/gdnative_interface.cpp | 14 ++++++++++++++ core/extension/gdnative_interface.h | 3 +++ core/object/class_db.cpp | 7 +++++++ core/object/class_db.h | 1 + 4 files changed, 25 insertions(+) diff --git a/core/extension/gdnative_interface.cpp b/core/extension/gdnative_interface.cpp index b41f74a4bc87..dde8449c3e44 100644 --- a/core/extension/gdnative_interface.cpp +++ b/core/extension/gdnative_interface.cpp @@ -862,6 +862,18 @@ static GDNativeClassConstructor gdnative_classdb_get_constructor(const char *p_c return nullptr; } +static GDNativeExtensionPtr gdnative_classdb_get_extension(const char *p_classname) { + ClassDB::ClassInfo *class_info = ClassDB::classes.getptr(StringName(p_classname)); + if (class_info) { + return (GDNativeExtensionPtr)class_info->native_extension; + } + return nullptr; +} + +static GDNativeObjectPtr gdnative_classdb_construct_extended(GDNativeClassConstructor p_constructor, GDNativeExtensionPtr p_extension) { + return (GDNativeObjectPtr)ClassDB::construct_extended((Object * (*)()) p_constructor, (ObjectNativeExtension *)p_extension); +} + static void *gdnative_classdb_get_class_tag(const char *p_classname) { ClassDB::ClassInfo *class_info = ClassDB::classes.getptr(p_classname); return class_info ? class_info->class_ptr : nullptr; @@ -1010,6 +1022,8 @@ void gdnative_setup_interface(GDNativeInterface *p_interface) { /* CLASSDB */ gdni.classdb_get_constructor = gdnative_classdb_get_constructor; + gdni.classdb_get_extension = gdnative_classdb_get_extension; + gdni.classdb_construct_extended = gdnative_classdb_construct_extended; gdni.classdb_get_method_bind = gdnative_classdb_get_method_bind; gdni.classdb_get_class_tag = gdnative_classdb_get_class_tag; diff --git a/core/extension/gdnative_interface.h b/core/extension/gdnative_interface.h index df735db9b603..6ab9c8aea3a5 100644 --- a/core/extension/gdnative_interface.h +++ b/core/extension/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; @@ -432,6 +433,8 @@ typedef struct { /* CLASSDB */ GDNativeClassConstructor (*classdb_get_constructor)(const char *p_classname); + GDNativeExtensionPtr (*classdb_get_extension)(const char *p_classname); + GDNativeObjectPtr (*classdb_construct_extended)(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); diff --git a/core/object/class_db.cpp b/core/object/class_db.cpp index 8e92340c1e5a..05b3dde4ed8a 100644 --- a/core/object/class_db.cpp +++ b/core/object/class_db.cpp @@ -545,6 +545,13 @@ Object *ClassDB::instantiate(const StringName &p_class) { return ti->creation_func(); } +Object *ClassDB::construct_extended(Object *(*p_create_func)(), ObjectNativeExtension *p_extension) { + initializing_with_extension = true; + initializing_extension = p_extension; + initializing_extension_instance = p_extension->create_instance(p_extension->class_userdata); + return p_create_func(); +} + bool ClassDB::can_instantiate(const StringName &p_class) { OBJTYPE_RLOCK; diff --git a/core/object/class_db.h b/core/object/class_db.h index e89c7fffd725..0ba9d5903c1e 100644 --- a/core/object/class_db.h +++ b/core/object/class_db.h @@ -234,6 +234,7 @@ public: static bool is_parent_class(const StringName &p_class, const StringName &p_inherits); static bool can_instantiate(const StringName &p_class); static Object *instantiate(const StringName &p_class); + static Object *construct_extended(Object *(*p_create_func)(), ObjectNativeExtension *p_extension); static void instance_get_native_extension_data(ObjectNativeExtension **r_extension, GDExtensionClassInstancePtr *r_extension_instance, Object *p_base); static APIType get_api_type(const StringName &p_class); From f9ce9a8e103b4b53ad3de032220c3e8799d52409 Mon Sep 17 00:00:00 2001 From: Fabio Alessandrelli Date: Wed, 22 Sep 2021 18:33:29 +0200 Subject: [PATCH 2/2] [ClassDB] Unify construct/extension retrieval. --- core/extension/gdnative_interface.cpp | 20 +++++++------------- core/extension/gdnative_interface.h | 5 ++--- core/object/class_db.cpp | 10 ++++++---- core/object/class_db.h | 2 +- 4 files changed, 16 insertions(+), 21 deletions(-) diff --git a/core/extension/gdnative_interface.cpp b/core/extension/gdnative_interface.cpp index dde8449c3e44..ff09b0b86c90 100644 --- a/core/extension/gdnative_interface.cpp +++ b/core/extension/gdnative_interface.cpp @@ -854,24 +854,19 @@ static GDNativeMethodBindPtr gdnative_classdb_get_method_bind(const char *p_clas return (GDNativeMethodBindPtr)mb; } -static GDNativeClassConstructor gdnative_classdb_get_constructor(const char *p_classname) { +static GDNativeClassConstructor gdnative_classdb_get_constructor(const char *p_classname, GDNativeExtensionPtr *r_extension) { ClassDB::ClassInfo *class_info = ClassDB::classes.getptr(StringName(p_classname)); if (class_info) { + if (r_extension) { + *r_extension = class_info->native_extension; + } return (GDNativeClassConstructor)class_info->creation_func; } return nullptr; } -static GDNativeExtensionPtr gdnative_classdb_get_extension(const char *p_classname) { - ClassDB::ClassInfo *class_info = ClassDB::classes.getptr(StringName(p_classname)); - if (class_info) { - return (GDNativeExtensionPtr)class_info->native_extension; - } - return nullptr; -} - -static GDNativeObjectPtr gdnative_classdb_construct_extended(GDNativeClassConstructor p_constructor, GDNativeExtensionPtr p_extension) { - return (GDNativeObjectPtr)ClassDB::construct_extended((Object * (*)()) p_constructor, (ObjectNativeExtension *)p_extension); +static GDNativeObjectPtr gdnative_classdb_construct_object(GDNativeClassConstructor p_constructor, GDNativeExtensionPtr p_extension) { + return (GDNativeObjectPtr)ClassDB::construct_object((Object * (*)()) p_constructor, (ObjectNativeExtension *)p_extension); } static void *gdnative_classdb_get_class_tag(const char *p_classname) { @@ -1022,8 +1017,7 @@ void gdnative_setup_interface(GDNativeInterface *p_interface) { /* CLASSDB */ gdni.classdb_get_constructor = gdnative_classdb_get_constructor; - gdni.classdb_get_extension = gdnative_classdb_get_extension; - gdni.classdb_construct_extended = gdnative_classdb_construct_extended; + gdni.classdb_construct_object = gdnative_classdb_construct_object; gdni.classdb_get_method_bind = gdnative_classdb_get_method_bind; gdni.classdb_get_class_tag = gdnative_classdb_get_class_tag; diff --git a/core/extension/gdnative_interface.h b/core/extension/gdnative_interface.h index 6ab9c8aea3a5..73f78bde5498 100644 --- a/core/extension/gdnative_interface.h +++ b/core/extension/gdnative_interface.h @@ -432,9 +432,8 @@ typedef struct { /* CLASSDB */ - GDNativeClassConstructor (*classdb_get_constructor)(const char *p_classname); - GDNativeExtensionPtr (*classdb_get_extension)(const char *p_classname); - GDNativeObjectPtr (*classdb_construct_extended)(GDNativeClassConstructor p_constructor, GDNativeExtensionPtr p_extension); + 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); diff --git a/core/object/class_db.cpp b/core/object/class_db.cpp index 05b3dde4ed8a..8ba46e49eb38 100644 --- a/core/object/class_db.cpp +++ b/core/object/class_db.cpp @@ -545,10 +545,12 @@ Object *ClassDB::instantiate(const StringName &p_class) { return ti->creation_func(); } -Object *ClassDB::construct_extended(Object *(*p_create_func)(), ObjectNativeExtension *p_extension) { - initializing_with_extension = true; - initializing_extension = p_extension; - initializing_extension_instance = p_extension->create_instance(p_extension->class_userdata); +Object *ClassDB::construct_object(Object *(*p_create_func)(), ObjectNativeExtension *p_extension) { + if (p_extension) { + initializing_with_extension = true; + initializing_extension = p_extension; + initializing_extension_instance = p_extension->create_instance(p_extension->class_userdata); + } return p_create_func(); } diff --git a/core/object/class_db.h b/core/object/class_db.h index 0ba9d5903c1e..3a1cbf8559b8 100644 --- a/core/object/class_db.h +++ b/core/object/class_db.h @@ -234,7 +234,7 @@ public: static bool is_parent_class(const StringName &p_class, const StringName &p_inherits); static bool can_instantiate(const StringName &p_class); static Object *instantiate(const StringName &p_class); - static Object *construct_extended(Object *(*p_create_func)(), ObjectNativeExtension *p_extension); + static Object *construct_object(Object *(*p_create_func)(), ObjectNativeExtension *p_extension); static void instance_get_native_extension_data(ObjectNativeExtension **r_extension, GDExtensionClassInstancePtr *r_extension_instance, Object *p_base); static APIType get_api_type(const StringName &p_class);