summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--godot-headers/godot/gdnative_interface.h2
-rw-r--r--include/godot_cpp/core/class_db.hpp25
-rw-r--r--test/src/example.h14
-rw-r--r--test/src/register_types.cpp2
4 files changed, 40 insertions, 3 deletions
diff --git a/godot-headers/godot/gdnative_interface.h b/godot-headers/godot/gdnative_interface.h
index 4513c66..1ce50bc 100644
--- a/godot-headers/godot/gdnative_interface.h
+++ b/godot-headers/godot/gdnative_interface.h
@@ -234,6 +234,8 @@ typedef void (*GDNativeExtensionClassFreeInstance)(void *p_userdata, GDExtension
typedef GDNativeExtensionClassCallVirtual (*GDNativeExtensionClassGetVirtual)(void *p_userdata, const char *p_name);
typedef struct {
+ GDNativeBool is_virtual;
+ GDNativeBool is_abstract;
GDNativeExtensionClassSet set_func;
GDNativeExtensionClassGet get_func;
GDNativeExtensionClassGetPropertyList get_property_list_func;
diff --git a/include/godot_cpp/core/class_db.hpp b/include/godot_cpp/core/class_db.hpp
index 0ce4105..514a800 100644
--- a/include/godot_cpp/core/class_db.hpp
+++ b/include/godot_cpp/core/class_db.hpp
@@ -108,9 +108,14 @@ private:
return ret;
}
+ template <class T, bool is_abstract>
+ static void _register_class(bool p_virtual = false);
+
public:
template <class T>
- static void register_class();
+ static void register_class(bool p_virtual = false);
+ template <class T>
+ static void register_abstract_class();
template <class N, class M, typename... VarArgs>
static MethodBind *bind_method(N p_method_name, M p_method, VarArgs... p_args);
@@ -153,8 +158,8 @@ public:
godot::ClassDB::bind_virtual_method(m_class::get_class_static(), #m_method, ___call##m_method); \
}
-template <class T>
-void ClassDB::register_class() {
+template <class T, bool is_abstract>
+void ClassDB::_register_class(bool p_virtual) {
// Register this class within our plugin
ClassInfo cl;
cl.name = T::get_class_static();
@@ -169,6 +174,8 @@ void ClassDB::register_class() {
// Register this class with Godot
GDNativeExtensionClassCreationInfo class_info = {
+ p_virtual, // GDNativeBool is_virtual;
+ is_abstract, // GDNativeBool is_abstract;
T::set_bind, // GDNativeExtensionClassSet set_func;
T::get_bind, // GDNativeExtensionClassGet get_func;
T::get_property_list_bind, // GDNativeExtensionClassGetPropertyList get_property_list_func;
@@ -195,6 +202,16 @@ void ClassDB::register_class() {
initialize_class(classes[cl.name]);
}
+template <class T>
+void ClassDB::register_class(bool p_virtual) {
+ ClassDB::_register_class<T, false>(p_virtual);
+}
+
+template <class T>
+void ClassDB::register_abstract_class() {
+ ClassDB::_register_class<T, true>();
+}
+
template <class N, class M, typename... VarArgs>
MethodBind *ClassDB::bind_method(N p_method_name, M p_method, VarArgs... p_args) {
Variant args[sizeof...(p_args) + 1] = { p_args..., Variant() }; // +1 makes sure zero sized arrays are also supported.
@@ -251,6 +268,8 @@ MethodBind *ClassDB::bind_vararg_method(uint32_t p_flags, const char *p_name, M
}
#define GDREGISTER_CLASS(m_class) ClassDB::register_class<m_class>();
+#define GDREGISTER_VIRTUAL_CLASS(m_class) ClassDB::register_class<m_class>(true);
+#define GDREGISTER_ABSTRACT_CLASS(m_class) ClassDB::register_abstract_class<m_class>();
} // namespace godot
diff --git a/test/src/example.h b/test/src/example.h
index e9565f9..44c1531 100644
--- a/test/src/example.h
+++ b/test/src/example.h
@@ -107,4 +107,18 @@ public:
VARIANT_ENUM_CAST(Example, Constants);
+class ExampleVirtual : public Object {
+ GDCLASS(ExampleVirtual, Object);
+
+protected:
+ static void _bind_methods() {}
+};
+
+class ExampleAbstract : public Object {
+ GDCLASS(ExampleAbstract, Object);
+
+protected:
+ static void _bind_methods() {}
+};
+
#endif // EXAMPLE_CLASS_H
diff --git a/test/src/register_types.cpp b/test/src/register_types.cpp
index 6636d8a..873801b 100644
--- a/test/src/register_types.cpp
+++ b/test/src/register_types.cpp
@@ -24,6 +24,8 @@ void initialize_example_module(ModuleInitializationLevel p_level) {
ClassDB::register_class<ExampleRef>();
ClassDB::register_class<ExampleMin>();
ClassDB::register_class<Example>();
+ ClassDB::register_class<ExampleVirtual>(true);
+ ClassDB::register_abstract_class<ExampleAbstract>();
}
void uninitialize_example_module(ModuleInitializationLevel p_level) {