1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-04 12:00:25 +00:00

Core: Natively convert enum/BitField with Variant

This commit is contained in:
Thaddeus Crews
2025-01-01 11:25:10 -06:00
parent a210fe6dbd
commit 8a93218aab
9 changed files with 95 additions and 591 deletions

View File

@@ -255,19 +255,6 @@ struct PtrToArg<Ref<T>> {
}
};
template <typename T>
struct PtrToArg<const Ref<T> &> {
typedef Ref<T> EncodeT;
_FORCE_INLINE_ static Ref<T> convert(const void *p_ptr) {
if (p_ptr == nullptr) {
return Ref<T>();
}
// p_ptr points to a RefCounted object
return Ref<T>(*((T *const *)p_ptr));
}
};
template <typename T>
struct GetTypeInfo<Ref<T>> {
static const Variant::Type VARIANT_TYPE = Variant::OBJECT;
@@ -278,28 +265,12 @@ struct GetTypeInfo<Ref<T>> {
}
};
template <typename T>
struct GetTypeInfo<const Ref<T> &> {
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 <typename T>
struct VariantInternalAccessor<Ref<T>> {
static _FORCE_INLINE_ Ref<T> get(const Variant *v) { return Ref<T>(*VariantInternal::get_object(v)); }
static _FORCE_INLINE_ void set(Variant *v, const Ref<T> &p_ref) { VariantInternal::object_assign(v, p_ref); }
};
template <typename T>
struct VariantInternalAccessor<const Ref<T> &> {
static _FORCE_INLINE_ Ref<T> get(const Variant *v) { return Ref<T>(*VariantInternal::get_object(v)); }
static _FORCE_INLINE_ void set(Variant *v, const Ref<T> &p_ref) { VariantInternal::object_assign(v, p_ref); }
};
// Zero-constructing Ref initializes reference to nullptr (and thus empty).
template <typename T>
struct is_zero_constructible<Ref<T>> : std::true_type {};

View File

@@ -81,73 +81,8 @@ struct VariantCaster<const T &> {
}
};
#define VARIANT_ENUM_CAST(m_enum) \
MAKE_ENUM_TYPE_INFO(m_enum) \
template <> \
struct VariantCaster<m_enum> { \
static _FORCE_INLINE_ m_enum cast(const Variant &p_variant) { \
return (m_enum)p_variant.operator int64_t(); \
} \
}; \
template <> \
struct PtrToArg<m_enum> { \
_FORCE_INLINE_ static m_enum convert(const void *p_ptr) { \
return m_enum(*reinterpret_cast<const int64_t *>(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<m_enum> { \
static void initialize(m_enum &value) { \
value = (m_enum)0; \
} \
}; \
template <> \
struct VariantInternalAccessor<m_enum> { \
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<BitField<m_enum>> { \
static _FORCE_INLINE_ BitField<m_enum> cast(const Variant &p_variant) { \
return BitField<m_enum>(p_variant.operator int64_t()); \
} \
}; \
template <> \
struct PtrToArg<BitField<m_enum>> { \
_FORCE_INLINE_ static BitField<m_enum> convert(const void *p_ptr) { \
return BitField<m_enum>(*reinterpret_cast<const int64_t *>(p_ptr)); \
} \
typedef int64_t EncodeT; \
_FORCE_INLINE_ static void encode(BitField<m_enum> p_val, const void *p_ptr) { \
*(int64_t *)p_ptr = p_val; \
} \
}; \
template <> \
struct ZeroInitializer<BitField<m_enum>> { \
static void initialize(BitField<m_enum> &value) { \
value = 0; \
} \
}; \
template <> \
struct VariantInternalAccessor<BitField<m_enum>> { \
static _FORCE_INLINE_ BitField<m_enum> get(const Variant *v) { \
return BitField<m_enum>(*VariantInternal::get_int(v)); \
} \
static _FORCE_INLINE_ void set(Variant *v, BitField<m_enum> 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);

View File

@@ -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 <typename T, typename = void>
struct PtrToArg;
template <typename T>
struct PtrToArg {};
struct PtrToArg<T, std::enable_if_t<!std::is_same_v<T, GetSimpleTypeT<T>>>> : PtrToArg<GetSimpleTypeT<T>> {};
#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<const m_type &> { \
_FORCE_INLINE_ static const m_type &convert(const void *p_ptr) { \
return *reinterpret_cast<const m_type *>(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<m_conv>(p_val); \
} \
}; \
template <> \
struct PtrToArg<const m_type &> { \
_FORCE_INLINE_ static m_type convert(const void *p_ptr) { \
return static_cast<m_type>(*reinterpret_cast<const m_conv *>(p_ptr)); \
} \
typedef m_conv EncodeT; \
_FORCE_INLINE_ static void encode(m_type p_val, void *p_ptr) { \
*((m_conv *)p_ptr) = static_cast<m_conv>(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<const m_type &> { \
_FORCE_INLINE_ static const m_type &convert(const void *p_ptr) { \
return *reinterpret_cast<const m_type *>(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 <typename T> \
struct PtrToArg<m_type, std::enable_if_t<m_conditional>> { \
_FORCE_INLINE_ static m_type convert(const void *p_ptr) { \
return static_cast<m_type>(*reinterpret_cast<const m_conv *>(p_ptr)); \
} \
typedef m_conv EncodeT; \
_FORCE_INLINE_ static void encode(m_type p_val, void *p_ptr) { \
*((m_conv *)p_ptr) = static_cast<m_conv>(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<T>);
MAKE_PTRARGCONV_CONDITIONAL(BitField<T>, int64_t, std::is_enum_v<T>);
// This is for Object.
template <typename T>
@@ -221,23 +210,7 @@ struct PtrToArg<ObjectID> {
} \
} \
} \
}; \
template <> \
struct PtrToArg<const Vector<m_type> &> { \
_FORCE_INLINE_ static Vector<m_type> convert(const void *p_ptr) { \
const Vector<m_type> *dvs = reinterpret_cast<const Vector<m_type> *>(p_ptr); \
Vector<m_type> 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<ObjectID> {
} \
} \
} \
}; \
template <> \
struct PtrToArg<const Vector<m_type_alt> &> { \
_FORCE_INLINE_ static Vector<m_type_alt> convert(const void *p_ptr) { \
const Vector<m_type> *dvs = reinterpret_cast<const Vector<m_type> *>(p_ptr); \
Vector<m_type_alt> 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<const Vector<m_type> &> { \
_FORCE_INLINE_ static Vector<m_type> convert(const void *p_ptr) { \
const Array *arr = reinterpret_cast<const Array *>(p_ptr); \
Vector<m_type> 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<const Vector<m_type> &> { \
_FORCE_INLINE_ static Vector<m_type> convert(const void *p_ptr) { \
const Array *arr = reinterpret_cast<const Array *>(p_ptr); \
Vector<m_type> 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<String *>(p_ptr); \
*arr = p_vec; \
} \
}; \
\
template <> \
struct PtrToArg<const m_type &> { \
_FORCE_INLINE_ static m_type convert(const void *p_ptr) { \
m_type s = *reinterpret_cast<const String *>(p_ptr); \
return s; \
} \
}
};
MAKE_STRINGCONV_BY_REFERENCE(IPAddress);
@@ -436,24 +356,3 @@ struct PtrToArg<Vector<Face3>> {
}
}
};
// No EncodeT because direct pointer conversion not possible.
template <>
struct PtrToArg<const Vector<Face3> &> {
_FORCE_INLINE_ static Vector<Face3> convert(const void *p_ptr) {
const Vector<Vector3> *dvs = reinterpret_cast<const Vector<Vector3> *>(p_ptr);
Vector<Face3> 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;
}
};

View File

@@ -30,6 +30,7 @@
#pragma once
#include "core/templates/simple_type.h"
#include "core/typedefs.h"
#include <type_traits>
@@ -60,6 +61,9 @@ enum Metadata {
template <typename T, typename = void>
struct GetTypeInfo;
template <typename T>
struct GetTypeInfo<T, std::enable_if_t<!std::is_same_v<T, GetSimpleTypeT<T>>>> : GetTypeInfo<GetSimpleTypeT<T>> {};
#define MAKE_TYPE_INFO(m_type, m_var_type) \
template <> \
struct GetTypeInfo<m_type> { \
@@ -68,14 +72,6 @@ struct GetTypeInfo;
static inline PropertyInfo get_class_info() { \
return PropertyInfo(VARIANT_TYPE, String()); \
} \
}; \
template <> \
struct GetTypeInfo<const m_type &> { \
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<const m_type &> { \
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<Variant> {
}
};
template <>
struct GetTypeInfo<const Variant &> {
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<m_template<m_type>> { \
@@ -184,14 +163,6 @@ struct GetTypeInfo<const Variant &> {
static inline PropertyInfo get_class_info() { \
return PropertyInfo(VARIANT_TYPE, String()); \
} \
}; \
template <> \
struct GetTypeInfo<const m_template<m_type> &> { \
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<m_impl> { \
struct GetTypeInfo<m_enum> { \
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 <typename T>
inline StringName __constant_get_enum_name(T param, const String &p_constant) {
if constexpr (GetTypeInfo<T>::VARIANT_TYPE == Variant::NIL) {
ERR_PRINT("Missing VARIANT_ENUM_CAST for constant's enum: " + p_constant);
}
return GetTypeInfo<T>::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<T> operator^(const BitField<T> &p_b) const { return BitField<T>(value ^ p_b.value); }
};
template <typename T>
struct is_zero_constructible<BitField<T>> : std::true_type {};
#define TEMPL_MAKE_BITFIELD_TYPE_INFO(m_enum, m_impl) \
#define MAKE_BITFIELD_TYPE_INFO(m_enum) \
template <> \
struct GetTypeInfo<m_impl> { \
struct GetTypeInfo<m_enum> { \
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<BitField<T>> : std::true_type {};
} \
}; \
template <> \
struct GetTypeInfo<BitField<m_impl>> { \
struct GetTypeInfo<BitField<m_enum>> { \
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<BitField<T>> : 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 <typename T>
inline StringName __constant_get_bitfield_name(T param, const String &p_constant) {
if (GetTypeInfo<T>::VARIANT_TYPE == Variant::NIL) {
ERR_PRINT("Missing VARIANT_ENUM_CAST for constant's bitfield: " + p_constant);
}
return GetTypeInfo<BitField<T>>::get_class_info().class_name;
}
#define CLASS_INFO(m_type) (GetTypeInfo<m_type *>::get_class_info())
// No initialization by default, except for scalar types.
template <typename T>
struct ZeroInitializer {
static void initialize(T &value) {} //no initialization by default
static void initialize(T &value) {
if constexpr (std::is_scalar_v<T>) {
value = {};
}
}
};
template <>
struct ZeroInitializer<bool> {
static void initialize(bool &value) { value = false; }
};
template <typename T>
struct ZeroInitializer<T *> {
static void initialize(T *&value) { value = nullptr; }
};
#define ZERO_INITIALIZER_NUMBER(m_type) \
template <> \
struct ZeroInitializer<m_type> { \
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)

View File

@@ -162,14 +162,6 @@ struct PtrToArg<TypedArray<T>> {
}
};
template <typename T>
struct PtrToArg<const TypedArray<T> &> {
typedef Array EncodeT;
_FORCE_INLINE_ static TypedArray<T> convert(const void *p_ptr) {
return TypedArray<T>(*reinterpret_cast<const Array *>(p_ptr));
}
};
template <typename T>
struct GetTypeInfo<TypedArray<T>> {
static const Variant::Type VARIANT_TYPE = Variant::ARRAY;
@@ -179,15 +171,6 @@ struct GetTypeInfo<TypedArray<T>> {
}
};
template <typename T>
struct GetTypeInfo<const TypedArray<T> &> {
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<TypedArray<m_type>> { \
@@ -196,14 +179,6 @@ struct GetTypeInfo<const TypedArray<T> &> {
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<const TypedArray<m_type> &> { \
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)

View File

@@ -91,15 +91,6 @@ struct PtrToArg<TypedDictionary<K, V>> {
}
};
template <typename K, typename V>
struct PtrToArg<const TypedDictionary<K, V> &> {
typedef Dictionary EncodeT;
_FORCE_INLINE_ static TypedDictionary<K, V>
convert(const void *p_ptr) {
return TypedDictionary<K, V>(*reinterpret_cast<const Dictionary *>(p_ptr));
}
};
template <typename K, typename V>
struct GetTypeInfo<TypedDictionary<K, V>> {
static const Variant::Type VARIANT_TYPE = Variant::DICTIONARY;
@@ -109,15 +100,6 @@ struct GetTypeInfo<TypedDictionary<K, V>> {
}
};
template <typename K, typename V>
struct GetTypeInfo<const TypedDictionary<K, V> &> {
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<const TypedDictionary<K, V> &> {
} \
}; \
template <typename T> \
struct GetTypeInfo<const TypedDictionary<T, m_type> &> { \
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 <typename T> \
class TypedDictionary<m_type, T> : public Dictionary { \
public: \
_FORCE_INLINE_ void operator=(const Dictionary &p_dictionary) { \
@@ -205,15 +178,6 @@ struct GetTypeInfo<const TypedDictionary<K, V> &> {
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 <typename T> \
struct GetTypeInfo<const TypedDictionary<m_type, T> &> { \
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<const TypedDictionary<K, V> &> {
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<const TypedDictionary<m_type_key, m_type_value> &> { \
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) \

View File

@@ -2294,14 +2294,6 @@ Variant::operator Vector<StringName>() 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<int> addr = operator Vector<int>();

View File

@@ -65,6 +65,8 @@ class RefCounted;
template <typename T>
class Ref;
template <typename T>
class BitField;
struct PropertyInfo;
struct MethodInfo;
@@ -478,12 +480,13 @@ public:
operator Vector<Variant>() const;
operator Vector<StringName>() const;
// some core type enums to convert to
operator Side() const;
operator Orientation() const;
operator IPAddress() const;
template <typename T, std::enable_if_t<std::is_enum_v<T>, int> = 0>
_FORCE_INLINE_ operator T() const { return static_cast<T>(operator int64_t()); }
template <typename T, std::enable_if_t<std::is_enum_v<T>, int> = 0>
_FORCE_INLINE_ operator BitField<T>() const { return static_cast<T>(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 <typename T, std::enable_if_t<std::is_enum_v<T>, int> = 0>
_FORCE_INLINE_ Variant(T p_enum) :
Variant(static_cast<int64_t>(p_enum)) {}
template <typename T, std::enable_if_t<std::is_enum_v<T>, int> = 0>
_FORCE_INLINE_ Variant(BitField<T> p_bitfield) :
Variant(static_cast<int64_t>(p_bitfield)) {}
// If this changes the table in variant_op must be updated
enum Operator {

View File

@@ -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 <typename T, typename = void>
struct VariantGetInternalPtr;
template <typename T>
struct VariantGetInternalPtr {
};
struct VariantGetInternalPtr<T, std::enable_if_t<!std::is_same_v<T, GetSimpleTypeT<T>>>> : VariantGetInternalPtr<GetSimpleTypeT<T>> {};
template <>
struct VariantGetInternalPtr<bool> {
@@ -537,56 +541,14 @@ struct VariantGetInternalPtr<bool> {
static const bool *get_ptr(const Variant *v) { return VariantInternal::get_bool(v); }
};
template <>
struct VariantGetInternalPtr<int8_t> {
template <typename T>
struct VariantGetInternalPtr<T, std::enable_if_t<std::is_integral_v<T> || std::is_enum_v<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); }
};
template <>
struct VariantGetInternalPtr<uint8_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); }
};
template <>
struct VariantGetInternalPtr<int16_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); }
};
template <>
struct VariantGetInternalPtr<uint16_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); }
};
template <>
struct VariantGetInternalPtr<int32_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); }
};
template <>
struct VariantGetInternalPtr<uint32_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); }
};
template <>
struct VariantGetInternalPtr<int64_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); }
};
template <>
struct VariantGetInternalPtr<uint64_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); }
};
template <>
struct VariantGetInternalPtr<char32_t> {
template <typename T>
struct VariantGetInternalPtr<BitField<T>, std::enable_if_t<std::is_enum_v<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<ObjectID> {
static const int64_t *get_ptr(const Variant *v) { return VariantInternal::get_int(v); }
};
template <>
struct VariantGetInternalPtr<Error> {
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<float> {
static double *get_ptr(Variant *v) { return VariantInternal::get_float(v); }
@@ -820,9 +776,11 @@ struct VariantGetInternalPtr<PackedVector4Array> {
static const PackedVector4Array *get_ptr(const Variant *v) { return VariantInternal::get_vector4_array(v); }
};
template <typename T, typename = void>
struct VariantInternalAccessor;
template <typename T>
struct VariantInternalAccessor {
};
struct VariantInternalAccessor<T, std::enable_if_t<!std::is_same_v<T, GetSimpleTypeT<T>>>> : VariantInternalAccessor<GetSimpleTypeT<T>> {};
template <>
struct VariantInternalAccessor<bool> {
@@ -830,26 +788,17 @@ struct VariantInternalAccessor<bool> {
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<m_type> { \
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 <typename T>
struct VariantInternalAccessor<T, std::enable_if_t<std::is_integral_v<T> || std::is_enum_v<T>>> {
static _FORCE_INLINE_ T get(const Variant *v) { return static_cast<T>(*VariantInternal::get_int(v)); }
static _FORCE_INLINE_ void set(Variant *v, T p_value) { *VariantInternal::get_int(v) = static_cast<int64_t>(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 <typename T>
struct VariantInternalAccessor<BitField<T>, std::enable_if_t<std::is_enum_v<T>>> {
static _FORCE_INLINE_ BitField<T> get(const Variant *v) { return BitField<T>(static_cast<T>(*VariantInternal::get_int(v))); }
static _FORCE_INLINE_ void set(Variant *v, BitField<T> p_value) { *VariantInternal::get_int(v) = static_cast<int64_t>(p_value); }
};
template <>
struct VariantInternalAccessor<ObjectID> {
@@ -1126,47 +1075,7 @@ struct VariantInternalAccessor<Vector<Variant>> {
template <typename T>
struct VariantInitializer {
};
template <>
struct VariantInitializer<bool> {
static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic<bool>(v); }
};
#define INITIALIZER_INT(m_type) \
template <> \
struct VariantInitializer<m_type> { \
static _FORCE_INLINE_ void init(Variant *v) { \
VariantInternal::init_generic<int64_t>(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<double> {
static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic<double>(v); }
};
template <>
struct VariantInitializer<float> {
static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic<double>(v); }
static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic<T>(v); }
};
template <>
@@ -1174,59 +1083,11 @@ struct VariantInitializer<String> {
static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_string(v); }
};
template <>
struct VariantInitializer<Vector2> {
static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic<Vector2>(v); }
};
template <>
struct VariantInitializer<Vector2i> {
static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic<Vector2i>(v); }
};
template <>
struct VariantInitializer<Rect2> {
static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic<Rect2>(v); }
};
template <>
struct VariantInitializer<Rect2i> {
static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic<Rect2i>(v); }
};
template <>
struct VariantInitializer<Vector3> {
static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic<Vector3>(v); }
};
template <>
struct VariantInitializer<Vector3i> {
static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic<Vector3i>(v); }
};
template <>
struct VariantInitializer<Vector4> {
static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic<Vector4>(v); }
};
template <>
struct VariantInitializer<Vector4i> {
static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic<Vector4i>(v); }
};
template <>
struct VariantInitializer<Transform2D> {
static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_transform2d(v); }
};
template <>
struct VariantInitializer<Plane> {
static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic<Plane>(v); }
};
template <>
struct VariantInitializer<Quaternion> {
static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic<Quaternion>(v); }
};
template <>
struct VariantInitializer<AABB> {
static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_aabb(v); }
@@ -1241,16 +1102,12 @@ template <>
struct VariantInitializer<Transform3D> {
static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_transform3d(v); }
};
template <>
struct VariantInitializer<Projection> {
static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_projection(v); }
};
template <>
struct VariantInitializer<Color> {
static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic<Color>(v); }
};
template <>
struct VariantInitializer<StringName> {
static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_string_name(v); }
@@ -1261,11 +1118,6 @@ struct VariantInitializer<NodePath> {
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<Callable> {
static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_callable(v); }
@@ -1341,17 +1193,24 @@ struct VariantInitializer<Object *> {
static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_object(v); }
};
template <typename T, typename = void>
struct VariantDefaultInitializer;
template <typename T>
struct VariantDefaultInitializer {
};
struct VariantDefaultInitializer<T, std::enable_if_t<!std::is_same_v<T, GetSimpleTypeT<T>>>> : VariantDefaultInitializer<GetSimpleTypeT<T>> {};
template <>
struct VariantDefaultInitializer<bool> {
static _FORCE_INLINE_ void init(Variant *v) { *VariantInternal::get_bool(v) = false; }
};
template <>
struct VariantDefaultInitializer<int64_t> {
template <typename T>
struct VariantDefaultInitializer<T, std::enable_if_t<std::is_integral_v<T> || std::is_enum_v<T>>> {
static _FORCE_INLINE_ void init(Variant *v) { *VariantInternal::get_int(v) = 0; }
};
template <typename T>
struct VariantDefaultInitializer<BitField<T>, std::enable_if_t<std::is_enum_v<T>>> {
static _FORCE_INLINE_ void init(Variant *v) { *VariantInternal::get_int(v) = 0; }
};