From 8a93218aabab0ee277427b84d43ce55edfb586eb Mon Sep 17 00:00:00 2001 From: Thaddeus Crews Date: Wed, 1 Jan 2025 11:25:10 -0600 Subject: [PATCH] Core: Natively convert enum/BitField with Variant --- core/object/ref_counted.h | 29 ----- core/variant/binder_common.h | 69 +--------- core/variant/method_ptrcall.h | 157 +++++------------------ core/variant/type_info.h | 104 +++------------ core/variant/typed_array.h | 25 ---- core/variant/typed_dictionary.h | 46 ------- core/variant/variant.cpp | 8 -- core/variant/variant.h | 33 ++--- core/variant/variant_internal.h | 215 ++++++-------------------------- 9 files changed, 95 insertions(+), 591 deletions(-) diff --git a/core/object/ref_counted.h b/core/object/ref_counted.h index 09b0f6a0279..3bd2b06272d 100644 --- a/core/object/ref_counted.h +++ b/core/object/ref_counted.h @@ -255,19 +255,6 @@ struct PtrToArg> { } }; -template -struct PtrToArg &> { - typedef Ref EncodeT; - - _FORCE_INLINE_ static Ref convert(const void *p_ptr) { - if (p_ptr == nullptr) { - return Ref(); - } - // p_ptr points to a RefCounted object - return Ref(*((T *const *)p_ptr)); - } -}; - template struct GetTypeInfo> { static const Variant::Type VARIANT_TYPE = Variant::OBJECT; @@ -278,28 +265,12 @@ struct GetTypeInfo> { } }; -template -struct GetTypeInfo &> { - static const Variant::Type VARIANT_TYPE = Variant::OBJECT; - static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE; - - static inline PropertyInfo get_class_info() { - return PropertyInfo(Variant::OBJECT, String(), PROPERTY_HINT_RESOURCE_TYPE, T::get_class_static()); - } -}; - template struct VariantInternalAccessor> { static _FORCE_INLINE_ Ref get(const Variant *v) { return Ref(*VariantInternal::get_object(v)); } static _FORCE_INLINE_ void set(Variant *v, const Ref &p_ref) { VariantInternal::object_assign(v, p_ref); } }; -template -struct VariantInternalAccessor &> { - static _FORCE_INLINE_ Ref get(const Variant *v) { return Ref(*VariantInternal::get_object(v)); } - static _FORCE_INLINE_ void set(Variant *v, const Ref &p_ref) { VariantInternal::object_assign(v, p_ref); } -}; - // Zero-constructing Ref initializes reference to nullptr (and thus empty). template struct is_zero_constructible> : std::true_type {}; diff --git a/core/variant/binder_common.h b/core/variant/binder_common.h index 1d1a0e8f5e2..fa1917c6c92 100644 --- a/core/variant/binder_common.h +++ b/core/variant/binder_common.h @@ -81,73 +81,8 @@ struct VariantCaster { } }; -#define VARIANT_ENUM_CAST(m_enum) \ - MAKE_ENUM_TYPE_INFO(m_enum) \ - template <> \ - struct VariantCaster { \ - static _FORCE_INLINE_ m_enum cast(const Variant &p_variant) { \ - return (m_enum)p_variant.operator int64_t(); \ - } \ - }; \ - template <> \ - struct PtrToArg { \ - _FORCE_INLINE_ static m_enum convert(const void *p_ptr) { \ - return m_enum(*reinterpret_cast(p_ptr)); \ - } \ - typedef int64_t EncodeT; \ - _FORCE_INLINE_ static void encode(m_enum p_val, const void *p_ptr) { \ - *(int64_t *)p_ptr = (int64_t)p_val; \ - } \ - }; \ - template <> \ - struct ZeroInitializer { \ - static void initialize(m_enum &value) { \ - value = (m_enum)0; \ - } \ - }; \ - template <> \ - struct VariantInternalAccessor { \ - static _FORCE_INLINE_ m_enum get(const Variant *v) { \ - return m_enum(*VariantInternal::get_int(v)); \ - } \ - static _FORCE_INLINE_ void set(Variant *v, m_enum p_value) { \ - *VariantInternal::get_int(v) = (int64_t)p_value; \ - } \ - }; - -#define VARIANT_BITFIELD_CAST(m_enum) \ - MAKE_BITFIELD_TYPE_INFO(m_enum) \ - template <> \ - struct VariantCaster> { \ - static _FORCE_INLINE_ BitField cast(const Variant &p_variant) { \ - return BitField(p_variant.operator int64_t()); \ - } \ - }; \ - template <> \ - struct PtrToArg> { \ - _FORCE_INLINE_ static BitField convert(const void *p_ptr) { \ - return BitField(*reinterpret_cast(p_ptr)); \ - } \ - typedef int64_t EncodeT; \ - _FORCE_INLINE_ static void encode(BitField p_val, const void *p_ptr) { \ - *(int64_t *)p_ptr = p_val; \ - } \ - }; \ - template <> \ - struct ZeroInitializer> { \ - static void initialize(BitField &value) { \ - value = 0; \ - } \ - }; \ - template <> \ - struct VariantInternalAccessor> { \ - static _FORCE_INLINE_ BitField get(const Variant *v) { \ - return BitField(*VariantInternal::get_int(v)); \ - } \ - static _FORCE_INLINE_ void set(Variant *v, BitField p_value) { \ - *VariantInternal::get_int(v) = p_value.operator int64_t(); \ - } \ - }; +#define VARIANT_ENUM_CAST(m_enum) MAKE_ENUM_TYPE_INFO(m_enum) +#define VARIANT_BITFIELD_CAST(m_enum) MAKE_BITFIELD_TYPE_INFO(m_enum) // Object enum casts must go here VARIANT_ENUM_CAST(Object::ConnectFlags); diff --git a/core/variant/method_ptrcall.h b/core/variant/method_ptrcall.h index a839edd2c7f..d7800dc9422 100644 --- a/core/variant/method_ptrcall.h +++ b/core/variant/method_ptrcall.h @@ -31,11 +31,15 @@ #pragma once #include "core/object/object_id.h" +#include "core/templates/simple_type.h" #include "core/typedefs.h" #include "core/variant/variant.h" +template +struct PtrToArg; + template -struct PtrToArg {}; +struct PtrToArg>>> : PtrToArg> {}; #define MAKE_PTRARG(m_type) \ template <> \ @@ -47,17 +51,7 @@ struct PtrToArg {}; _FORCE_INLINE_ static void encode(m_type p_val, void *p_ptr) { \ *((m_type *)p_ptr) = p_val; \ } \ - }; \ - template <> \ - struct PtrToArg { \ - _FORCE_INLINE_ static const m_type &convert(const void *p_ptr) { \ - return *reinterpret_cast(p_ptr); \ - } \ - typedef m_type EncodeT; \ - _FORCE_INLINE_ static void encode(m_type p_val, void *p_ptr) { \ - *((m_type *)p_ptr) = p_val; \ - } \ - } + }; #define MAKE_PTRARGCONV(m_type, m_conv) \ template <> \ @@ -69,17 +63,7 @@ struct PtrToArg {}; _FORCE_INLINE_ static void encode(m_type p_val, void *p_ptr) { \ *((m_conv *)p_ptr) = static_cast(p_val); \ } \ - }; \ - template <> \ - struct PtrToArg { \ - _FORCE_INLINE_ static m_type convert(const void *p_ptr) { \ - return static_cast(*reinterpret_cast(p_ptr)); \ - } \ - typedef m_conv EncodeT; \ - _FORCE_INLINE_ static void encode(m_type p_val, void *p_ptr) { \ - *((m_conv *)p_ptr) = static_cast(p_val); \ - } \ - } + }; #define MAKE_PTRARG_BY_REFERENCE(m_type) \ template <> \ @@ -91,17 +75,19 @@ struct PtrToArg {}; _FORCE_INLINE_ static void encode(const m_type &p_val, void *p_ptr) { \ *((m_type *)p_ptr) = p_val; \ } \ - }; \ - template <> \ - struct PtrToArg { \ - _FORCE_INLINE_ static const m_type &convert(const void *p_ptr) { \ - return *reinterpret_cast(p_ptr); \ - } \ - typedef m_type EncodeT; \ - _FORCE_INLINE_ static void encode(const m_type &p_val, void *p_ptr) { \ - *((m_type *)p_ptr) = p_val; \ - } \ - } + }; + +#define MAKE_PTRARGCONV_CONDITIONAL(m_type, m_conv, m_conditional) \ + template \ + struct PtrToArg> { \ + _FORCE_INLINE_ static m_type convert(const void *p_ptr) { \ + return static_cast(*reinterpret_cast(p_ptr)); \ + } \ + typedef m_conv EncodeT; \ + _FORCE_INLINE_ static void encode(m_type p_val, void *p_ptr) { \ + *((m_conv *)p_ptr) = static_cast(p_val); \ + } \ + }; MAKE_PTRARGCONV(bool, uint8_t); // Integer types. @@ -154,6 +140,9 @@ MAKE_PTRARG(PackedColorArray); MAKE_PTRARG(PackedVector4Array); MAKE_PTRARG_BY_REFERENCE(Variant); +MAKE_PTRARGCONV_CONDITIONAL(T, int64_t, std::is_enum_v); +MAKE_PTRARGCONV_CONDITIONAL(BitField, int64_t, std::is_enum_v); + // This is for Object. template @@ -221,23 +210,7 @@ struct PtrToArg { } \ } \ } \ - }; \ - template <> \ - struct PtrToArg &> { \ - _FORCE_INLINE_ static Vector convert(const void *p_ptr) { \ - const Vector *dvs = reinterpret_cast *>(p_ptr); \ - Vector ret; \ - int len = dvs->size(); \ - ret.resize(len); \ - { \ - const m_type *r = dvs->ptr(); \ - for (int i = 0; i < len; i++) { \ - ret.write[i] = r[i]; \ - } \ - } \ - return ret; \ - } \ - } + }; // No EncodeT because direct pointer conversion not possible. #define MAKE_VECARG_ALT(m_type, m_type_alt) \ @@ -267,23 +240,7 @@ struct PtrToArg { } \ } \ } \ - }; \ - template <> \ - struct PtrToArg &> { \ - _FORCE_INLINE_ static Vector convert(const void *p_ptr) { \ - const Vector *dvs = reinterpret_cast *>(p_ptr); \ - Vector ret; \ - int len = dvs->size(); \ - ret.resize(len); \ - { \ - const m_type *r = dvs->ptr(); \ - for (int i = 0; i < len; i++) { \ - ret.write[i] = r[i]; \ - } \ - } \ - return ret; \ - } \ - } + }; MAKE_VECARG_ALT(String, StringName); @@ -311,20 +268,7 @@ MAKE_VECARG_ALT(String, StringName); (*arr)[i] = p_vec[i]; \ } \ } \ - }; \ - template <> \ - struct PtrToArg &> { \ - _FORCE_INLINE_ static Vector convert(const void *p_ptr) { \ - const Array *arr = reinterpret_cast(p_ptr); \ - Vector ret; \ - int len = arr->size(); \ - ret.resize(len); \ - for (int i = 0; i < len; i++) { \ - ret.write[i] = (*arr)[i]; \ - } \ - return ret; \ - } \ - } + }; MAKE_VECARR(Variant); MAKE_VECARR(RID); @@ -358,23 +302,7 @@ MAKE_VECARR(Plane); } \ } \ } \ - }; \ - template <> \ - struct PtrToArg &> { \ - _FORCE_INLINE_ static Vector convert(const void *p_ptr) { \ - const Array *arr = reinterpret_cast(p_ptr); \ - Vector ret; \ - int len = arr->size(); \ - ret.resize(len); \ - { \ - m_type *w = ret.ptrw(); \ - for (int i = 0; i < len; i++) { \ - w[i] = (*arr)[i]; \ - } \ - } \ - return ret; \ - } \ - } + }; // Special case for IPAddress. @@ -390,15 +318,7 @@ MAKE_VECARR(Plane); String *arr = reinterpret_cast(p_ptr); \ *arr = p_vec; \ } \ - }; \ - \ - template <> \ - struct PtrToArg { \ - _FORCE_INLINE_ static m_type convert(const void *p_ptr) { \ - m_type s = *reinterpret_cast(p_ptr); \ - return s; \ - } \ - } + }; MAKE_STRINGCONV_BY_REFERENCE(IPAddress); @@ -436,24 +356,3 @@ struct PtrToArg> { } } }; - -// No EncodeT because direct pointer conversion not possible. -template <> -struct PtrToArg &> { - _FORCE_INLINE_ static Vector convert(const void *p_ptr) { - const Vector *dvs = reinterpret_cast *>(p_ptr); - Vector ret; - int len = dvs->size() / 3; - ret.resize(len); - { - const Vector3 *r = dvs->ptr(); - Face3 *w = ret.ptrw(); - for (int i = 0; i < len; i++) { - w[i].vertex[0] = r[i * 3 + 0]; - w[i].vertex[1] = r[i * 3 + 1]; - w[i].vertex[2] = r[i * 3 + 2]; - } - } - return ret; - } -}; diff --git a/core/variant/type_info.h b/core/variant/type_info.h index 2781f61da89..145dba94e05 100644 --- a/core/variant/type_info.h +++ b/core/variant/type_info.h @@ -30,6 +30,7 @@ #pragma once +#include "core/templates/simple_type.h" #include "core/typedefs.h" #include @@ -60,6 +61,9 @@ enum Metadata { template struct GetTypeInfo; +template +struct GetTypeInfo>>> : GetTypeInfo> {}; + #define MAKE_TYPE_INFO(m_type, m_var_type) \ template <> \ struct GetTypeInfo { \ @@ -68,14 +72,6 @@ struct GetTypeInfo; static inline PropertyInfo get_class_info() { \ return PropertyInfo(VARIANT_TYPE, String()); \ } \ - }; \ - template <> \ - struct GetTypeInfo { \ - static const Variant::Type VARIANT_TYPE = m_var_type; \ - static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE; \ - static inline PropertyInfo get_class_info() { \ - return PropertyInfo(VARIANT_TYPE, String()); \ - } \ }; #define MAKE_TYPE_INFO_WITH_META(m_type, m_var_type, m_metadata) \ @@ -86,14 +82,6 @@ struct GetTypeInfo; static inline PropertyInfo get_class_info() { \ return PropertyInfo(VARIANT_TYPE, String()); \ } \ - }; \ - template <> \ - struct GetTypeInfo { \ - static const Variant::Type VARIANT_TYPE = m_var_type; \ - static const GodotTypeInfo::Metadata METADATA = m_metadata; \ - static inline PropertyInfo get_class_info() { \ - return PropertyInfo(VARIANT_TYPE, String()); \ - } \ }; MAKE_TYPE_INFO(bool, Variant::BOOL) @@ -167,15 +155,6 @@ struct GetTypeInfo { } }; -template <> -struct GetTypeInfo { - static const Variant::Type VARIANT_TYPE = Variant::NIL; - static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE; - static inline PropertyInfo get_class_info() { - return PropertyInfo(Variant::NIL, String(), PROPERTY_HINT_NONE, String(), PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_NIL_IS_VARIANT); - } -}; - #define MAKE_TEMPLATE_TYPE_INFO(m_template, m_type, m_var_type) \ template <> \ struct GetTypeInfo> { \ @@ -184,14 +163,6 @@ struct GetTypeInfo { static inline PropertyInfo get_class_info() { \ return PropertyInfo(VARIANT_TYPE, String()); \ } \ - }; \ - template <> \ - struct GetTypeInfo &> { \ - static const Variant::Type VARIANT_TYPE = m_var_type; \ - static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE; \ - static inline PropertyInfo get_class_info() { \ - return PropertyInfo(VARIANT_TYPE, String()); \ - } \ }; MAKE_TEMPLATE_TYPE_INFO(Vector, Variant, Variant::ARRAY) @@ -222,9 +193,9 @@ inline String enum_qualified_name_to_class_info_name(const String &p_qualified_n } // namespace Internal } // namespace GodotTypeInfo -#define TEMPL_MAKE_ENUM_TYPE_INFO(m_enum, m_impl) \ +#define MAKE_ENUM_TYPE_INFO(m_enum) \ template <> \ - struct GetTypeInfo { \ + struct GetTypeInfo { \ static const Variant::Type VARIANT_TYPE = Variant::INT; \ static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE; \ static inline PropertyInfo get_class_info() { \ @@ -233,17 +204,8 @@ inline String enum_qualified_name_to_class_info_name(const String &p_qualified_n } \ }; -#define MAKE_ENUM_TYPE_INFO(m_enum) \ - TEMPL_MAKE_ENUM_TYPE_INFO(m_enum, m_enum) \ - TEMPL_MAKE_ENUM_TYPE_INFO(m_enum, m_enum const) \ - TEMPL_MAKE_ENUM_TYPE_INFO(m_enum, m_enum &) \ - TEMPL_MAKE_ENUM_TYPE_INFO(m_enum, const m_enum &) - template inline StringName __constant_get_enum_name(T param, const String &p_constant) { - if constexpr (GetTypeInfo::VARIANT_TYPE == Variant::NIL) { - ERR_PRINT("Missing VARIANT_ENUM_CAST for constant's enum: " + p_constant); - } return GetTypeInfo::get_class_info().class_name; } @@ -264,16 +226,15 @@ public: _FORCE_INLINE_ constexpr BitField(int64_t p_value) { value = p_value; } _FORCE_INLINE_ constexpr BitField(T p_value) { value = (int64_t)p_value; } _FORCE_INLINE_ operator int64_t() const { return value; } - _FORCE_INLINE_ operator Variant() const { return value; } _FORCE_INLINE_ BitField operator^(const BitField &p_b) const { return BitField(value ^ p_b.value); } }; template struct is_zero_constructible> : std::true_type {}; -#define TEMPL_MAKE_BITFIELD_TYPE_INFO(m_enum, m_impl) \ +#define MAKE_BITFIELD_TYPE_INFO(m_enum) \ template <> \ - struct GetTypeInfo { \ + struct GetTypeInfo { \ static const Variant::Type VARIANT_TYPE = Variant::INT; \ static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE; \ static inline PropertyInfo get_class_info() { \ @@ -282,7 +243,7 @@ struct is_zero_constructible> : std::true_type {}; } \ }; \ template <> \ - struct GetTypeInfo> { \ + struct GetTypeInfo> { \ static const Variant::Type VARIANT_TYPE = Variant::INT; \ static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE; \ static inline PropertyInfo get_class_info() { \ @@ -291,53 +252,18 @@ struct is_zero_constructible> : std::true_type {}; } \ }; -#define MAKE_BITFIELD_TYPE_INFO(m_enum) \ - TEMPL_MAKE_BITFIELD_TYPE_INFO(m_enum, m_enum) \ - TEMPL_MAKE_BITFIELD_TYPE_INFO(m_enum, m_enum const) \ - TEMPL_MAKE_BITFIELD_TYPE_INFO(m_enum, m_enum &) \ - TEMPL_MAKE_BITFIELD_TYPE_INFO(m_enum, const m_enum &) - template inline StringName __constant_get_bitfield_name(T param, const String &p_constant) { - if (GetTypeInfo::VARIANT_TYPE == Variant::NIL) { - ERR_PRINT("Missing VARIANT_ENUM_CAST for constant's bitfield: " + p_constant); - } return GetTypeInfo>::get_class_info().class_name; } #define CLASS_INFO(m_type) (GetTypeInfo::get_class_info()) +// No initialization by default, except for scalar types. template struct ZeroInitializer { - static void initialize(T &value) {} //no initialization by default + static void initialize(T &value) { + if constexpr (std::is_scalar_v) { + value = {}; + } + } }; - -template <> -struct ZeroInitializer { - static void initialize(bool &value) { value = false; } -}; - -template -struct ZeroInitializer { - static void initialize(T *&value) { value = nullptr; } -}; - -#define ZERO_INITIALIZER_NUMBER(m_type) \ - template <> \ - struct ZeroInitializer { \ - static void initialize(m_type &value) { \ - value = 0; \ - } \ - }; - -ZERO_INITIALIZER_NUMBER(uint8_t) -ZERO_INITIALIZER_NUMBER(int8_t) -ZERO_INITIALIZER_NUMBER(uint16_t) -ZERO_INITIALIZER_NUMBER(int16_t) -ZERO_INITIALIZER_NUMBER(uint32_t) -ZERO_INITIALIZER_NUMBER(int32_t) -ZERO_INITIALIZER_NUMBER(uint64_t) -ZERO_INITIALIZER_NUMBER(int64_t) -ZERO_INITIALIZER_NUMBER(char16_t) -ZERO_INITIALIZER_NUMBER(char32_t) -ZERO_INITIALIZER_NUMBER(float) -ZERO_INITIALIZER_NUMBER(double) diff --git a/core/variant/typed_array.h b/core/variant/typed_array.h index 639b5f703d5..8e6c83ec283 100644 --- a/core/variant/typed_array.h +++ b/core/variant/typed_array.h @@ -162,14 +162,6 @@ struct PtrToArg> { } }; -template -struct PtrToArg &> { - typedef Array EncodeT; - _FORCE_INLINE_ static TypedArray convert(const void *p_ptr) { - return TypedArray(*reinterpret_cast(p_ptr)); - } -}; - template struct GetTypeInfo> { static const Variant::Type VARIANT_TYPE = Variant::ARRAY; @@ -179,15 +171,6 @@ struct GetTypeInfo> { } }; -template -struct GetTypeInfo &> { - static const Variant::Type VARIANT_TYPE = Variant::ARRAY; - static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE; - static inline PropertyInfo get_class_info() { - return PropertyInfo(Variant::ARRAY, String(), PROPERTY_HINT_ARRAY_TYPE, T::get_class_static()); - } -}; - #define MAKE_TYPED_ARRAY_INFO(m_type, m_variant_type) \ template <> \ struct GetTypeInfo> { \ @@ -196,14 +179,6 @@ struct GetTypeInfo &> { static inline PropertyInfo get_class_info() { \ return PropertyInfo(Variant::ARRAY, String(), PROPERTY_HINT_ARRAY_TYPE, Variant::get_type_name(m_variant_type)); \ } \ - }; \ - template <> \ - struct GetTypeInfo &> { \ - static const Variant::Type VARIANT_TYPE = Variant::ARRAY; \ - static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE; \ - static inline PropertyInfo get_class_info() { \ - return PropertyInfo(Variant::ARRAY, String(), PROPERTY_HINT_ARRAY_TYPE, Variant::get_type_name(m_variant_type)); \ - } \ }; MAKE_TYPED_ARRAY_INFO(bool, Variant::BOOL) diff --git a/core/variant/typed_dictionary.h b/core/variant/typed_dictionary.h index b0df0d3aaa8..e75c8a1b3bb 100644 --- a/core/variant/typed_dictionary.h +++ b/core/variant/typed_dictionary.h @@ -91,15 +91,6 @@ struct PtrToArg> { } }; -template -struct PtrToArg &> { - typedef Dictionary EncodeT; - _FORCE_INLINE_ static TypedDictionary - convert(const void *p_ptr) { - return TypedDictionary(*reinterpret_cast(p_ptr)); - } -}; - template struct GetTypeInfo> { static const Variant::Type VARIANT_TYPE = Variant::DICTIONARY; @@ -109,15 +100,6 @@ struct GetTypeInfo> { } }; -template -struct GetTypeInfo &> { - static const Variant::Type VARIANT_TYPE = Variant::DICTIONARY; - static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE; - static inline PropertyInfo get_class_info() { - return PropertyInfo(Variant::DICTIONARY, String(), PROPERTY_HINT_DICTIONARY_TYPE, vformat("%s;%s", K::get_class_static(), V::get_class_static())); - } -}; - // Specialization for the rest of the Variant types. #define MAKE_TYPED_DICTIONARY_WITH_OBJECT(m_type, m_variant_type) \ @@ -160,15 +142,6 @@ struct GetTypeInfo &> { } \ }; \ template \ - struct GetTypeInfo &> { \ - static const Variant::Type VARIANT_TYPE = Variant::DICTIONARY; \ - static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE; \ - static inline PropertyInfo get_class_info() { \ - return PropertyInfo(Variant::DICTIONARY, String(), PROPERTY_HINT_DICTIONARY_TYPE, \ - vformat("%s;%s", T::get_class_static(), m_variant_type == Variant::NIL ? "Variant" : Variant::get_type_name(m_variant_type))); \ - } \ - }; \ - template \ class TypedDictionary : public Dictionary { \ public: \ _FORCE_INLINE_ void operator=(const Dictionary &p_dictionary) { \ @@ -205,15 +178,6 @@ struct GetTypeInfo &> { return PropertyInfo(Variant::DICTIONARY, String(), PROPERTY_HINT_DICTIONARY_TYPE, \ vformat("%s;%s", m_variant_type == Variant::NIL ? "Variant" : Variant::get_type_name(m_variant_type), T::get_class_static())); \ } \ - }; \ - template \ - struct GetTypeInfo &> { \ - static const Variant::Type VARIANT_TYPE = Variant::DICTIONARY; \ - static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE; \ - static inline PropertyInfo get_class_info() { \ - return PropertyInfo(Variant::DICTIONARY, String(), PROPERTY_HINT_DICTIONARY_TYPE, \ - vformat("%s;%s", m_variant_type == Variant::NIL ? "Variant" : Variant::get_type_name(m_variant_type), T::get_class_static())); \ - } \ }; #define MAKE_TYPED_DICTIONARY_EXPANDED(m_type_key, m_variant_type_key, m_type_value, m_variant_type_value) \ @@ -255,16 +219,6 @@ struct GetTypeInfo &> { vformat("%s;%s", m_variant_type_key == Variant::NIL ? "Variant" : Variant::get_type_name(m_variant_type_key), \ m_variant_type_value == Variant::NIL ? "Variant" : Variant::get_type_name(m_variant_type_value))); \ } \ - }; \ - template <> \ - struct GetTypeInfo &> { \ - static const Variant::Type VARIANT_TYPE = Variant::DICTIONARY; \ - static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE; \ - static inline PropertyInfo get_class_info() { \ - return PropertyInfo(Variant::DICTIONARY, String(), PROPERTY_HINT_DICTIONARY_TYPE, \ - vformat("%s;%s", m_variant_type_key == Variant::NIL ? "Variant" : Variant::get_type_name(m_variant_type_key), \ - m_variant_type_value == Variant::NIL ? "Variant" : Variant::get_type_name(m_variant_type_value))); \ - } \ }; #define MAKE_TYPED_DICTIONARY_NIL(m_type, m_variant_type) \ diff --git a/core/variant/variant.cpp b/core/variant/variant.cpp index c6a7b0d4584..6219c9ff685 100644 --- a/core/variant/variant.cpp +++ b/core/variant/variant.cpp @@ -2294,14 +2294,6 @@ Variant::operator Vector() const { return to; } -Variant::operator Side() const { - return (Side) operator int(); -} - -Variant::operator Orientation() const { - return (Orientation) operator int(); -} - Variant::operator IPAddress() const { if (type == PACKED_FLOAT32_ARRAY || type == PACKED_INT32_ARRAY || type == PACKED_FLOAT64_ARRAY || type == PACKED_INT64_ARRAY || type == PACKED_BYTE_ARRAY) { Vector addr = operator Vector(); diff --git a/core/variant/variant.h b/core/variant/variant.h index 23329072a59..4b247492a81 100644 --- a/core/variant/variant.h +++ b/core/variant/variant.h @@ -65,6 +65,8 @@ class RefCounted; template class Ref; +template +class BitField; struct PropertyInfo; struct MethodInfo; @@ -478,12 +480,13 @@ public: operator Vector() const; operator Vector() const; - // some core type enums to convert to - operator Side() const; - operator Orientation() const; - operator IPAddress() const; + template , int> = 0> + _FORCE_INLINE_ operator T() const { return static_cast(operator int64_t()); } + template , int> = 0> + _FORCE_INLINE_ operator BitField() const { return static_cast(operator int64_t()); } + Object *get_validated_object() const; Object *get_validated_object_with_check(bool &r_previously_freed) const; @@ -547,22 +550,12 @@ public: Variant(const IPAddress &p_address); -#define VARIANT_ENUM_CLASS_CONSTRUCTOR(m_enum) \ - Variant(m_enum p_value) : \ - type(INT) { \ - _data._int = (int64_t)p_value; \ - } - - // Only enum classes that need to be bound need this to be defined. - VARIANT_ENUM_CLASS_CONSTRUCTOR(EulerOrder) - VARIANT_ENUM_CLASS_CONSTRUCTOR(JoyAxis) - VARIANT_ENUM_CLASS_CONSTRUCTOR(JoyButton) - VARIANT_ENUM_CLASS_CONSTRUCTOR(Key) - VARIANT_ENUM_CLASS_CONSTRUCTOR(KeyLocation) - VARIANT_ENUM_CLASS_CONSTRUCTOR(MIDIMessage) - VARIANT_ENUM_CLASS_CONSTRUCTOR(MouseButton) - -#undef VARIANT_ENUM_CLASS_CONSTRUCTOR + template , int> = 0> + _FORCE_INLINE_ Variant(T p_enum) : + Variant(static_cast(p_enum)) {} + template , int> = 0> + _FORCE_INLINE_ Variant(BitField p_bitfield) : + Variant(static_cast(p_bitfield)) {} // If this changes the table in variant_op must be updated enum Operator { diff --git a/core/variant/variant_internal.h b/core/variant/variant_internal.h index bb4b5e9b080..48d13a5199f 100644 --- a/core/variant/variant_internal.h +++ b/core/variant/variant_internal.h @@ -32,6 +32,8 @@ #include "variant.h" +#include "core/templates/simple_type.h" + // For use when you want to access the internal pointer of a Variant directly. // Use with caution. You need to be sure that the type is correct. @@ -527,9 +529,11 @@ public: } }; +template +struct VariantGetInternalPtr; + template -struct VariantGetInternalPtr { -}; +struct VariantGetInternalPtr>>> : VariantGetInternalPtr> {}; template <> struct VariantGetInternalPtr { @@ -537,56 +541,14 @@ struct VariantGetInternalPtr { static const bool *get_ptr(const Variant *v) { return VariantInternal::get_bool(v); } }; -template <> -struct VariantGetInternalPtr { +template +struct VariantGetInternalPtr || std::is_enum_v>> { static int64_t *get_ptr(Variant *v) { return VariantInternal::get_int(v); } static const int64_t *get_ptr(const Variant *v) { return VariantInternal::get_int(v); } }; -template <> -struct VariantGetInternalPtr { - static int64_t *get_ptr(Variant *v) { return VariantInternal::get_int(v); } - static const int64_t *get_ptr(const Variant *v) { return VariantInternal::get_int(v); } -}; - -template <> -struct VariantGetInternalPtr { - static int64_t *get_ptr(Variant *v) { return VariantInternal::get_int(v); } - static const int64_t *get_ptr(const Variant *v) { return VariantInternal::get_int(v); } -}; - -template <> -struct VariantGetInternalPtr { - static int64_t *get_ptr(Variant *v) { return VariantInternal::get_int(v); } - static const int64_t *get_ptr(const Variant *v) { return VariantInternal::get_int(v); } -}; - -template <> -struct VariantGetInternalPtr { - static int64_t *get_ptr(Variant *v) { return VariantInternal::get_int(v); } - static const int64_t *get_ptr(const Variant *v) { return VariantInternal::get_int(v); } -}; - -template <> -struct VariantGetInternalPtr { - static int64_t *get_ptr(Variant *v) { return VariantInternal::get_int(v); } - static const int64_t *get_ptr(const Variant *v) { return VariantInternal::get_int(v); } -}; - -template <> -struct VariantGetInternalPtr { - static int64_t *get_ptr(Variant *v) { return VariantInternal::get_int(v); } - static const int64_t *get_ptr(const Variant *v) { return VariantInternal::get_int(v); } -}; - -template <> -struct VariantGetInternalPtr { - static int64_t *get_ptr(Variant *v) { return VariantInternal::get_int(v); } - static const int64_t *get_ptr(const Variant *v) { return VariantInternal::get_int(v); } -}; - -template <> -struct VariantGetInternalPtr { +template +struct VariantGetInternalPtr, std::enable_if_t>> { static int64_t *get_ptr(Variant *v) { return VariantInternal::get_int(v); } static const int64_t *get_ptr(const Variant *v) { return VariantInternal::get_int(v); } }; @@ -597,12 +559,6 @@ struct VariantGetInternalPtr { static const int64_t *get_ptr(const Variant *v) { return VariantInternal::get_int(v); } }; -template <> -struct VariantGetInternalPtr { - static int64_t *get_ptr(Variant *v) { return VariantInternal::get_int(v); } - static const int64_t *get_ptr(const Variant *v) { return VariantInternal::get_int(v); } -}; - template <> struct VariantGetInternalPtr { static double *get_ptr(Variant *v) { return VariantInternal::get_float(v); } @@ -820,9 +776,11 @@ struct VariantGetInternalPtr { static const PackedVector4Array *get_ptr(const Variant *v) { return VariantInternal::get_vector4_array(v); } }; +template +struct VariantInternalAccessor; + template -struct VariantInternalAccessor { -}; +struct VariantInternalAccessor>>> : VariantInternalAccessor> {}; template <> struct VariantInternalAccessor { @@ -830,26 +788,17 @@ struct VariantInternalAccessor { static _FORCE_INLINE_ void set(Variant *v, bool p_value) { *VariantInternal::get_bool(v) = p_value; } }; -#define VARIANT_ACCESSOR_NUMBER(m_type) \ - template <> \ - struct VariantInternalAccessor { \ - static _FORCE_INLINE_ m_type get(const Variant *v) { \ - return (m_type) * VariantInternal::get_int(v); \ - } \ - static _FORCE_INLINE_ void set(Variant *v, m_type p_value) { \ - *VariantInternal::get_int(v) = p_value; \ - } \ - }; +template +struct VariantInternalAccessor || std::is_enum_v>> { + static _FORCE_INLINE_ T get(const Variant *v) { return static_cast(*VariantInternal::get_int(v)); } + static _FORCE_INLINE_ void set(Variant *v, T p_value) { *VariantInternal::get_int(v) = static_cast(p_value); } +}; -VARIANT_ACCESSOR_NUMBER(int8_t) -VARIANT_ACCESSOR_NUMBER(uint8_t) -VARIANT_ACCESSOR_NUMBER(int16_t) -VARIANT_ACCESSOR_NUMBER(uint16_t) -VARIANT_ACCESSOR_NUMBER(int32_t) -VARIANT_ACCESSOR_NUMBER(uint32_t) -VARIANT_ACCESSOR_NUMBER(int64_t) -VARIANT_ACCESSOR_NUMBER(uint64_t) -VARIANT_ACCESSOR_NUMBER(char32_t) +template +struct VariantInternalAccessor, std::enable_if_t>> { + static _FORCE_INLINE_ BitField get(const Variant *v) { return BitField(static_cast(*VariantInternal::get_int(v))); } + static _FORCE_INLINE_ void set(Variant *v, BitField p_value) { *VariantInternal::get_int(v) = static_cast(p_value); } +}; template <> struct VariantInternalAccessor { @@ -1126,47 +1075,7 @@ struct VariantInternalAccessor> { template struct VariantInitializer { -}; - -template <> -struct VariantInitializer { - static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic(v); } -}; - -#define INITIALIZER_INT(m_type) \ - template <> \ - struct VariantInitializer { \ - static _FORCE_INLINE_ void init(Variant *v) { \ - VariantInternal::init_generic(v); \ - } \ - }; - -INITIALIZER_INT(uint8_t) -INITIALIZER_INT(int8_t) -INITIALIZER_INT(uint16_t) -INITIALIZER_INT(int16_t) -INITIALIZER_INT(uint32_t) -INITIALIZER_INT(int32_t) -INITIALIZER_INT(uint64_t) -INITIALIZER_INT(int64_t) -INITIALIZER_INT(char32_t) -INITIALIZER_INT(Error) -INITIALIZER_INT(ObjectID) -INITIALIZER_INT(Vector2::Axis) -INITIALIZER_INT(Vector2i::Axis) -INITIALIZER_INT(Vector3::Axis) -INITIALIZER_INT(Vector3i::Axis) -INITIALIZER_INT(Vector4::Axis) -INITIALIZER_INT(Vector4i::Axis) - -template <> -struct VariantInitializer { - static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic(v); } -}; - -template <> -struct VariantInitializer { - static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic(v); } + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic(v); } }; template <> @@ -1174,59 +1083,11 @@ struct VariantInitializer { static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_string(v); } }; -template <> -struct VariantInitializer { - static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic(v); } -}; - -template <> -struct VariantInitializer { - static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic(v); } -}; - -template <> -struct VariantInitializer { - static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic(v); } -}; - -template <> -struct VariantInitializer { - static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic(v); } -}; - -template <> -struct VariantInitializer { - static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic(v); } -}; - -template <> -struct VariantInitializer { - static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic(v); } -}; -template <> -struct VariantInitializer { - static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic(v); } -}; - -template <> -struct VariantInitializer { - static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic(v); } -}; template <> struct VariantInitializer { static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_transform2d(v); } }; -template <> -struct VariantInitializer { - static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic(v); } -}; - -template <> -struct VariantInitializer { - static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic(v); } -}; - template <> struct VariantInitializer { static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_aabb(v); } @@ -1241,16 +1102,12 @@ template <> struct VariantInitializer { static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_transform3d(v); } }; + template <> struct VariantInitializer { static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_projection(v); } }; -template <> -struct VariantInitializer { - static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic(v); } -}; - template <> struct VariantInitializer { static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_string_name(v); } @@ -1261,11 +1118,6 @@ struct VariantInitializer { static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_node_path(v); } }; -template <> -struct VariantInitializer<::RID> { - static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic<::RID>(v); } -}; - template <> struct VariantInitializer { static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_callable(v); } @@ -1341,17 +1193,24 @@ struct VariantInitializer { static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_object(v); } }; +template +struct VariantDefaultInitializer; + template -struct VariantDefaultInitializer { -}; +struct VariantDefaultInitializer>>> : VariantDefaultInitializer> {}; template <> struct VariantDefaultInitializer { static _FORCE_INLINE_ void init(Variant *v) { *VariantInternal::get_bool(v) = false; } }; -template <> -struct VariantDefaultInitializer { +template +struct VariantDefaultInitializer || std::is_enum_v>> { + static _FORCE_INLINE_ void init(Variant *v) { *VariantInternal::get_int(v) = 0; } +}; + +template +struct VariantDefaultInitializer, std::enable_if_t>> { static _FORCE_INLINE_ void init(Variant *v) { *VariantInternal::get_int(v) = 0; } };