summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFabio Alessandrelli <fabio.alessandrelli@gmail.com>2021-09-21 03:54:50 +0200
committerFabio Alessandrelli <fabio.alessandrelli@gmail.com>2021-09-22 17:46:08 +0200
commitf724bd1880ba9633e3f2dd530775dc0535d9cc17 (patch)
tree8f8b282fce7a244973769fb9901389e21a431d89
parenta4b80cdad95e251d3066a6798cffc64bbf45a0e2 (diff)
[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.
-rw-r--r--core/extension/gdnative_interface.cpp14
-rw-r--r--core/extension/gdnative_interface.h3
-rw-r--r--core/object/class_db.cpp7
-rw-r--r--core/object/class_db.h1
4 files changed, 25 insertions, 0 deletions
diff --git a/core/extension/gdnative_interface.cpp b/core/extension/gdnative_interface.cpp
index b41f74a4bc..dde8449c3e 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 df735db9b6..6ab9c8aea3 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 8e92340c1e..05b3dde4ed 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 e89c7fffd7..0ba9d5903c 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);