summaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/godot_cpp/core/binder_common.hpp21
-rw-r--r--include/godot_cpp/core/class_db.hpp5
-rw-r--r--include/godot_cpp/core/type_info.hpp47
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