diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/godot_cpp/core/binder_common.hpp | 21 | ||||
-rw-r--r-- | include/godot_cpp/core/class_db.hpp | 5 | ||||
-rw-r--r-- | include/godot_cpp/core/type_info.hpp | 47 |
3 files changed, 72 insertions, 1 deletions
diff --git a/include/godot_cpp/core/binder_common.hpp b/include/godot_cpp/core/binder_common.hpp index 927132c..93ed731 100644 --- a/include/godot_cpp/core/binder_common.hpp +++ b/include/godot_cpp/core/binder_common.hpp @@ -62,6 +62,27 @@ namespace godot { }; \ } +#define VARIANT_BITFIELD_CAST(m_class, m_enum) \ + namespace godot { \ + MAKE_BITFIELD_TYPE_INFO(m_class, m_enum) \ + template <> \ + struct VariantCaster<BitField<m_class::m_enum>> { \ + static _FORCE_INLINE_ BitField<m_class::m_enum> cast(const Variant &p_variant) { \ + return BitField<m_class::m_enum>(p_variant.operator int64_t()); \ + } \ + }; \ + template <> \ + struct PtrToArg<BitField<m_class::m_enum>> { \ + _FORCE_INLINE_ static BitField<m_class::m_enum> convert(const void *p_ptr) { \ + return BitField<m_class::m_enum>(*reinterpret_cast<const int64_t *>(p_ptr)); \ + } \ + typedef int64_t EncodeT; \ + _FORCE_INLINE_ static void encode(BitField<m_class::m_enum> p_val, const void *p_ptr) { \ + *(int64_t *)p_ptr = p_val; \ + } \ + }; \ + } + template <class T> struct VariantCaster { static _FORCE_INLINE_ T cast(const Variant &p_variant) { diff --git a/include/godot_cpp/core/class_db.hpp b/include/godot_cpp/core/class_db.hpp index 71005f5..96a9bb3 100644 --- a/include/godot_cpp/core/class_db.hpp +++ b/include/godot_cpp/core/class_db.hpp @@ -116,7 +116,7 @@ public: static void add_property_subgroup(const char *p_class, const char *p_name, const char *p_prefix); static void add_property(const char *p_class, const PropertyInfo &p_pinfo, const char *p_setter, const char *p_getter, int p_index = -1); static void add_signal(const char *p_class, const MethodInfo &p_signal); - static void bind_integer_constant(const char *p_class_name, const char *p_enum_name, const char *p_constant_name, GDNativeInt p_constant_value); + static void bind_integer_constant(const char *p_class_name, const char *p_enum_name, const char *p_constant_name, GDNativeInt p_constant_value, bool p_is_bitfield = false); static void bind_virtual_method(const char *p_class, const char *p_method, GDNativeExtensionClassCallVirtual p_call); static MethodBind *get_method(const char *p_class, const char *p_method); @@ -133,6 +133,9 @@ public: #define BIND_ENUM_CONSTANT(m_constant) \ godot::ClassDB::bind_integer_constant(get_class_static(), godot::__constant_get_enum_name(m_constant, #m_constant), #m_constant, m_constant); +#define BIND_BITFIELD_FLAG(m_constant) \ + godot::ClassDB::bind_integer_constant(get_class_static(), godot::__constant_get_bitfield_name(m_constant, #m_constant), #m_constant, m_constant, true); + #define BIND_VIRTUAL_METHOD(m_class, m_method) \ { \ auto ___call##m_method = [](GDNativeObjectPtr p_instance, const GDNativeTypePtr *p_args, GDNativeTypePtr p_ret) -> void { \ diff --git a/include/godot_cpp/core/type_info.hpp b/include/godot_cpp/core/type_info.hpp index ba847c9..b507e04 100644 --- a/include/godot_cpp/core/type_info.hpp +++ b/include/godot_cpp/core/type_info.hpp @@ -219,6 +219,53 @@ inline const char *__constant_get_enum_name(T param, const char *p_constant) { return GetTypeInfo<T>::get_class_info().class_name; } +template <class T> +class BitField { + uint32_t value = 0; + +public: + _FORCE_INLINE_ void set_flag(T p_flag) { value |= p_flag; } + _FORCE_INLINE_ bool has_flag(T p_flag) const { return value & p_flag; } + _FORCE_INLINE_ void clear_flag(T p_flag) { return value &= ~p_flag; } + _FORCE_INLINE_ BitField(uint32_t p_value) { value = p_value; } + _FORCE_INLINE_ operator uint32_t() const { return value; } + _FORCE_INLINE_ operator Variant() const { return value; } +}; + +#define TEMPL_MAKE_BITFIELD_TYPE_INFO(m_class, m_enum, m_impl) \ + template <> \ + struct GetTypeInfo<m_impl> { \ + static const Variant::Type VARIANT_TYPE = Variant::INT; \ + static const GDNativeExtensionClassMethodArgumentMetadata METADATA = GDNATIVE_EXTENSION_METHOD_ARGUMENT_METADATA_NONE; \ + static inline GDNativePropertyInfo get_class_info() { \ + return PropertyInfo(GDNATIVE_VARIANT_TYPE_INT, "", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_CLASS_IS_BITFIELD, \ + #m_class "." #m_enum); \ + } \ + }; \ + template <> \ + struct GetTypeInfo<BitField<m_impl>> { \ + static const Variant::Type VARIANT_TYPE = Variant::INT; \ + static const GDNativeExtensionClassMethodArgumentMetadata METADATA = GDNATIVE_EXTENSION_METHOD_ARGUMENT_METADATA_NONE; \ + static inline GDNativePropertyInfo get_class_info() { \ + return PropertyInfo(GDNATIVE_VARIANT_TYPE_INT, "", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_CLASS_IS_BITFIELD, \ + #m_class "." #m_enum); \ + } \ + }; + +#define MAKE_BITFIELD_TYPE_INFO(m_class, m_enum) \ + TEMPL_MAKE_BITFIELD_TYPE_INFO(m_class, m_enum, m_enum) \ + TEMPL_MAKE_BITFIELD_TYPE_INFO(m_class, m_enum, m_enum const) \ + TEMPL_MAKE_BITFIELD_TYPE_INFO(m_class, m_enum, m_enum &) \ + TEMPL_MAKE_BITFIELD_TYPE_INFO(m_class, m_enum, const m_enum &) + +template <typename T> +inline const char *__constant_get_bitfield_name(T param, const char *p_constant) { + if (GetTypeInfo<T>::VARIANT_TYPE == Variant::NIL) { + ERR_PRINT(("Missing VARIANT_ENUM_CAST for constant's bitfield: " + String(p_constant)).utf8().get_data()); + } + return GetTypeInfo<BitField<T>>::get_class_info().class_name; +} + #define CLASS_INFO(m_type) (GetTypeInfo<m_type *>::get_class_info()) } // namespace godot |