Give compile-time error if registering a class without its own `_bind_methods()` function

(cherry picked from commit ca46ef4d25)
pull/1465/head
David Snopek 2024-04-24 14:26:06 -05:00
parent 897280444b
commit 8aef77a64d
3 changed files with 16 additions and 0 deletions

View File

@ -193,6 +193,7 @@ protected:
\ \
public: \ public: \
typedef m_class self_type; \ typedef m_class self_type; \
typedef m_inherits parent_type; \
\ \
static void initialize_class() { \ static void initialize_class() { \
static bool initialized = false; \ static bool initialized = false; \
@ -359,6 +360,7 @@ private:
private: \ private: \
inline static ::godot::internal::EngineClassRegistration<m_class> _gde_engine_class_registration_helper; \ inline static ::godot::internal::EngineClassRegistration<m_class> _gde_engine_class_registration_helper; \
void operator=(const m_class &p_rval) {} \ void operator=(const m_class &p_rval) {} \
friend class ::godot::ClassDB; \
\ \
protected: \ protected: \
virtual const GDExtensionInstanceBindingCallbacks *_get_bindings_callbacks() const override { \ virtual const GDExtensionInstanceBindingCallbacks *_get_bindings_callbacks() const override { \
@ -368,6 +370,8 @@ protected:
m_class(const char *p_godot_class) : m_inherits(p_godot_class) {} \ m_class(const char *p_godot_class) : m_inherits(p_godot_class) {} \
m_class(GodotObject *p_godot_object) : m_inherits(p_godot_object) {} \ m_class(GodotObject *p_godot_object) : m_inherits(p_godot_object) {} \
\ \
static void _bind_methods() {} \
\
static void (*_get_bind_methods())() { \ static void (*_get_bind_methods())() { \
return nullptr; \ return nullptr; \
} \ } \
@ -410,6 +414,7 @@ protected:
\ \
public: \ public: \
typedef m_class self_type; \ typedef m_class self_type; \
typedef m_inherits parent_type; \
\ \
static void initialize_class() {} \ static void initialize_class() {} \
\ \

View File

@ -198,6 +198,7 @@ public:
template <typename T, bool is_abstract> template <typename T, bool is_abstract>
void ClassDB::_register_class(bool p_virtual, bool p_exposed) { void ClassDB::_register_class(bool p_virtual, bool p_exposed) {
static_assert(TypesAreSame<typename T::self_type, T>::value, "Class not declared properly, please use GDCLASS."); static_assert(TypesAreSame<typename T::self_type, T>::value, "Class not declared properly, please use GDCLASS.");
static_assert(!FunctionsAreSame<T::self_type::_bind_methods, T::parent_type::_bind_methods>::value, "Class must declare 'static void _bind_methods'.");
static_assert(!std::is_abstract_v<T> || is_abstract, "Class is abstract, please use GDREGISTER_ABSTRACT_CLASS."); static_assert(!std::is_abstract_v<T> || is_abstract, "Class is abstract, please use GDREGISTER_ABSTRACT_CLASS.");
instance_binding_callbacks[T::get_class_static()] = &T::_gde_binding_callbacks; instance_binding_callbacks[T::get_class_static()] = &T::_gde_binding_callbacks;

View File

@ -58,6 +58,16 @@ struct TypesAreSame<A, A> {
static bool const value = true; static bool const value = true;
}; };
template <auto A, auto B>
struct FunctionsAreSame {
static bool const value = false;
};
template <auto A>
struct FunctionsAreSame<A, A> {
static bool const value = true;
};
template <typename B, typename D> template <typename B, typename D>
struct TypeInherits { struct TypeInherits {
static D *get_d(); static D *get_d();