Add support for virtual and abstract classes

pull/883/head
Ricardo Buring 2022-10-15 12:23:36 +02:00
parent 1044251a9e
commit 01960ffc9f
4 changed files with 40 additions and 3 deletions

View File

@ -234,6 +234,8 @@ typedef void (*GDNativeExtensionClassFreeInstance)(void *p_userdata, GDExtension
typedef GDNativeExtensionClassCallVirtual (*GDNativeExtensionClassGetVirtual)(void *p_userdata, const char *p_name); typedef GDNativeExtensionClassCallVirtual (*GDNativeExtensionClassGetVirtual)(void *p_userdata, const char *p_name);
typedef struct { typedef struct {
GDNativeBool is_virtual;
GDNativeBool is_abstract;
GDNativeExtensionClassSet set_func; GDNativeExtensionClassSet set_func;
GDNativeExtensionClassGet get_func; GDNativeExtensionClassGet get_func;
GDNativeExtensionClassGetPropertyList get_property_list_func; GDNativeExtensionClassGetPropertyList get_property_list_func;

View File

@ -108,9 +108,14 @@ private:
return ret; return ret;
} }
template <class T, bool is_abstract>
static void _register_class(bool p_virtual = false);
public: public:
template <class T> 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> template <class N, class M, typename... VarArgs>
static MethodBind *bind_method(N p_method_name, M p_method, VarArgs... p_args); 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); \ godot::ClassDB::bind_virtual_method(m_class::get_class_static(), #m_method, ___call##m_method); \
} }
template <class T> template <class T, bool is_abstract>
void ClassDB::register_class() { void ClassDB::_register_class(bool p_virtual) {
// Register this class within our plugin // Register this class within our plugin
ClassInfo cl; ClassInfo cl;
cl.name = T::get_class_static(); cl.name = T::get_class_static();
@ -169,6 +174,8 @@ void ClassDB::register_class() {
// Register this class with Godot // Register this class with Godot
GDNativeExtensionClassCreationInfo class_info = { GDNativeExtensionClassCreationInfo class_info = {
p_virtual, // GDNativeBool is_virtual;
is_abstract, // GDNativeBool is_abstract;
T::set_bind, // GDNativeExtensionClassSet set_func; T::set_bind, // GDNativeExtensionClassSet set_func;
T::get_bind, // GDNativeExtensionClassGet get_func; T::get_bind, // GDNativeExtensionClassGet get_func;
T::get_property_list_bind, // GDNativeExtensionClassGetPropertyList get_property_list_func; T::get_property_list_bind, // GDNativeExtensionClassGetPropertyList get_property_list_func;
@ -195,6 +202,16 @@ void ClassDB::register_class() {
initialize_class(classes[cl.name]); 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> template <class N, class M, typename... VarArgs>
MethodBind *ClassDB::bind_method(N p_method_name, M p_method, VarArgs... p_args) { 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. 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_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 } // namespace godot

View File

@ -107,4 +107,18 @@ public:
VARIANT_ENUM_CAST(Example, Constants); 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 #endif // EXAMPLE_CLASS_H

View File

@ -24,6 +24,8 @@ void initialize_example_module(ModuleInitializationLevel p_level) {
ClassDB::register_class<ExampleRef>(); ClassDB::register_class<ExampleRef>();
ClassDB::register_class<ExampleMin>(); ClassDB::register_class<ExampleMin>();
ClassDB::register_class<Example>(); ClassDB::register_class<Example>();
ClassDB::register_class<ExampleVirtual>(true);
ClassDB::register_abstract_class<ExampleAbstract>();
} }
void uninitialize_example_module(ModuleInitializationLevel p_level) { void uninitialize_example_module(ModuleInitializationLevel p_level) {