Rework GDCLASS macro to allow pure virtual functions
parent
0ddef6ed96
commit
321c8d2b30
|
@ -42,6 +42,8 @@
|
|||
namespace godot {
|
||||
|
||||
class ClassDB;
|
||||
template <class T>
|
||||
class ClassCreator;
|
||||
|
||||
typedef void GodotObject;
|
||||
|
||||
|
@ -49,6 +51,8 @@ typedef void GodotObject;
|
|||
class Wrapped {
|
||||
friend class GDExtensionBinding;
|
||||
friend void postinitialize_handler(Wrapped *);
|
||||
template <class T>
|
||||
friend class ClassCreator;
|
||||
|
||||
protected:
|
||||
#ifdef HOT_RELOAD_ENABLED
|
||||
|
@ -132,16 +136,41 @@ struct EngineClassRegistration {
|
|||
} // namespace godot
|
||||
|
||||
#ifdef HOT_RELOAD_ENABLED
|
||||
#define _GDCLASS_RECREATE(m_class, m_inherits) \
|
||||
#define _GDCLASS_RECREATE(m_class) \
|
||||
m_class *new_instance = (m_class *)memalloc(sizeof(m_class)); \
|
||||
Wrapped::RecreateInstance recreate_data = { new_instance, obj, Wrapped::recreate_instance }; \
|
||||
Wrapped::recreate_instance = &recreate_data; \
|
||||
memnew_placement(new_instance, m_class); \
|
||||
return new_instance;
|
||||
#else
|
||||
#define _GDCLASS_RECREATE(m_class, m_inherits) return nullptr;
|
||||
#define _GDCLASS_RECREATE(m_class) return nullptr;
|
||||
#endif
|
||||
|
||||
namespace godot {
|
||||
|
||||
template <class T>
|
||||
class ClassCreator {
|
||||
public:
|
||||
static GDExtensionObjectPtr create(void *data) {
|
||||
if constexpr (!std::is_abstract_v<T>) {
|
||||
T *new_object = memnew(T);
|
||||
return new_object->_owner;
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
static GDExtensionClassInstancePtr recreate(void *data, GDExtensionObjectPtr obj) {
|
||||
if constexpr (!std::is_abstract_v<T>) {
|
||||
_GDCLASS_RECREATE(T)
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace godot
|
||||
|
||||
// Use this on top of your own classes.
|
||||
// Note: the trail of `***` is to keep sane diffs in PRs, because clang-format otherwise moves every `\` which makes
|
||||
// every line of the macro different
|
||||
|
@ -226,15 +255,6 @@ public:
|
|||
return m_inherits::get_class_static(); \
|
||||
} \
|
||||
\
|
||||
static GDExtensionObjectPtr create(void *data) { \
|
||||
m_class *new_object = memnew(m_class); \
|
||||
return new_object->_owner; \
|
||||
} \
|
||||
\
|
||||
static GDExtensionClassInstancePtr recreate(void *data, GDExtensionObjectPtr obj) { \
|
||||
_GDCLASS_RECREATE(m_class, m_inherits); \
|
||||
} \
|
||||
\
|
||||
static void notification_bind(GDExtensionClassInstancePtr p_instance, int32_t p_what, GDExtensionBool p_reversed) { \
|
||||
if (p_instance && m_class::_get_notification()) { \
|
||||
if (m_class::_get_notification() != m_inherits::_get_notification()) { \
|
||||
|
|
|
@ -202,9 +202,9 @@ void ClassDB::_register_class(bool p_virtual, bool p_exposed) {
|
|||
T::to_string_bind, // GDExtensionClassToString to_string_func;
|
||||
nullptr, // GDExtensionClassReference reference_func;
|
||||
nullptr, // GDExtensionClassUnreference unreference_func;
|
||||
T::create, // GDExtensionClassCreateInstance create_instance_func; /* this one is mandatory */
|
||||
ClassCreator<T>::create, // GDExtensionClassCreateInstance create_instance_func; /* this one is mandatory */
|
||||
T::free, // GDExtensionClassFreeInstance free_instance_func; /* this one is mandatory */
|
||||
T::recreate, // GDExtensionClassRecreateInstance recreate_instance_func;
|
||||
ClassCreator<T>::recreate, // GDExtensionClassRecreateInstance recreate_instance_func;
|
||||
&ClassDB::get_virtual_func, // GDExtensionClassGetVirtual get_virtual_func;
|
||||
nullptr, // GDExtensionClassGetVirtualCallData get_virtual_call_data_func;
|
||||
nullptr, // GDExtensionClassCallVirtualWithData call_virtual_func;
|
||||
|
|
Loading…
Reference in New Issue