From 01960ffc9f30eb76bcdd3532141a874d4212e96c Mon Sep 17 00:00:00 2001 From: Ricardo Buring Date: Sat, 15 Oct 2022 12:23:36 +0200 Subject: [PATCH] Add support for virtual and abstract classes --- godot-headers/godot/gdnative_interface.h | 2 ++ include/godot_cpp/core/class_db.hpp | 25 +++++++++++++++++++++--- test/src/example.h | 14 +++++++++++++ test/src/register_types.cpp | 2 ++ 4 files changed, 40 insertions(+), 3 deletions(-) diff --git a/godot-headers/godot/gdnative_interface.h b/godot-headers/godot/gdnative_interface.h index 4513c66a..1ce50bc1 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 0ce4105e..514a8008 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 + static void _register_class(bool p_virtual = false); + public: template - static void register_class(); + static void register_class(bool p_virtual = false); + template + static void register_abstract_class(); template 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 -void ClassDB::register_class() { +template +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 +void ClassDB::register_class(bool p_virtual) { + ClassDB::_register_class(p_virtual); +} + +template +void ClassDB::register_abstract_class() { + ClassDB::_register_class(); +} + template 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(); +#define GDREGISTER_VIRTUAL_CLASS(m_class) ClassDB::register_class(true); +#define GDREGISTER_ABSTRACT_CLASS(m_class) ClassDB::register_abstract_class(); } // namespace godot diff --git a/test/src/example.h b/test/src/example.h index e9565f91..44c1531a 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 6636d8ab..873801b4 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(); ClassDB::register_class(); ClassDB::register_class(); + ClassDB::register_class(true); + ClassDB::register_abstract_class(); } void uninitialize_example_module(ModuleInitializationLevel p_level) {