diff options
Diffstat (limited to 'core/variant')
26 files changed, 3052 insertions, 2301 deletions
diff --git a/core/variant/array.cpp b/core/variant/array.cpp index 09cf785390..8373cbd4e8 100644 --- a/core/variant/array.cpp +++ b/core/variant/array.cpp @@ -203,9 +203,9 @@ Error Array::resize(int p_new_size) { return _p->array.resize(p_new_size); } -void Array::insert(int p_pos, const Variant &p_value) { - ERR_FAIL_COND(!_p->typed.validate(p_value, "insert")); - _p->array.insert(p_pos, p_value); +Error Array::insert(int p_pos, const Variant &p_value) { + ERR_FAIL_COND_V(!_p->typed.validate(p_value, "insert"), ERR_INVALID_PARAMETER); + return _p->array.insert(p_pos, p_value); } void Array::fill(const Variant &p_value) { @@ -535,8 +535,8 @@ void Array::push_front(const Variant &p_value) { Variant Array::pop_back() { if (!_p->array.is_empty()) { - int n = _p->array.size() - 1; - Variant ret = _p->array.get(n); + const int n = _p->array.size() - 1; + const Variant ret = _p->array.get(n); _p->array.resize(n); return ret; } @@ -545,13 +545,38 @@ Variant Array::pop_back() { Variant Array::pop_front() { if (!_p->array.is_empty()) { - Variant ret = _p->array.get(0); + const Variant ret = _p->array.get(0); _p->array.remove(0); return ret; } return Variant(); } +Variant Array::pop_at(int p_pos) { + if (_p->array.is_empty()) { + // Return `null` without printing an error to mimic `pop_back()` and `pop_front()` behavior. + return Variant(); + } + + if (p_pos < 0) { + // Relative offset from the end + p_pos = _p->array.size() + p_pos; + } + + ERR_FAIL_INDEX_V_MSG( + p_pos, + _p->array.size(), + Variant(), + vformat( + "The calculated index %s is out of bounds (the array has %s elements). Leaving the array untouched and returning `null`.", + p_pos, + _p->array.size())); + + const Variant ret = _p->array.get(p_pos); + _p->array.remove(p_pos); + return ret; +} + Variant Array::min() const { Variant minval; for (int i = 0; i < size(); i++) { diff --git a/core/variant/array.h b/core/variant/array.h index 540dcb1f4e..4a1b25c4a9 100644 --- a/core/variant/array.h +++ b/core/variant/array.h @@ -72,7 +72,7 @@ public: void append_array(const Array &p_array); Error resize(int p_new_size); - void insert(int p_pos, const Variant &p_value); + Error insert(int p_pos, const Variant &p_value); void remove(int p_pos); void fill(const Variant &p_value); @@ -97,6 +97,7 @@ public: void push_front(const Variant &p_value); Variant pop_back(); Variant pop_front(); + Variant pop_at(int p_pos); Array duplicate(bool p_deep = false) const; diff --git a/core/variant/binder_common.h b/core/variant/binder_common.h index 830e0a5cbd..3b2c837096 100644 --- a/core/variant/binder_common.h +++ b/core/variant/binder_common.h @@ -31,7 +31,9 @@ #ifndef BINDER_COMMON_H #define BINDER_COMMON_H +#include "core/input/input_enums.h" #include "core/object/object.h" +#include "core/os/keyboard.h" #include "core/templates/list.h" #include "core/templates/simple_type.h" #include "core/typedefs.h" @@ -68,16 +70,17 @@ struct VariantCaster<const T &> { template <> \ struct VariantCaster<m_enum> { \ static _FORCE_INLINE_ m_enum cast(const Variant &p_variant) { \ - return (m_enum)p_variant.operator int(); \ + 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 int *>(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) { \ - *(int *)p_ptr = p_val; \ + *(int64_t *)p_ptr = p_val; \ } \ }; @@ -90,9 +93,18 @@ VARIANT_ENUM_CAST(Error); VARIANT_ENUM_CAST(Side); VARIANT_ENUM_CAST(ClockDirection); VARIANT_ENUM_CAST(Corner); +VARIANT_ENUM_CAST(HatDir); +VARIANT_ENUM_CAST(HatMask); +VARIANT_ENUM_CAST(JoyAxis); +VARIANT_ENUM_CAST(JoyButton); +VARIANT_ENUM_CAST(Key); +VARIANT_ENUM_CAST(KeyModifierMask); +VARIANT_ENUM_CAST(MIDIMessage); +VARIANT_ENUM_CAST(MouseButton); VARIANT_ENUM_CAST(Orientation); VARIANT_ENUM_CAST(HAlign); VARIANT_ENUM_CAST(VAlign); +VARIANT_ENUM_CAST(InlineAlign); VARIANT_ENUM_CAST(PropertyHint); VARIANT_ENUM_CAST(PropertyUsageFlags); VARIANT_ENUM_CAST(Variant::Type); @@ -110,6 +122,7 @@ struct PtrToArg<char32_t> { _FORCE_INLINE_ static char32_t convert(const void *p_ptr) { return char32_t(*reinterpret_cast<const int *>(p_ptr)); } + typedef int64_t EncodeT; _FORCE_INLINE_ static void encode(char32_t p_val, const void *p_ptr) { *(int *)p_ptr = p_val; } diff --git a/core/variant/callable.cpp b/core/variant/callable.cpp index 34b3e3ea35..f487e718f4 100644 --- a/core/variant/callable.cpp +++ b/core/variant/callable.cpp @@ -89,6 +89,10 @@ Callable Callable::unbind(int p_argcount) const { return Callable(memnew(CallableCustomUnbind(*this, p_argcount))); } +bool Callable::is_valid() const { + return get_object() && (is_custom() || get_object()->has_method(get_method())); +} + Object *Callable::get_object() const { if (is_null()) { return nullptr; @@ -403,8 +407,8 @@ Array Signal::get_connections() const { object->get_signal_connection_list(name, &connections); Array arr; - for (List<Object::Connection>::Element *E = connections.front(); E; E = E->next()) { - arr.push_back(E->get()); + for (const Object::Connection &E : connections) { + arr.push_back(E); } return arr; } diff --git a/core/variant/callable.h b/core/variant/callable.h index 20d0804292..52094af3aa 100644 --- a/core/variant/callable.h +++ b/core/variant/callable.h @@ -81,6 +81,7 @@ public: _FORCE_INLINE_ bool is_standard() const { return method != StringName(); } + bool is_valid() const; Callable bind(const Variant **p_arguments, int p_argcount) const; Callable unbind(int p_argcount) const; diff --git a/core/variant/callable_bind.cpp b/core/variant/callable_bind.cpp index 10446a5ec1..56eda6e703 100644 --- a/core/variant/callable_bind.cpp +++ b/core/variant/callable_bind.cpp @@ -169,7 +169,8 @@ CallableCustomUnbind::~CallableCustomUnbind() { } Callable callable_bind(const Callable &p_callable, const Variant &p_arg1) { - return p_callable.bind((const Variant **)&p_arg1, 1); + const Variant *args[1] = { &p_arg1 }; + return p_callable.bind(args, 1); } Callable callable_bind(const Callable &p_callable, const Variant &p_arg1, const Variant &p_arg2) { diff --git a/core/variant/dictionary.cpp b/core/variant/dictionary.cpp index b2f7c6aa0a..07b3a9a675 100644 --- a/core/variant/dictionary.cpp +++ b/core/variant/dictionary.cpp @@ -33,6 +33,11 @@ #include "core/templates/ordered_hash_map.h" #include "core/templates/safe_refcount.h" #include "core/variant/variant.h" +// required in this order by VariantInternal, do not remove this comment. +#include "core/object/class_db.h" +#include "core/object/object.h" +#include "core/variant/type_info.h" +#include "core/variant/variant_internal.h" struct DictionaryPrivate { SafeRefCount refcount; @@ -74,15 +79,32 @@ Variant Dictionary::get_value_at_index(int p_index) const { } Variant &Dictionary::operator[](const Variant &p_key) { - return _p->variant_map[p_key]; + if (p_key.get_type() == Variant::STRING_NAME) { + const StringName *sn = VariantInternal::get_string_name(&p_key); + return _p->variant_map[sn->operator String()]; + } else { + return _p->variant_map[p_key]; + } } const Variant &Dictionary::operator[](const Variant &p_key) const { - return _p->variant_map[p_key]; + if (p_key.get_type() == Variant::STRING_NAME) { + const StringName *sn = VariantInternal::get_string_name(&p_key); + return _p->variant_map[sn->operator String()]; + } else { + return _p->variant_map[p_key]; + } } const Variant *Dictionary::getptr(const Variant &p_key) const { - OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::ConstElement E = ((const OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator> *)&_p->variant_map)->find(p_key); + OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::ConstElement E; + + if (p_key.get_type() == Variant::STRING_NAME) { + const StringName *sn = VariantInternal::get_string_name(&p_key); + E = ((const OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator> *)&_p->variant_map)->find(sn->operator String()); + } else { + E = ((const OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator> *)&_p->variant_map)->find(p_key); + } if (!E) { return nullptr; @@ -91,8 +113,14 @@ const Variant *Dictionary::getptr(const Variant &p_key) const { } Variant *Dictionary::getptr(const Variant &p_key) { - OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E = _p->variant_map.find(p_key); + OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E; + if (p_key.get_type() == Variant::STRING_NAME) { + const StringName *sn = VariantInternal::get_string_name(&p_key); + E = ((OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator> *)&_p->variant_map)->find(sn->operator String()); + } else { + E = ((OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator> *)&_p->variant_map)->find(p_key); + } if (!E) { return nullptr; } @@ -100,7 +128,14 @@ Variant *Dictionary::getptr(const Variant &p_key) { } Variant Dictionary::get_valid(const Variant &p_key) const { - OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::ConstElement E = ((const OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator> *)&_p->variant_map)->find(p_key); + OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::ConstElement E; + + if (p_key.get_type() == Variant::STRING_NAME) { + const StringName *sn = VariantInternal::get_string_name(&p_key); + E = ((const OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator> *)&_p->variant_map)->find(sn->operator String()); + } else { + E = ((const OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator> *)&_p->variant_map)->find(p_key); + } if (!E) { return Variant(); @@ -126,7 +161,12 @@ bool Dictionary::is_empty() const { } bool Dictionary::has(const Variant &p_key) const { - return _p->variant_map.has(p_key); + if (p_key.get_type() == Variant::STRING_NAME) { + const StringName *sn = VariantInternal::get_string_name(&p_key); + return _p->variant_map.has(sn->operator String()); + } else { + return _p->variant_map.has(p_key); + } } bool Dictionary::has_all(const Array &p_keys) const { @@ -139,7 +179,12 @@ bool Dictionary::has_all(const Array &p_keys) const { } bool Dictionary::erase(const Variant &p_key) { - return _p->variant_map.erase(p_key); + if (p_key.get_type() == Variant::STRING_NAME) { + const StringName *sn = VariantInternal::get_string_name(&p_key); + return _p->variant_map.erase(sn->operator String()); + } else { + return _p->variant_map.erase(p_key); + } } bool Dictionary::operator==(const Dictionary &p_dictionary) const { diff --git a/core/variant/method_ptrcall.h b/core/variant/method_ptrcall.h index d4ec5e570c..98304621f2 100644 --- a/core/variant/method_ptrcall.h +++ b/core/variant/method_ptrcall.h @@ -45,6 +45,7 @@ struct PtrToArg {}; _FORCE_INLINE_ static 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; \ } \ @@ -54,6 +55,7 @@ struct PtrToArg {}; _FORCE_INLINE_ static 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; \ } \ @@ -65,6 +67,7 @@ struct PtrToArg {}; _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); \ } \ @@ -74,6 +77,7 @@ struct PtrToArg {}; _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); \ } \ @@ -85,6 +89,7 @@ struct PtrToArg {}; _FORCE_INLINE_ static 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; \ } \ @@ -94,12 +99,13 @@ struct PtrToArg {}; _FORCE_INLINE_ static 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; \ } \ } -MAKE_PTRARG(bool); +MAKE_PTRARGCONV(bool, uint8_t); // Integer types. MAKE_PTRARGCONV(uint8_t, int64_t); MAKE_PTRARGCONV(int8_t, int64_t); @@ -153,7 +159,7 @@ struct PtrToArg<T *> { _FORCE_INLINE_ static T *convert(const void *p_ptr) { return const_cast<T *>(reinterpret_cast<const T *>(p_ptr)); } - + typedef Object *EncodeT; _FORCE_INLINE_ static void encode(T *p_var, void *p_ptr) { *((T **)p_ptr) = p_var; } @@ -164,7 +170,7 @@ struct PtrToArg<const T *> { _FORCE_INLINE_ static const T *convert(const void *p_ptr) { return reinterpret_cast<const T *>(p_ptr); } - + typedef const Object *EncodeT; _FORCE_INLINE_ static void encode(T *p_var, void *p_ptr) { *((T **)p_ptr) = p_var; } @@ -177,7 +183,7 @@ struct PtrToArg<ObjectID> { _FORCE_INLINE_ static const ObjectID convert(const void *p_ptr) { return ObjectID(*reinterpret_cast<const uint64_t *>(p_ptr)); } - + typedef uint64_t EncodeT; _FORCE_INLINE_ static void encode(const ObjectID &p_val, void *p_ptr) { *((uint64_t *)p_ptr) = p_val; } @@ -185,6 +191,7 @@ struct PtrToArg<ObjectID> { // This is for the special cases used by Variant. +// No EncodeT because direct pointer conversion not possible. #define MAKE_VECARG(m_type) \ template <> \ struct PtrToArg<Vector<m_type>> { \ @@ -230,6 +237,7 @@ struct PtrToArg<ObjectID> { } \ } +// No EncodeT because direct pointer conversion not possible. #define MAKE_VECARG_ALT(m_type, m_type_alt) \ template <> \ struct PtrToArg<Vector<m_type_alt>> { \ @@ -279,6 +287,7 @@ MAKE_VECARG_ALT(String, StringName); // For stuff that gets converted to Array vectors. +// No EncodeT because direct pointer conversion not possible. #define MAKE_VECARR(m_type) \ template <> \ struct PtrToArg<Vector<m_type>> { \ @@ -319,6 +328,7 @@ MAKE_VECARR(Variant); MAKE_VECARR(RID); MAKE_VECARR(Plane); +// No EncodeT because direct pointer conversion not possible. #define MAKE_DVECARR(m_type) \ template <> \ struct PtrToArg<Vector<m_type>> { \ @@ -366,6 +376,7 @@ MAKE_VECARR(Plane); // Special case for IPAddress. +// No EncodeT because direct pointer conversion not possible. #define MAKE_STRINGCONV_BY_REFERENCE(m_type) \ template <> \ struct PtrToArg<m_type> { \ @@ -389,6 +400,7 @@ MAKE_VECARR(Plane); MAKE_STRINGCONV_BY_REFERENCE(IPAddress); +// No EncodeT because direct pointer conversion not possible. template <> struct PtrToArg<Vector<Face3>> { _FORCE_INLINE_ static Vector<Face3> convert(const void *p_ptr) { @@ -423,6 +435,7 @@ 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) { diff --git a/core/variant/native_ptr.h b/core/variant/native_ptr.h new file mode 100644 index 0000000000..b4ec0df7d6 --- /dev/null +++ b/core/variant/native_ptr.h @@ -0,0 +1,130 @@ +/*************************************************************************/ +/* native_ptr.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef NATIVE_PTR_H +#define NATIVE_PTR_H + +#include "core/math/audio_frame.h" +#include "core/variant/method_ptrcall.h" +#include "core/variant/type_info.h" + +template <class T> +struct GDNativeConstPtr { + const T *data = nullptr; + GDNativeConstPtr(const T *p_assign) { data = p_assign; } + static const char *get_name() { return "const void"; } + operator const T *() const { return data; } + operator Variant() const { return uint64_t(data); } +}; + +template <class T> +struct GDNativePtr { + T *data = nullptr; + GDNativePtr(T *p_assign) { data = p_assign; } + static const char *get_name() { return "void"; } + operator T *() const { return data; } + operator Variant() const { return uint64_t(data); } +}; + +#define GDVIRTUAL_NATIVE_PTR(m_type) \ + template <> \ + struct GDNativeConstPtr<m_type> { \ + const m_type *data = nullptr; \ + GDNativeConstPtr(const m_type *p_assign) { data = p_assign; } \ + static const char *get_name() { return "const " #m_type; } \ + operator const m_type *() const { return data; } \ + operator Variant() const { return uint64_t(data); } \ + }; \ + template <> \ + struct GDNativePtr<m_type> { \ + m_type *data = nullptr; \ + GDNativePtr(m_type *p_assign) { data = p_assign; } \ + static const char *get_name() { return #m_type; } \ + operator m_type *() const { return data; } \ + operator Variant() const { return uint64_t(data); } \ + }; + +template <class T> +struct GetTypeInfo<GDNativeConstPtr<T>> { + 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::INT, String(), PROPERTY_HINT_INT_IS_POINTER, GDNativeConstPtr<T>::get_name()); + } +}; + +template <class T> +struct GetTypeInfo<GDNativePtr<T>> { + 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::INT, String(), PROPERTY_HINT_INT_IS_POINTER, GDNativePtr<T>::get_name()); + } +}; + +template <class T> +struct PtrToArg<GDNativeConstPtr<T>> { + _FORCE_INLINE_ static GDNativeConstPtr<T> convert(const void *p_ptr) { + return GDNativeConstPtr<T>(reinterpret_cast<const T *>(p_ptr)); + } + typedef const T *EncodeT; + _FORCE_INLINE_ static void encode(GDNativeConstPtr<T> p_val, void *p_ptr) { + *((const T **)p_ptr) = p_val.data; + } +}; +template <class T> +struct PtrToArg<GDNativePtr<T>> { + _FORCE_INLINE_ static GDNativePtr<T> convert(const void *p_ptr) { + return GDNativePtr<T>(reinterpret_cast<const T *>(p_ptr)); + } + typedef T *EncodeT; + _FORCE_INLINE_ static void encode(GDNativePtr<T> p_val, void *p_ptr) { + *((T **)p_ptr) = p_val.data; + } +}; + +GDVIRTUAL_NATIVE_PTR(AudioFrame) +GDVIRTUAL_NATIVE_PTR(bool) +GDVIRTUAL_NATIVE_PTR(char) +GDVIRTUAL_NATIVE_PTR(char16_t) +GDVIRTUAL_NATIVE_PTR(char32_t) +GDVIRTUAL_NATIVE_PTR(wchar_t) +GDVIRTUAL_NATIVE_PTR(uint8_t) +GDVIRTUAL_NATIVE_PTR(int8_t) +GDVIRTUAL_NATIVE_PTR(uint16_t) +GDVIRTUAL_NATIVE_PTR(int16_t) +GDVIRTUAL_NATIVE_PTR(uint32_t) +GDVIRTUAL_NATIVE_PTR(int32_t) +GDVIRTUAL_NATIVE_PTR(int64_t) +GDVIRTUAL_NATIVE_PTR(uint64_t) +GDVIRTUAL_NATIVE_PTR(float) +GDVIRTUAL_NATIVE_PTR(double) + +#endif // NATIVE_PTR_H diff --git a/core/variant/type_info.h b/core/variant/type_info.h index 76cb065d10..b70d29bbac 100644 --- a/core/variant/type_info.h +++ b/core/variant/type_info.h @@ -241,14 +241,27 @@ struct GetTypeInfo<const T *, typename EnableIf<TypeInherits<Object, T>::value>: } }; -#define TEMPL_MAKE_ENUM_TYPE_INFO(m_enum, m_impl) \ - template <> \ - struct GetTypeInfo<m_impl> { \ - static const Variant::Type VARIANT_TYPE = Variant::INT; \ - static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE; \ - static inline PropertyInfo get_class_info() { \ - return PropertyInfo(Variant::INT, String(), PROPERTY_HINT_NONE, String(), PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_CLASS_IS_ENUM, String(#m_enum).replace("::", ".")); \ - } \ +namespace godot { +namespace details { +inline String enum_qualified_name_to_class_info_name(const String &p_qualified_name) { + Vector<String> parts = p_qualified_name.split("::", false); + if (parts.size() <= 2) + return String(".").join(parts); + // Contains namespace. We only want the class and enum names. + return parts[parts.size() - 2] + "." + parts[parts.size() - 1]; +} +} // namespace details +} // namespace godot + +#define TEMPL_MAKE_ENUM_TYPE_INFO(m_enum, m_impl) \ + template <> \ + struct GetTypeInfo<m_impl> { \ + static const Variant::Type VARIANT_TYPE = Variant::INT; \ + static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE; \ + static inline PropertyInfo get_class_info() { \ + return PropertyInfo(Variant::INT, String(), PROPERTY_HINT_NONE, String(), PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_CLASS_IS_ENUM, \ + godot::details::enum_qualified_name_to_class_info_name(String(#m_enum))); \ + } \ }; #define MAKE_ENUM_TYPE_INFO(m_enum) \ diff --git a/core/variant/typed_array.h b/core/variant/typed_array.h index 900dcf7689..2e96f4e445 100644 --- a/core/variant/typed_array.h +++ b/core/variant/typed_array.h @@ -125,7 +125,7 @@ struct PtrToArg<TypedArray<T>> { _FORCE_INLINE_ static TypedArray<T> convert(const void *p_ptr) { return TypedArray<T>(*reinterpret_cast<const Array *>(p_ptr)); } - + typedef Array EncodeT; _FORCE_INLINE_ static void encode(TypedArray<T> p_val, void *p_ptr) { *(Array *)p_ptr = p_val; } @@ -133,13 +133,13 @@ struct PtrToArg<TypedArray<T>> { template <class T> struct PtrToArg<const TypedArray<T> &> { - _FORCE_INLINE_ static TypedArray<T> convert(const void *p_ptr) { + typedef Array EncodeT; + _FORCE_INLINE_ static TypedArray<T> + convert(const void *p_ptr) { return TypedArray<T>(*reinterpret_cast<const Array *>(p_ptr)); } }; -#ifdef DEBUG_METHODS_ENABLED - template <class T> struct GetTypeInfo<TypedArray<T>> { static const Variant::Type VARIANT_TYPE = Variant::ARRAY; @@ -218,6 +218,4 @@ MAKE_TYPED_ARRAY_INFO(Vector<Vector2>, Variant::PACKED_VECTOR2_ARRAY) MAKE_TYPED_ARRAY_INFO(Vector<Vector3>, Variant::PACKED_VECTOR3_ARRAY) MAKE_TYPED_ARRAY_INFO(Vector<Color>, Variant::PACKED_COLOR_ARRAY) -#endif - #endif // TYPED_ARRAY_H diff --git a/core/variant/variant.cpp b/core/variant/variant.cpp index d10f41b833..c5cada674f 100644 --- a/core/variant/variant.cpp +++ b/core/variant/variant.cpp @@ -32,6 +32,7 @@ #include "core/core_string_names.h" #include "core/debugger/engine_debugger.h" +#include "core/io/json.h" #include "core/io/marshalls.h" #include "core/io/resource.h" #include "core/math/math_funcs.h" @@ -1626,9 +1627,9 @@ Variant::operator String() const { String Variant::stringify(List<const void *> &stack) const { switch (type) { case NIL: - return "Null"; + return "null"; case BOOL: - return _data._bool ? "True" : "False"; + return _data._bool ? "true" : "false"; case INT: return itos(_data._int); case FLOAT: @@ -1680,10 +1681,10 @@ String Variant::stringify(List<const void *> &stack) const { Vector<_VariantStrPair> pairs; - for (List<Variant>::Element *E = keys.front(); E; E = E->next()) { + for (const Variant &E : keys) { _VariantStrPair sp; - sp.key = E->get().stringify(stack); - sp.value = d[E->get()].stringify(stack); + sp.key = E.stringify(stack); + sp.value = d[E].stringify(stack); pairs.push_back(sp); } @@ -1698,6 +1699,7 @@ String Variant::stringify(List<const void *> &stack) const { } str += "}"; + stack.erase(d.id()); return str; } break; case PACKED_VECTOR2_ARRAY: { @@ -1801,6 +1803,7 @@ String Variant::stringify(List<const void *> &stack) const { } str += "]"; + stack.erase(arr.id()); return str; } break; @@ -1836,6 +1839,11 @@ String Variant::stringify(List<const void *> &stack) const { return ""; } +String Variant::to_json_string() const { + JSON json; + return json.stringify(*this); +} + Variant::operator Vector2() const { if (type == VECTOR2) { return *reinterpret_cast<const Vector2 *>(_data._mem); @@ -3525,12 +3533,13 @@ void Variant::register_types() { _register_variant_methods(); _register_variant_setters_getters(); _register_variant_constructors(); + _register_variant_destructors(); _register_variant_utility_functions(); } void Variant::unregister_types() { _unregister_variant_operators(); _unregister_variant_methods(); _unregister_variant_setters_getters(); - _unregister_variant_constructors(); + _unregister_variant_destructors(); _unregister_variant_utility_functions(); } diff --git a/core/variant/variant.h b/core/variant/variant.h index 75316da63f..9ec131a1b8 100644 --- a/core/variant/variant.h +++ b/core/variant/variant.h @@ -118,6 +118,11 @@ public: VARIANT_MAX }; + enum { + // Maximum recursion depth allowed when serializing variants. + MAX_RECURSION_DEPTH = 1024, + }; + private: friend struct _VariantCall; friend class VariantInternal; @@ -203,7 +208,7 @@ private: Transform3D *_transform3d; PackedArrayRefBase *packed_array; void *_ptr; //generic pointer - uint8_t _mem[sizeof(ObjData) > (sizeof(real_t) * 4) ? sizeof(ObjData) : (sizeof(real_t) * 4)]; + uint8_t _mem[sizeof(ObjData) > (sizeof(real_t) * 4) ? sizeof(ObjData) : (sizeof(real_t) * 4)]{ 0 }; } _data alignas(8); void reference(const Variant &p_variant); @@ -253,7 +258,7 @@ private: true, //PACKED_COLOR_ARRAY, }; - if (unlikely(needs_deinit[type])) { //make it fast for types that dont need deinit + if (unlikely(needs_deinit[type])) { // Make it fast for types that don't need deinit. _clear_internal(); } type = NIL; @@ -266,6 +271,8 @@ private: static void _register_variant_setters_getters(); static void _unregister_variant_setters_getters(); static void _register_variant_constructors(); + static void _unregister_variant_destructors(); + static void _register_variant_destructors(); static void _unregister_variant_constructors(); static void _register_variant_utility_functions(); static void _unregister_variant_utility_functions(); @@ -499,9 +506,10 @@ public: static bool is_builtin_method_vararg(Variant::Type p_type, const StringName &p_method); static void get_builtin_method_list(Variant::Type p_type, List<StringName> *p_list); static int get_builtin_method_count(Variant::Type p_type); + static uint32_t get_builtin_method_hash(Variant::Type p_type, const StringName &p_method); void call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error); - Variant call(const StringName &p_method, const Variant &p_arg1 = Variant(), const Variant &p_arg2 = Variant(), const Variant &p_arg3 = Variant(), const Variant &p_arg4 = Variant(), const Variant &p_arg5 = Variant()); + Variant call(const StringName &p_method, const Variant &p_arg1 = Variant(), const Variant &p_arg2 = Variant(), const Variant &p_arg3 = Variant(), const Variant &p_arg4 = Variant(), const Variant &p_arg5 = Variant(), const Variant &p_arg6 = Variant(), const Variant &p_arg7 = Variant(), const Variant &p_arg8 = Variant()); static void call_static(Variant::Type p_type, const StringName &p_method, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error); @@ -528,6 +536,14 @@ public: static void get_constructor_list(Type p_type, List<MethodInfo> *r_list); //convenience + /* Destructors */ + + // Only ptrcall is available. + typedef void (*PTRDestructor)(void *base); + + static PTRDestructor get_ptr_destructor(Variant::Type p_type); + static bool has_destructor(Variant::Type p_type); + /* Properties */ void set_named(const StringName &p_member, const Variant &p_value, bool &r_valid); @@ -586,7 +602,7 @@ public: typedef void (*PTRKeyedSetter)(void *base, const void *key, const void *value); typedef void (*PTRKeyedGetter)(const void *base, const void *key, void *value); - typedef bool (*PTRKeyedChecker)(const void *base, const void *key); + typedef uint32_t (*PTRKeyedChecker)(const void *base, const void *key); static PTRKeyedSetter get_member_ptr_keyed_setter(Variant::Type p_type); static PTRKeyedGetter get_member_ptr_keyed_getter(Variant::Type p_type); @@ -631,6 +647,7 @@ public: static bool has_utility_function_return_value(const StringName &p_name); static Variant::Type get_utility_function_return_type(const StringName &p_name); static bool is_utility_function_vararg(const StringName &p_name); + static uint32_t get_utility_function_hash(const StringName &p_name); static void get_utility_function_list(List<StringName> *r_functions); static int get_utility_function_count(); @@ -645,6 +662,7 @@ public: bool hash_compare(const Variant &p_variant) const; bool booleanize() const; String stringify(List<const void *> &stack) const; + String to_json_string() const; void static_assign(const Variant &p_variant); static void get_constants_for_type(Variant::Type p_type, List<StringName> *p_constants); diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp index 05ed35c760..39207df9e7 100644 --- a/core/variant/variant_call.cpp +++ b/core/variant/variant_call.cpp @@ -750,6 +750,42 @@ struct _VariantCall { return 0; } + static PackedInt32Array func_PackedByteArray_decode_s32_array(PackedByteArray *p_instance) { + uint64_t size = p_instance->size(); + const uint8_t *r = p_instance->ptr(); + PackedInt32Array dest; + dest.resize(size / sizeof(int32_t)); + memcpy(dest.ptrw(), r, size); + return dest; + } + + static PackedInt64Array func_PackedByteArray_decode_s64_array(PackedByteArray *p_instance) { + uint64_t size = p_instance->size(); + const uint8_t *r = p_instance->ptr(); + PackedInt64Array dest; + dest.resize(size / sizeof(int64_t)); + memcpy(dest.ptrw(), r, size); + return dest; + } + + static PackedFloat32Array func_PackedByteArray_decode_float_array(PackedByteArray *p_instance) { + uint64_t size = p_instance->size(); + const uint8_t *r = p_instance->ptr(); + PackedFloat32Array dest; + dest.resize(size / sizeof(float)); + memcpy(dest.ptrw(), r, size); + return dest; + } + + static PackedFloat64Array func_PackedByteArray_decode_double_array(PackedByteArray *p_instance) { + uint64_t size = p_instance->size(); + const uint8_t *r = p_instance->ptr(); + PackedFloat64Array dest; + dest.resize(size / sizeof(double)); + memcpy(dest.ptrw(), r, size); + return dest; + } + static void func_PackedByteArray_encode_u8(PackedByteArray *p_instance, int64_t p_offset, int64_t p_value) { uint64_t size = p_instance->size(); ERR_FAIL_COND(p_offset < 0 || p_offset > int64_t(size) - 1); @@ -1088,8 +1124,8 @@ bool Variant::has_builtin_method_return_value(Variant::Type p_type, const String void Variant::get_builtin_method_list(Variant::Type p_type, List<StringName> *p_list) { ERR_FAIL_INDEX(p_type, Variant::VARIANT_MAX); - for (List<StringName>::Element *E = builtin_method_names[p_type].front(); E; E = E->next()) { - p_list->push_back(E->get()); + for (const StringName &E : builtin_method_names[p_type]) { + p_list->push_back(E); } } @@ -1126,6 +1162,25 @@ bool Variant::is_builtin_method_vararg(Variant::Type p_type, const StringName &p return method->is_vararg; } +uint32_t Variant::get_builtin_method_hash(Variant::Type p_type, const StringName &p_method) { + ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, 0); + const VariantBuiltInMethodInfo *method = builtin_method_info[p_type].lookup_ptr(p_method); + ERR_FAIL_COND_V(!method, 0); + uint32_t hash = hash_djb2_one_32(method->is_const); + hash = hash_djb2_one_32(method->is_static, hash); + hash = hash_djb2_one_32(method->is_vararg, hash); + hash = hash_djb2_one_32(method->has_return_type, hash); + if (method->has_return_type) { + hash = hash_djb2_one_32(method->return_type, hash); + } + hash = hash_djb2_one_32(method->argument_count, hash); + for (int i = 0; i < method->argument_count; i++) { + hash = method->get_argument_type(i); + } + + return hash; +} + void Variant::get_method_list(List<MethodInfo> *p_list) const { if (type == OBJECT) { Object *obj = get_validated_object(); @@ -1133,12 +1188,12 @@ void Variant::get_method_list(List<MethodInfo> *p_list) const { obj->get_method_list(p_list); } } else { - for (List<StringName>::Element *E = builtin_method_names[type].front(); E; E = E->next()) { - const VariantBuiltInMethodInfo *method = builtin_method_info[type].lookup_ptr(E->get()); + for (const StringName &E : builtin_method_names[type]) { + const VariantBuiltInMethodInfo *method = builtin_method_info[type].lookup_ptr(E); ERR_CONTINUE(!method); MethodInfo mi; - mi.name = E->get(); + mi.name = E; //return type if (method->has_return_type) { @@ -1366,7 +1421,8 @@ static void _register_variant_builtin_methods() { //bind_method(String, humanize_size, sarray("size"), varray()); bind_method(String, is_absolute_path, sarray(), varray()); - bind_method(String, is_rel_path, sarray(), varray()); + bind_method(String, is_relative_path, sarray(), varray()); + bind_method(String, simplify_path, sarray(), varray()); bind_method(String, get_base_dir, sarray(), varray()); bind_method(String, get_file, sarray(), varray()); bind_method(String, xml_escape, sarray("escape_quotes"), varray(false)); @@ -1380,7 +1436,7 @@ static void _register_variant_builtin_methods() { bind_method(String, validate_node_name, sarray(), varray()); bind_method(String, is_valid_identifier, sarray(), varray()); - bind_method(String, is_valid_integer, sarray(), varray()); + bind_method(String, is_valid_int, sarray(), varray()); bind_method(String, is_valid_float, sarray(), varray()); bind_method(String, is_valid_hex_number, sarray("with_prefix"), varray(false)); bind_method(String, is_valid_html_color, sarray(), varray()); @@ -1446,6 +1502,8 @@ static void _register_variant_builtin_methods() { bind_method(Vector2, clamp, sarray("min", "max"), varray()); bind_method(Vector2, snapped, sarray("step"), varray()); + bind_static_method(Vector2, from_angle, sarray("angle"), varray()); + /* Vector2i */ bind_method(Vector2i, aspect, sarray(), varray()); @@ -1552,6 +1610,7 @@ static void _register_variant_builtin_methods() { bind_method(Quaternion, is_normalized, sarray(), varray()); bind_method(Quaternion, is_equal_approx, sarray("to"), varray()); bind_method(Quaternion, inverse, sarray(), varray()); + bind_method(Quaternion, angle_to, sarray("to"), varray()); bind_method(Quaternion, dot, sarray("with"), varray()); bind_method(Quaternion, slerp, sarray("to", "weight"), varray()); bind_method(Quaternion, slerpni, sarray("to", "weight"), varray()); @@ -1610,6 +1669,7 @@ static void _register_variant_builtin_methods() { bind_method(Callable, is_null, sarray(), varray()); bind_method(Callable, is_custom, sarray(), varray()); bind_method(Callable, is_standard, sarray(), varray()); + bind_method(Callable, is_valid, sarray(), varray()); bind_method(Callable, get_object, sarray(), varray()); bind_method(Callable, get_object_id, sarray(), varray()); bind_method(Callable, get_method, sarray(), varray()); @@ -1652,7 +1712,7 @@ static void _register_variant_builtin_methods() { bind_method(Transform2D, interpolate_with, sarray("xform", "weight"), varray()); bind_method(Transform2D, is_equal_approx, sarray("xform"), varray()); bind_method(Transform2D, set_rotation, sarray("rotation"), varray()); - bind_method(Transform2D, looking_at, sarray("target"), varray(Transform2D())); + bind_method(Transform2D, looking_at, sarray("target"), varray(Vector2())); /* Basis */ @@ -1671,6 +1731,7 @@ static void _register_variant_builtin_methods() { bind_method(Basis, slerp, sarray("to", "weight"), varray()); bind_method(Basis, is_equal_approx, sarray("b"), varray()); bind_method(Basis, get_rotation_quaternion, sarray(), varray()); + bind_static_method(Basis, looking_at, sarray("target", "up"), varray(Vector3(0, 1, 0))); /* AABB */ @@ -1748,6 +1809,7 @@ static void _register_variant_builtin_methods() { bind_method(Array, has, sarray("value"), varray()); bind_method(Array, pop_back, sarray(), varray()); bind_method(Array, pop_front, sarray(), varray()); + bind_method(Array, pop_at, sarray("position"), varray()); bind_method(Array, sort, sarray(), varray()); bind_method(Array, sort_custom, sarray("func"), varray()); bind_method(Array, shuffle, sarray(), varray()); @@ -1803,6 +1865,11 @@ static void _register_variant_builtin_methods() { bind_function(PackedByteArray, decode_var, _VariantCall::func_PackedByteArray_decode_var, sarray("byte_offset", "allow_objects"), varray(false)); bind_function(PackedByteArray, decode_var_size, _VariantCall::func_PackedByteArray_decode_var_size, sarray("byte_offset", "allow_objects"), varray(false)); + bind_function(PackedByteArray, to_int32_array, _VariantCall::func_PackedByteArray_decode_s32_array, sarray(), varray()); + bind_function(PackedByteArray, to_int64_array, _VariantCall::func_PackedByteArray_decode_s64_array, sarray(), varray()); + bind_function(PackedByteArray, to_float32_array, _VariantCall::func_PackedByteArray_decode_float_array, sarray(), varray()); + bind_function(PackedByteArray, to_float64_array, _VariantCall::func_PackedByteArray_decode_double_array, sarray(), varray()); + bind_functionnc(PackedByteArray, encode_u8, _VariantCall::func_PackedByteArray_encode_u8, sarray("byte_offset", "value"), varray()); bind_functionnc(PackedByteArray, encode_s8, _VariantCall::func_PackedByteArray_encode_s8, sarray("byte_offset", "value"), varray()); bind_functionnc(PackedByteArray, encode_u16, _VariantCall::func_PackedByteArray_encode_u16, sarray("byte_offset", "value"), varray()); @@ -1981,7 +2048,7 @@ static void _register_variant_builtin_methods() { _VariantCall::add_variant_constant(Variant::VECTOR3, "ZERO", Vector3(0, 0, 0)); _VariantCall::add_variant_constant(Variant::VECTOR3, "ONE", Vector3(1, 1, 1)); - _VariantCall::add_variant_constant(Variant::VECTOR3, "INF", Vector3(Math_INF, Math_INF, Math_INF)); + _VariantCall::add_variant_constant(Variant::VECTOR3, "INF", Vector3(INFINITY, INFINITY, INFINITY)); _VariantCall::add_variant_constant(Variant::VECTOR3, "LEFT", Vector3(-1, 0, 0)); _VariantCall::add_variant_constant(Variant::VECTOR3, "RIGHT", Vector3(1, 0, 0)); _VariantCall::add_variant_constant(Variant::VECTOR3, "UP", Vector3(0, 1, 0)); @@ -2010,7 +2077,7 @@ static void _register_variant_builtin_methods() { _VariantCall::add_variant_constant(Variant::VECTOR2, "ZERO", Vector2(0, 0)); _VariantCall::add_variant_constant(Variant::VECTOR2, "ONE", Vector2(1, 1)); - _VariantCall::add_variant_constant(Variant::VECTOR2, "INF", Vector2(Math_INF, Math_INF)); + _VariantCall::add_variant_constant(Variant::VECTOR2, "INF", Vector2(INFINITY, INFINITY)); _VariantCall::add_variant_constant(Variant::VECTOR2, "LEFT", Vector2(-1, 0)); _VariantCall::add_variant_constant(Variant::VECTOR2, "RIGHT", Vector2(1, 0)); _VariantCall::add_variant_constant(Variant::VECTOR2, "UP", Vector2(0, -1)); diff --git a/core/variant/variant_construct.cpp b/core/variant/variant_construct.cpp index 9e3ab5897b..a1a2bec369 100644 --- a/core/variant/variant_construct.cpp +++ b/core/variant/variant_construct.cpp @@ -28,543 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "variant.h" - -#include "core/core_string_names.h" -#include "core/crypto/crypto_core.h" -#include "core/debugger/engine_debugger.h" -#include "core/io/compression.h" -#include "core/object/class_db.h" -#include "core/os/os.h" -#include "core/templates/local_vector.h" -#include "core/templates/oa_hash_map.h" - -template <class T> -struct PtrConstruct {}; - -#define MAKE_PTRCONSTRUCT(m_type) \ - template <> \ - struct PtrConstruct<m_type> { \ - _FORCE_INLINE_ static void construct(const m_type &p_value, void *p_ptr) { \ - memnew_placement(p_ptr, m_type(p_value)); \ - } \ - }; - -MAKE_PTRCONSTRUCT(bool); -MAKE_PTRCONSTRUCT(int64_t); -MAKE_PTRCONSTRUCT(double); -MAKE_PTRCONSTRUCT(String); -MAKE_PTRCONSTRUCT(Vector2); -MAKE_PTRCONSTRUCT(Vector2i); -MAKE_PTRCONSTRUCT(Rect2); -MAKE_PTRCONSTRUCT(Rect2i); -MAKE_PTRCONSTRUCT(Vector3); -MAKE_PTRCONSTRUCT(Vector3i); -MAKE_PTRCONSTRUCT(Transform2D); -MAKE_PTRCONSTRUCT(Plane); -MAKE_PTRCONSTRUCT(Quaternion); -MAKE_PTRCONSTRUCT(AABB); -MAKE_PTRCONSTRUCT(Basis); -MAKE_PTRCONSTRUCT(Transform3D); -MAKE_PTRCONSTRUCT(Color); -MAKE_PTRCONSTRUCT(StringName); -MAKE_PTRCONSTRUCT(NodePath); -MAKE_PTRCONSTRUCT(RID); - -template <> -struct PtrConstruct<Object *> { - _FORCE_INLINE_ static void construct(Object *p_value, void *p_ptr) { - *((Object **)p_ptr) = p_value; - } -}; - -MAKE_PTRCONSTRUCT(Callable); -MAKE_PTRCONSTRUCT(Signal); -MAKE_PTRCONSTRUCT(Dictionary); -MAKE_PTRCONSTRUCT(Array); -MAKE_PTRCONSTRUCT(PackedByteArray); -MAKE_PTRCONSTRUCT(PackedInt32Array); -MAKE_PTRCONSTRUCT(PackedInt64Array); -MAKE_PTRCONSTRUCT(PackedFloat32Array); -MAKE_PTRCONSTRUCT(PackedFloat64Array); -MAKE_PTRCONSTRUCT(PackedStringArray); -MAKE_PTRCONSTRUCT(PackedVector2Array); -MAKE_PTRCONSTRUCT(PackedVector3Array); -MAKE_PTRCONSTRUCT(PackedColorArray); -MAKE_PTRCONSTRUCT(Variant); - -template <class T, class... P> -class VariantConstructor { - template <size_t... Is> - static _FORCE_INLINE_ void construct_helper(T &base, const Variant **p_args, Callable::CallError &r_error, IndexSequence<Is...>) { - r_error.error = Callable::CallError::CALL_OK; - -#ifdef DEBUG_METHODS_ENABLED - base = T(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...); -#else - base = T(VariantCaster<P>::cast(*p_args[Is])...); -#endif - } - - template <size_t... Is> - static _FORCE_INLINE_ void validated_construct_helper(T &base, const Variant **p_args, IndexSequence<Is...>) { - base = T((*VariantGetInternalPtr<P>::get_ptr(p_args[Is]))...); - } - - template <size_t... Is> - static _FORCE_INLINE_ void ptr_construct_helper(void *base, const void **p_args, IndexSequence<Is...>) { - PtrConstruct<T>::construct(T(PtrToArg<P>::convert(p_args[Is])...), base); - } - -public: - static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { - r_error.error = Callable::CallError::CALL_OK; - VariantTypeChanger<T>::change(&r_ret); - construct_helper(*VariantGetInternalPtr<T>::get_ptr(&r_ret), p_args, r_error, BuildIndexSequence<sizeof...(P)>{}); - } - - static void validated_construct(Variant *r_ret, const Variant **p_args) { - VariantTypeChanger<T>::change(r_ret); - validated_construct_helper(*VariantGetInternalPtr<T>::get_ptr(r_ret), p_args, BuildIndexSequence<sizeof...(P)>{}); - } - static void ptr_construct(void *base, const void **p_args) { - ptr_construct_helper(base, p_args, BuildIndexSequence<sizeof...(P)>{}); - } - - static int get_argument_count() { - return sizeof...(P); - } - - static Variant::Type get_argument_type(int p_arg) { - return call_get_argument_type<P...>(p_arg); - } - - static Variant::Type get_base_type() { - return GetTypeInfo<T>::VARIANT_TYPE; - } -}; - -class VariantConstructorObject { -public: - static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { - VariantInternal::clear(&r_ret); - if (p_args[0]->get_type() == Variant::NIL) { - VariantInternal::object_assign_null(&r_ret); - r_error.error = Callable::CallError::CALL_OK; - } else if (p_args[0]->get_type() == Variant::OBJECT) { - VariantInternal::object_assign(&r_ret, p_args[0]); - r_error.error = Callable::CallError::CALL_OK; - } else { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument = 0; - r_error.expected = Variant::OBJECT; - } - } - - static void validated_construct(Variant *r_ret, const Variant **p_args) { - VariantInternal::clear(r_ret); - VariantInternal::object_assign(r_ret, p_args[0]); - } - static void ptr_construct(void *base, const void **p_args) { - PtrConstruct<Object *>::construct(PtrToArg<Object *>::convert(p_args[0]), base); - } - - static int get_argument_count() { - return 1; - } - - static Variant::Type get_argument_type(int p_arg) { - return Variant::OBJECT; - } - - static Variant::Type get_base_type() { - return Variant::OBJECT; - } -}; - -class VariantConstructorNilObject { -public: - static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { - if (p_args[0]->get_type() != Variant::NIL) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument = 0; - r_error.expected = Variant::NIL; - } - - VariantInternal::clear(&r_ret); - VariantInternal::object_assign_null(&r_ret); - } - - static void validated_construct(Variant *r_ret, const Variant **p_args) { - VariantInternal::clear(r_ret); - VariantInternal::object_assign_null(r_ret); - } - static void ptr_construct(void *base, const void **p_args) { - PtrConstruct<Object *>::construct(nullptr, base); - } - - static int get_argument_count() { - return 1; - } - - static Variant::Type get_argument_type(int p_arg) { - return Variant::NIL; - } - - static Variant::Type get_base_type() { - return Variant::OBJECT; - } -}; - -class VariantConstructorCallableArgs { -public: - static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { - ObjectID object_id; - StringName method; - - if (p_args[0]->get_type() == Variant::NIL) { - // leave as is - } else if (p_args[0]->get_type() == Variant::OBJECT) { - object_id = VariantInternal::get_object_id(p_args[0]); - } else { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument = 0; - r_error.expected = Variant::OBJECT; - return; - } - - if (p_args[1]->get_type() == Variant::STRING_NAME) { - method = *VariantGetInternalPtr<StringName>::get_ptr(p_args[1]); - } else if (p_args[1]->get_type() == Variant::STRING) { - method = *VariantGetInternalPtr<String>::get_ptr(p_args[1]); - } else { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument = 1; - r_error.expected = Variant::STRING_NAME; - return; - } - - VariantTypeChanger<Callable>::change(&r_ret); - *VariantGetInternalPtr<Callable>::get_ptr(&r_ret) = Callable(object_id, method); - } - - static void validated_construct(Variant *r_ret, const Variant **p_args) { - VariantTypeChanger<Callable>::change(r_ret); - *VariantGetInternalPtr<Callable>::get_ptr(r_ret) = Callable(VariantInternal::get_object_id(p_args[0]), *VariantGetInternalPtr<StringName>::get_ptr(p_args[1])); - } - static void ptr_construct(void *base, const void **p_args) { - PtrConstruct<Callable>::construct(Callable(PtrToArg<Object *>::convert(p_args[0]), PtrToArg<StringName>::convert(p_args[1])), base); - } - - static int get_argument_count() { - return 2; - } - - static Variant::Type get_argument_type(int p_arg) { - if (p_arg == 0) { - return Variant::OBJECT; - } else { - return Variant::STRING_NAME; - } - } - - static Variant::Type get_base_type() { - return Variant::CALLABLE; - } -}; - -class VariantConstructorSignalArgs { -public: - static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { - ObjectID object_id; - StringName method; - - if (p_args[0]->get_type() == Variant::NIL) { - // leave as is - } else if (p_args[0]->get_type() == Variant::OBJECT) { - object_id = VariantInternal::get_object_id(p_args[0]); - } else { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument = 0; - r_error.expected = Variant::OBJECT; - return; - } - - if (p_args[1]->get_type() == Variant::STRING_NAME) { - method = *VariantGetInternalPtr<StringName>::get_ptr(p_args[1]); - } else if (p_args[1]->get_type() == Variant::STRING) { - method = *VariantGetInternalPtr<String>::get_ptr(p_args[1]); - } else { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument = 1; - r_error.expected = Variant::STRING_NAME; - return; - } - - VariantTypeChanger<Signal>::change(&r_ret); - *VariantGetInternalPtr<Signal>::get_ptr(&r_ret) = Signal(object_id, method); - } - - static void validated_construct(Variant *r_ret, const Variant **p_args) { - VariantTypeChanger<Signal>::change(r_ret); - *VariantGetInternalPtr<Signal>::get_ptr(r_ret) = Signal(VariantInternal::get_object_id(p_args[0]), *VariantGetInternalPtr<StringName>::get_ptr(p_args[1])); - } - static void ptr_construct(void *base, const void **p_args) { - PtrConstruct<Signal>::construct(Signal(PtrToArg<Object *>::convert(p_args[0]), PtrToArg<StringName>::convert(p_args[1])), base); - } - - static int get_argument_count() { - return 2; - } - - static Variant::Type get_argument_type(int p_arg) { - if (p_arg == 0) { - return Variant::OBJECT; - } else { - return Variant::STRING_NAME; - } - } - - static Variant::Type get_base_type() { - return Variant::SIGNAL; - } -}; - -template <class T> -class VariantConstructorToArray { -public: - static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { - if (p_args[0]->get_type() != GetTypeInfo<T>::VARIANT_TYPE) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument = 0; - r_error.expected = GetTypeInfo<T>::VARIANT_TYPE; - return; - } - - VariantTypeChanger<Array>::change(&r_ret); - Array &dst_arr = *VariantGetInternalPtr<Array>::get_ptr(&r_ret); - const T &src_arr = *VariantGetInternalPtr<T>::get_ptr(p_args[0]); - - int size = src_arr.size(); - dst_arr.resize(size); - for (int i = 0; i < size; i++) { - dst_arr[i] = src_arr[i]; - } - } - - static void validated_construct(Variant *r_ret, const Variant **p_args) { - VariantTypeChanger<Array>::change(r_ret); - Array &dst_arr = *VariantGetInternalPtr<Array>::get_ptr(r_ret); - const T &src_arr = *VariantGetInternalPtr<T>::get_ptr(p_args[0]); - - int size = src_arr.size(); - dst_arr.resize(size); - for (int i = 0; i < size; i++) { - dst_arr[i] = src_arr[i]; - } - } - static void ptr_construct(void *base, const void **p_args) { - Array dst_arr; - T src_arr = PtrToArg<T>::convert(p_args[0]); - - int size = src_arr.size(); - dst_arr.resize(size); - for (int i = 0; i < size; i++) { - dst_arr[i] = src_arr[i]; - } - - PtrConstruct<Array>::construct(dst_arr, base); - } - - static int get_argument_count() { - return 1; - } - - static Variant::Type get_argument_type(int p_arg) { - return GetTypeInfo<T>::VARIANT_TYPE; - } - - static Variant::Type get_base_type() { - return Variant::ARRAY; - } -}; - -template <class T> -class VariantConstructorFromArray { -public: - static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { - if (p_args[0]->get_type() != Variant::ARRAY) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument = 0; - r_error.expected = Variant::ARRAY; - return; - } - - VariantTypeChanger<T>::change(&r_ret); - const Array &src_arr = *VariantGetInternalPtr<Array>::get_ptr(p_args[0]); - T &dst_arr = *VariantGetInternalPtr<T>::get_ptr(&r_ret); - - int size = src_arr.size(); - dst_arr.resize(size); - for (int i = 0; i < size; i++) { - dst_arr.write[i] = src_arr[i]; - } - } - - static void validated_construct(Variant *r_ret, const Variant **p_args) { - VariantTypeChanger<T>::change(r_ret); - const Array &src_arr = *VariantGetInternalPtr<Array>::get_ptr(p_args[0]); - T &dst_arr = *VariantGetInternalPtr<T>::get_ptr(r_ret); - - int size = src_arr.size(); - dst_arr.resize(size); - for (int i = 0; i < size; i++) { - dst_arr.write[i] = src_arr[i]; - } - } - static void ptr_construct(void *base, const void **p_args) { - Array src_arr = PtrToArg<Array>::convert(p_args[0]); - T dst_arr; - - int size = src_arr.size(); - dst_arr.resize(size); - for (int i = 0; i < size; i++) { - dst_arr.write[i] = src_arr[i]; - } - - PtrConstruct<T>::construct(dst_arr, base); - } - - static int get_argument_count() { - return 1; - } - - static Variant::Type get_argument_type(int p_arg) { - return Variant::ARRAY; - } - - static Variant::Type get_base_type() { - return GetTypeInfo<T>::VARIANT_TYPE; - } -}; - -class VariantConstructorNil { -public: - static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { - if (p_args[0]->get_type() != Variant::NIL) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument = 0; - r_error.expected = Variant::NIL; - return; - } - - r_error.error = Callable::CallError::CALL_OK; - VariantInternal::clear(&r_ret); - } - - static void validated_construct(Variant *r_ret, const Variant **p_args) { - VariantInternal::clear(r_ret); - } - static void ptr_construct(void *base, const void **p_args) { - PtrConstruct<Variant>::construct(Variant(), base); - } - - static int get_argument_count() { - return 1; - } - - static Variant::Type get_argument_type(int p_arg) { - return Variant::NIL; - } - - static Variant::Type get_base_type() { - return Variant::NIL; - } -}; - -template <class T> -class VariantConstructNoArgs { -public: - static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { - VariantTypeChanger<T>::change_and_reset(&r_ret); - r_error.error = Callable::CallError::CALL_OK; - } - - static void validated_construct(Variant *r_ret, const Variant **p_args) { - VariantTypeChanger<T>::change_and_reset(r_ret); - } - static void ptr_construct(void *base, const void **p_args) { - PtrConstruct<T>::construct(T(), base); - } - - static int get_argument_count() { - return 0; - } - - static Variant::Type get_argument_type(int p_arg) { - return Variant::NIL; - } - - static Variant::Type get_base_type() { - return GetTypeInfo<T>::VARIANT_TYPE; - } -}; - -class VariantConstructNoArgsNil { -public: - static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { - VariantInternal::clear(&r_ret); - r_error.error = Callable::CallError::CALL_OK; - } - - static void validated_construct(Variant *r_ret, const Variant **p_args) { - VariantInternal::clear(r_ret); - } - static void ptr_construct(void *base, const void **p_args) { - ERR_FAIL_MSG("can't ptrcall nil constructor"); - } - - static int get_argument_count() { - return 0; - } - - static Variant::Type get_argument_type(int p_arg) { - return Variant::NIL; - } - - static Variant::Type get_base_type() { - return Variant::NIL; - } -}; - -class VariantConstructNoArgsObject { -public: - static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { - VariantInternal::clear(&r_ret); - VariantInternal::object_assign_null(&r_ret); - r_error.error = Callable::CallError::CALL_OK; - } - - static void validated_construct(Variant *r_ret, const Variant **p_args) { - VariantInternal::clear(r_ret); - VariantInternal::object_assign_null(r_ret); - } - static void ptr_construct(void *base, const void **p_args) { - PtrConstruct<Object *>::construct(nullptr, base); - } - - static int get_argument_count() { - return 0; - } - - static Variant::Type get_argument_type(int p_arg) { - return Variant::NIL; - } - - static Variant::Type get_base_type() { - return Variant::OBJECT; - } -}; +#include "variant_construct.h" struct VariantConstructData { void (*construct)(Variant &r_base, const Variant **p_args, Callable::CallError &r_error); diff --git a/core/variant/variant_construct.h b/core/variant/variant_construct.h new file mode 100644 index 0000000000..b03f4a8d3b --- /dev/null +++ b/core/variant/variant_construct.h @@ -0,0 +1,572 @@ +/*************************************************************************/ +/* variant_construct.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef VARIANT_CONSTRUCT_H +#define VARIANT_CONSTRUCT_H + +#include "variant.h" + +#include "core/core_string_names.h" +#include "core/crypto/crypto_core.h" +#include "core/debugger/engine_debugger.h" +#include "core/io/compression.h" +#include "core/object/class_db.h" +#include "core/os/os.h" +#include "core/templates/local_vector.h" +#include "core/templates/oa_hash_map.h" + +template <class T> +struct PtrConstruct {}; + +#define MAKE_PTRCONSTRUCT(m_type) \ + template <> \ + struct PtrConstruct<m_type> { \ + _FORCE_INLINE_ static void construct(const m_type &p_value, void *p_ptr) { \ + memnew_placement(p_ptr, m_type(p_value)); \ + } \ + }; + +MAKE_PTRCONSTRUCT(bool); +MAKE_PTRCONSTRUCT(int64_t); +MAKE_PTRCONSTRUCT(double); +MAKE_PTRCONSTRUCT(String); +MAKE_PTRCONSTRUCT(Vector2); +MAKE_PTRCONSTRUCT(Vector2i); +MAKE_PTRCONSTRUCT(Rect2); +MAKE_PTRCONSTRUCT(Rect2i); +MAKE_PTRCONSTRUCT(Vector3); +MAKE_PTRCONSTRUCT(Vector3i); +MAKE_PTRCONSTRUCT(Transform2D); +MAKE_PTRCONSTRUCT(Plane); +MAKE_PTRCONSTRUCT(Quaternion); +MAKE_PTRCONSTRUCT(AABB); +MAKE_PTRCONSTRUCT(Basis); +MAKE_PTRCONSTRUCT(Transform3D); +MAKE_PTRCONSTRUCT(Color); +MAKE_PTRCONSTRUCT(StringName); +MAKE_PTRCONSTRUCT(NodePath); +MAKE_PTRCONSTRUCT(RID); + +template <> +struct PtrConstruct<Object *> { + _FORCE_INLINE_ static void construct(Object *p_value, void *p_ptr) { + *((Object **)p_ptr) = p_value; + } +}; + +MAKE_PTRCONSTRUCT(Callable); +MAKE_PTRCONSTRUCT(Signal); +MAKE_PTRCONSTRUCT(Dictionary); +MAKE_PTRCONSTRUCT(Array); +MAKE_PTRCONSTRUCT(PackedByteArray); +MAKE_PTRCONSTRUCT(PackedInt32Array); +MAKE_PTRCONSTRUCT(PackedInt64Array); +MAKE_PTRCONSTRUCT(PackedFloat32Array); +MAKE_PTRCONSTRUCT(PackedFloat64Array); +MAKE_PTRCONSTRUCT(PackedStringArray); +MAKE_PTRCONSTRUCT(PackedVector2Array); +MAKE_PTRCONSTRUCT(PackedVector3Array); +MAKE_PTRCONSTRUCT(PackedColorArray); +MAKE_PTRCONSTRUCT(Variant); + +template <class T, class... P> +class VariantConstructor { + template <size_t... Is> + static _FORCE_INLINE_ void construct_helper(T &base, const Variant **p_args, Callable::CallError &r_error, IndexSequence<Is...>) { + r_error.error = Callable::CallError::CALL_OK; + +#ifdef DEBUG_METHODS_ENABLED + base = T(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...); +#else + base = T(VariantCaster<P>::cast(*p_args[Is])...); +#endif + } + + template <size_t... Is> + static _FORCE_INLINE_ void validated_construct_helper(T &base, const Variant **p_args, IndexSequence<Is...>) { + base = T((*VariantGetInternalPtr<P>::get_ptr(p_args[Is]))...); + } + + template <size_t... Is> + static _FORCE_INLINE_ void ptr_construct_helper(void *base, const void **p_args, IndexSequence<Is...>) { + PtrConstruct<T>::construct(T(PtrToArg<P>::convert(p_args[Is])...), base); + } + +public: + static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { + r_error.error = Callable::CallError::CALL_OK; + VariantTypeChanger<T>::change(&r_ret); + construct_helper(*VariantGetInternalPtr<T>::get_ptr(&r_ret), p_args, r_error, BuildIndexSequence<sizeof...(P)>{}); + } + + static inline void validated_construct(Variant *r_ret, const Variant **p_args) { + VariantTypeChanger<T>::change(r_ret); + validated_construct_helper(*VariantGetInternalPtr<T>::get_ptr(r_ret), p_args, BuildIndexSequence<sizeof...(P)>{}); + } + static void ptr_construct(void *base, const void **p_args) { + ptr_construct_helper(base, p_args, BuildIndexSequence<sizeof...(P)>{}); + } + + static int get_argument_count() { + return sizeof...(P); + } + + static Variant::Type get_argument_type(int p_arg) { + return call_get_argument_type<P...>(p_arg); + } + + static Variant::Type get_base_type() { + return GetTypeInfo<T>::VARIANT_TYPE; + } +}; + +class VariantConstructorObject { +public: + static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { + VariantInternal::clear(&r_ret); + if (p_args[0]->get_type() == Variant::NIL) { + VariantInternal::object_assign_null(&r_ret); + r_error.error = Callable::CallError::CALL_OK; + } else if (p_args[0]->get_type() == Variant::OBJECT) { + VariantInternal::object_assign(&r_ret, p_args[0]); + r_error.error = Callable::CallError::CALL_OK; + } else { + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument = 0; + r_error.expected = Variant::OBJECT; + } + } + + static inline void validated_construct(Variant *r_ret, const Variant **p_args) { + VariantInternal::clear(r_ret); + VariantInternal::object_assign(r_ret, p_args[0]); + } + static void ptr_construct(void *base, const void **p_args) { + PtrConstruct<Object *>::construct(PtrToArg<Object *>::convert(p_args[0]), base); + } + + static int get_argument_count() { + return 1; + } + + static Variant::Type get_argument_type(int p_arg) { + return Variant::OBJECT; + } + + static Variant::Type get_base_type() { + return Variant::OBJECT; + } +}; + +class VariantConstructorNilObject { +public: + static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { + if (p_args[0]->get_type() != Variant::NIL) { + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument = 0; + r_error.expected = Variant::NIL; + } + + VariantInternal::clear(&r_ret); + VariantInternal::object_assign_null(&r_ret); + } + + static inline void validated_construct(Variant *r_ret, const Variant **p_args) { + VariantInternal::clear(r_ret); + VariantInternal::object_assign_null(r_ret); + } + static void ptr_construct(void *base, const void **p_args) { + PtrConstruct<Object *>::construct(nullptr, base); + } + + static int get_argument_count() { + return 1; + } + + static Variant::Type get_argument_type(int p_arg) { + return Variant::NIL; + } + + static Variant::Type get_base_type() { + return Variant::OBJECT; + } +}; + +class VariantConstructorCallableArgs { +public: + static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { + ObjectID object_id; + StringName method; + + if (p_args[0]->get_type() == Variant::NIL) { + // leave as is + } else if (p_args[0]->get_type() == Variant::OBJECT) { + object_id = VariantInternal::get_object_id(p_args[0]); + } else { + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument = 0; + r_error.expected = Variant::OBJECT; + return; + } + + if (p_args[1]->get_type() == Variant::STRING_NAME) { + method = *VariantGetInternalPtr<StringName>::get_ptr(p_args[1]); + } else if (p_args[1]->get_type() == Variant::STRING) { + method = *VariantGetInternalPtr<String>::get_ptr(p_args[1]); + } else { + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument = 1; + r_error.expected = Variant::STRING_NAME; + return; + } + + VariantTypeChanger<Callable>::change(&r_ret); + *VariantGetInternalPtr<Callable>::get_ptr(&r_ret) = Callable(object_id, method); + } + + static inline void validated_construct(Variant *r_ret, const Variant **p_args) { + VariantTypeChanger<Callable>::change(r_ret); + *VariantGetInternalPtr<Callable>::get_ptr(r_ret) = Callable(VariantInternal::get_object_id(p_args[0]), *VariantGetInternalPtr<StringName>::get_ptr(p_args[1])); + } + static void ptr_construct(void *base, const void **p_args) { + PtrConstruct<Callable>::construct(Callable(PtrToArg<Object *>::convert(p_args[0]), PtrToArg<StringName>::convert(p_args[1])), base); + } + + static int get_argument_count() { + return 2; + } + + static Variant::Type get_argument_type(int p_arg) { + if (p_arg == 0) { + return Variant::OBJECT; + } else { + return Variant::STRING_NAME; + } + } + + static Variant::Type get_base_type() { + return Variant::CALLABLE; + } +}; + +class VariantConstructorSignalArgs { +public: + static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { + ObjectID object_id; + StringName method; + + if (p_args[0]->get_type() == Variant::NIL) { + // leave as is + } else if (p_args[0]->get_type() == Variant::OBJECT) { + object_id = VariantInternal::get_object_id(p_args[0]); + } else { + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument = 0; + r_error.expected = Variant::OBJECT; + return; + } + + if (p_args[1]->get_type() == Variant::STRING_NAME) { + method = *VariantGetInternalPtr<StringName>::get_ptr(p_args[1]); + } else if (p_args[1]->get_type() == Variant::STRING) { + method = *VariantGetInternalPtr<String>::get_ptr(p_args[1]); + } else { + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument = 1; + r_error.expected = Variant::STRING_NAME; + return; + } + + VariantTypeChanger<Signal>::change(&r_ret); + *VariantGetInternalPtr<Signal>::get_ptr(&r_ret) = Signal(object_id, method); + } + + static inline void validated_construct(Variant *r_ret, const Variant **p_args) { + VariantTypeChanger<Signal>::change(r_ret); + *VariantGetInternalPtr<Signal>::get_ptr(r_ret) = Signal(VariantInternal::get_object_id(p_args[0]), *VariantGetInternalPtr<StringName>::get_ptr(p_args[1])); + } + static void ptr_construct(void *base, const void **p_args) { + PtrConstruct<Signal>::construct(Signal(PtrToArg<Object *>::convert(p_args[0]), PtrToArg<StringName>::convert(p_args[1])), base); + } + + static int get_argument_count() { + return 2; + } + + static Variant::Type get_argument_type(int p_arg) { + if (p_arg == 0) { + return Variant::OBJECT; + } else { + return Variant::STRING_NAME; + } + } + + static Variant::Type get_base_type() { + return Variant::SIGNAL; + } +}; + +template <class T> +class VariantConstructorToArray { +public: + static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { + if (p_args[0]->get_type() != GetTypeInfo<T>::VARIANT_TYPE) { + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument = 0; + r_error.expected = GetTypeInfo<T>::VARIANT_TYPE; + return; + } + + VariantTypeChanger<Array>::change(&r_ret); + Array &dst_arr = *VariantGetInternalPtr<Array>::get_ptr(&r_ret); + const T &src_arr = *VariantGetInternalPtr<T>::get_ptr(p_args[0]); + + int size = src_arr.size(); + dst_arr.resize(size); + for (int i = 0; i < size; i++) { + dst_arr[i] = src_arr[i]; + } + } + + static inline void validated_construct(Variant *r_ret, const Variant **p_args) { + VariantTypeChanger<Array>::change(r_ret); + Array &dst_arr = *VariantGetInternalPtr<Array>::get_ptr(r_ret); + const T &src_arr = *VariantGetInternalPtr<T>::get_ptr(p_args[0]); + + int size = src_arr.size(); + dst_arr.resize(size); + for (int i = 0; i < size; i++) { + dst_arr[i] = src_arr[i]; + } + } + static void ptr_construct(void *base, const void **p_args) { + Array dst_arr; + T src_arr = PtrToArg<T>::convert(p_args[0]); + + int size = src_arr.size(); + dst_arr.resize(size); + for (int i = 0; i < size; i++) { + dst_arr[i] = src_arr[i]; + } + + PtrConstruct<Array>::construct(dst_arr, base); + } + + static int get_argument_count() { + return 1; + } + + static Variant::Type get_argument_type(int p_arg) { + return GetTypeInfo<T>::VARIANT_TYPE; + } + + static Variant::Type get_base_type() { + return Variant::ARRAY; + } +}; + +template <class T> +class VariantConstructorFromArray { +public: + static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { + if (p_args[0]->get_type() != Variant::ARRAY) { + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument = 0; + r_error.expected = Variant::ARRAY; + return; + } + + VariantTypeChanger<T>::change(&r_ret); + const Array &src_arr = *VariantGetInternalPtr<Array>::get_ptr(p_args[0]); + T &dst_arr = *VariantGetInternalPtr<T>::get_ptr(&r_ret); + + int size = src_arr.size(); + dst_arr.resize(size); + for (int i = 0; i < size; i++) { + dst_arr.write[i] = src_arr[i]; + } + } + + static inline void validated_construct(Variant *r_ret, const Variant **p_args) { + VariantTypeChanger<T>::change(r_ret); + const Array &src_arr = *VariantGetInternalPtr<Array>::get_ptr(p_args[0]); + T &dst_arr = *VariantGetInternalPtr<T>::get_ptr(r_ret); + + int size = src_arr.size(); + dst_arr.resize(size); + for (int i = 0; i < size; i++) { + dst_arr.write[i] = src_arr[i]; + } + } + static void ptr_construct(void *base, const void **p_args) { + Array src_arr = PtrToArg<Array>::convert(p_args[0]); + T dst_arr; + + int size = src_arr.size(); + dst_arr.resize(size); + for (int i = 0; i < size; i++) { + dst_arr.write[i] = src_arr[i]; + } + + PtrConstruct<T>::construct(dst_arr, base); + } + + static int get_argument_count() { + return 1; + } + + static Variant::Type get_argument_type(int p_arg) { + return Variant::ARRAY; + } + + static Variant::Type get_base_type() { + return GetTypeInfo<T>::VARIANT_TYPE; + } +}; + +class VariantConstructorNil { +public: + static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { + if (p_args[0]->get_type() != Variant::NIL) { + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument = 0; + r_error.expected = Variant::NIL; + return; + } + + r_error.error = Callable::CallError::CALL_OK; + VariantInternal::clear(&r_ret); + } + + static inline void validated_construct(Variant *r_ret, const Variant **p_args) { + VariantInternal::clear(r_ret); + } + static void ptr_construct(void *base, const void **p_args) { + PtrConstruct<Variant>::construct(Variant(), base); + } + + static int get_argument_count() { + return 1; + } + + static Variant::Type get_argument_type(int p_arg) { + return Variant::NIL; + } + + static Variant::Type get_base_type() { + return Variant::NIL; + } +}; + +template <class T> +class VariantConstructNoArgs { +public: + static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { + VariantTypeChanger<T>::change_and_reset(&r_ret); + r_error.error = Callable::CallError::CALL_OK; + } + + static inline void validated_construct(Variant *r_ret, const Variant **p_args) { + VariantTypeChanger<T>::change_and_reset(r_ret); + } + static void ptr_construct(void *base, const void **p_args) { + PtrConstruct<T>::construct(T(), base); + } + + static int get_argument_count() { + return 0; + } + + static Variant::Type get_argument_type(int p_arg) { + return Variant::NIL; + } + + static Variant::Type get_base_type() { + return GetTypeInfo<T>::VARIANT_TYPE; + } +}; + +class VariantConstructNoArgsNil { +public: + static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { + VariantInternal::clear(&r_ret); + r_error.error = Callable::CallError::CALL_OK; + } + + static inline void validated_construct(Variant *r_ret, const Variant **p_args) { + VariantInternal::clear(r_ret); + } + static void ptr_construct(void *base, const void **p_args) { + ERR_FAIL_MSG("can't ptrcall nil constructor"); + } + + static int get_argument_count() { + return 0; + } + + static Variant::Type get_argument_type(int p_arg) { + return Variant::NIL; + } + + static Variant::Type get_base_type() { + return Variant::NIL; + } +}; + +class VariantConstructNoArgsObject { +public: + static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { + VariantInternal::clear(&r_ret); + VariantInternal::object_assign_null(&r_ret); + r_error.error = Callable::CallError::CALL_OK; + } + + static inline void validated_construct(Variant *r_ret, const Variant **p_args) { + VariantInternal::clear(r_ret); + VariantInternal::object_assign_null(r_ret); + } + static void ptr_construct(void *base, const void **p_args) { + PtrConstruct<Object *>::construct(nullptr, base); + } + + static int get_argument_count() { + return 0; + } + + static Variant::Type get_argument_type(int p_arg) { + return Variant::NIL; + } + + static Variant::Type get_base_type() { + return Variant::OBJECT; + } +}; + +#endif // VARIANT_CONSTRUCT_H diff --git a/core/variant/variant_destruct.cpp b/core/variant/variant_destruct.cpp new file mode 100644 index 0000000000..366b71df3a --- /dev/null +++ b/core/variant/variant_destruct.cpp @@ -0,0 +1,78 @@ +/*************************************************************************/ +/* variant_destruct.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "variant_destruct.h" + +#include "core/templates/local_vector.h" + +static Variant::PTRDestructor destruct_pointers[Variant::VARIANT_MAX] = { nullptr }; + +template <class T> +static void add_destructor() { + destruct_pointers[T::get_base_type()] = T::ptr_destruct; +} + +void Variant::_register_variant_destructors() { + add_destructor<VariantDestruct<String>>(); + add_destructor<VariantDestruct<Transform2D>>(); + add_destructor<VariantDestruct<::AABB>>(); + add_destructor<VariantDestruct<Basis>>(); + add_destructor<VariantDestruct<Transform3D>>(); + add_destructor<VariantDestruct<StringName>>(); + add_destructor<VariantDestruct<NodePath>>(); + add_destructor<VariantDestruct<::RID>>(); + add_destructor<VariantDestruct<Callable>>(); + add_destructor<VariantDestruct<Signal>>(); + add_destructor<VariantDestruct<Dictionary>>(); + add_destructor<VariantDestruct<Array>>(); + add_destructor<VariantDestruct<PackedByteArray>>(); + add_destructor<VariantDestruct<PackedInt32Array>>(); + add_destructor<VariantDestruct<PackedInt64Array>>(); + add_destructor<VariantDestruct<PackedFloat32Array>>(); + add_destructor<VariantDestruct<PackedFloat64Array>>(); + add_destructor<VariantDestruct<PackedStringArray>>(); + add_destructor<VariantDestruct<PackedVector2Array>>(); + add_destructor<VariantDestruct<PackedVector3Array>>(); + add_destructor<VariantDestruct<PackedColorArray>>(); +} + +void Variant::_unregister_variant_destructors() { + // Nothing to be done. +} + +Variant::PTRDestructor Variant::get_ptr_destructor(Variant::Type p_type) { + ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, nullptr); + return destruct_pointers[p_type]; +} + +bool Variant::has_destructor(Variant::Type p_type) { + ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, false); + return destruct_pointers[p_type] != nullptr; +} diff --git a/core/variant/variant_destruct.h b/core/variant/variant_destruct.h new file mode 100644 index 0000000000..7356e42201 --- /dev/null +++ b/core/variant/variant_destruct.h @@ -0,0 +1,76 @@ +/*************************************************************************/ +/* variant_destruct.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef VARIANT_DESTRUCT_H +#define VARIANT_DESTRUCT_H + +#include "core/variant/variant.h" + +#include "core/object/class_db.h" + +template <class T> +struct VariantDestruct {}; + +#define MAKE_PTRDESTRUCT(m_type) \ + template <> \ + struct VariantDestruct<m_type> { \ + _FORCE_INLINE_ static void ptr_destruct(void *p_ptr) { \ + reinterpret_cast<m_type *>(p_ptr)->~m_type(); \ + } \ + _FORCE_INLINE_ static Variant::Type get_base_type() { \ + return GetTypeInfo<m_type>::VARIANT_TYPE; \ + } \ + } + +MAKE_PTRDESTRUCT(String); +MAKE_PTRDESTRUCT(Transform2D); +MAKE_PTRDESTRUCT(AABB); +MAKE_PTRDESTRUCT(Basis); +MAKE_PTRDESTRUCT(Transform3D); +MAKE_PTRDESTRUCT(StringName); +MAKE_PTRDESTRUCT(NodePath); +MAKE_PTRDESTRUCT(RID); +MAKE_PTRDESTRUCT(Callable); +MAKE_PTRDESTRUCT(Signal); +MAKE_PTRDESTRUCT(Dictionary); +MAKE_PTRDESTRUCT(Array); +MAKE_PTRDESTRUCT(PackedByteArray); +MAKE_PTRDESTRUCT(PackedInt32Array); +MAKE_PTRDESTRUCT(PackedInt64Array); +MAKE_PTRDESTRUCT(PackedFloat32Array); +MAKE_PTRDESTRUCT(PackedFloat64Array); +MAKE_PTRDESTRUCT(PackedStringArray); +MAKE_PTRDESTRUCT(PackedVector2Array); +MAKE_PTRDESTRUCT(PackedVector3Array); +MAKE_PTRDESTRUCT(PackedColorArray); + +#undef MAKE_PTRDESTRUCT + +#endif // VARIANT_DESTRUCT_H diff --git a/core/variant/variant_internal.h b/core/variant/variant_internal.h index 78e1ad06ae..40c8a1bfde 100644 --- a/core/variant/variant_internal.h +++ b/core/variant/variant_internal.h @@ -104,7 +104,7 @@ public: init_color_array(v); break; case Variant::OBJECT: - object_assign_null(v); + init_object(v); break; default: break; @@ -280,6 +280,10 @@ public: v->_data.packed_array = Variant::PackedArrayRef<Color>::create(Vector<Color>()); v->type = Variant::PACKED_COLOR_ARRAY; } + _FORCE_INLINE_ static void init_object(Variant *v) { + object_assign_null(v); + v->type = Variant::OBJECT; + } _FORCE_INLINE_ static void clear(Variant *v) { v->clear(); @@ -1171,6 +1175,11 @@ struct VariantInitializer<PackedColorArray> { static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_color_array(v); } }; +template <> +struct VariantInitializer<Object *> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_object(v); } +}; + template <class T> struct VariantZeroAssigner { }; @@ -1385,4 +1394,37 @@ struct VariantTypeAdjust<Object *> { } }; +// GDNative extension helpers. + +template <class T> +struct VariantTypeConstructor { + _FORCE_INLINE_ static void variant_from_type(void *p_variant, void *p_value) { + Variant *variant = reinterpret_cast<Variant *>(p_variant); + VariantInitializer<T>::init(variant); + VariantInternalAccessor<T>::set(variant, *((T *)p_value)); + } + + _FORCE_INLINE_ static void type_from_variant(void *p_value, void *p_variant) { + *((T *)p_value) = VariantInternalAccessor<T>::get(reinterpret_cast<Variant *>(p_variant)); + } +}; + +template <> +struct VariantTypeConstructor<Object *> { + _FORCE_INLINE_ static void variant_from_type(void *p_variant, void *p_value) { + Variant *variant = reinterpret_cast<Variant *>(p_variant); + VariantInitializer<Object *>::init(variant); + Object *value = *(reinterpret_cast<Object **>(p_value)); + if (value) { + VariantInternalAccessor<Object *>::set(variant, value); + VariantInternalAccessor<ObjectID>::set(variant, value->get_instance_id()); + } + } + + _FORCE_INLINE_ static void type_from_variant(void *p_value, void *p_variant) { + Object **value = reinterpret_cast<Object **>(p_value); + *value = VariantInternalAccessor<Object *>::get(reinterpret_cast<Variant *>(p_variant)); + } +}; + #endif // VARIANT_INTERNAL_H diff --git a/core/variant/variant_op.cpp b/core/variant/variant_op.cpp index 10d0a83014..a245aff35b 100644 --- a/core/variant/variant_op.cpp +++ b/core/variant/variant_op.cpp @@ -28,1342 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "variant.h" - -#include "core/core_string_names.h" -#include "core/debugger/engine_debugger.h" -#include "core/object/class_db.h" - -template <class R, class A, class B> -class OperatorEvaluatorAdd { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); - const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); - *r_ret = a + b; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<R>::change(r_ret); - *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) + *VariantGetInternalPtr<B>::get_ptr(right); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<R>::encode(PtrToArg<A>::convert(left) + PtrToArg<B>::convert(right), r_ret); - } - static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } -}; - -template <class R, class A, class B> -class OperatorEvaluatorSub { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); - const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); - *r_ret = a - b; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<R>::change(r_ret); - *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) - *VariantGetInternalPtr<B>::get_ptr(right); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<R>::encode(PtrToArg<A>::convert(left) - PtrToArg<B>::convert(right), r_ret); - } - static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } -}; - -template <class R, class A, class B> -class OperatorEvaluatorMul { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); - const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); - *r_ret = a * b; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<R>::change(r_ret); - *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) * *VariantGetInternalPtr<B>::get_ptr(right); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<R>::encode(PtrToArg<A>::convert(left) * PtrToArg<B>::convert(right), r_ret); - } - static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } -}; - -template <class R, class A, class B> -class OperatorEvaluatorXForm { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); - const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); - *r_ret = a.xform(b); - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<R>::change(r_ret); - *VariantGetInternalPtr<R>::get_ptr(r_ret) = VariantGetInternalPtr<A>::get_ptr(left)->xform(*VariantGetInternalPtr<B>::get_ptr(right)); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<R>::encode(PtrToArg<A>::convert(left).xform(PtrToArg<B>::convert(right)), r_ret); - } - static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } -}; - -template <class R, class A, class B> -class OperatorEvaluatorXFormInv { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); - const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); - *r_ret = b.xform_inv(a); - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<R>::change(r_ret); - *VariantGetInternalPtr<R>::get_ptr(r_ret) = VariantGetInternalPtr<B>::get_ptr(right)->xform_inv(*VariantGetInternalPtr<A>::get_ptr(left)); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<R>::encode(PtrToArg<B>::convert(right).xform_inv(PtrToArg<A>::convert(left)), r_ret); - } - static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } -}; - -template <class R, class A, class B> -class OperatorEvaluatorDiv { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); - const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); - *r_ret = a / b; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<R>::change(r_ret); - *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) / *VariantGetInternalPtr<B>::get_ptr(right); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<R>::encode(PtrToArg<A>::convert(left) / PtrToArg<B>::convert(right), r_ret); - } - static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } -}; - -template <class R, class A, class B> -class OperatorEvaluatorDivNZ { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); - const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); - if (b == 0) { - r_valid = false; - *r_ret = "Division by zero error"; - return; - } - *r_ret = a / b; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<R>::change(r_ret); - *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) / *VariantGetInternalPtr<B>::get_ptr(right); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<R>::encode(PtrToArg<A>::convert(left) / PtrToArg<B>::convert(right), r_ret); - } - static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } -}; - -template <class R, class A, class B> -class OperatorEvaluatorMod { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); - const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); - *r_ret = a % b; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<R>::change(r_ret); - *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) % *VariantGetInternalPtr<B>::get_ptr(right); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<R>::encode(PtrToArg<A>::convert(left) % PtrToArg<B>::convert(right), r_ret); - } - static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } -}; - -template <class R, class A, class B> -class OperatorEvaluatorModNZ { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); - const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); - if (b == 0) { - r_valid = false; - *r_ret = "Module by zero error"; - return; - } - *r_ret = a % b; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<R>::change(r_ret); - *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) % *VariantGetInternalPtr<B>::get_ptr(right); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<R>::encode(PtrToArg<A>::convert(left) % PtrToArg<B>::convert(right), r_ret); - } - static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } -}; - -template <class R, class A> -class OperatorEvaluatorNeg { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); - *r_ret = -a; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<R>::change(r_ret); - *VariantGetInternalPtr<R>::get_ptr(r_ret) = -*VariantGetInternalPtr<A>::get_ptr(left); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<R>::encode(-PtrToArg<A>::convert(left), r_ret); - } - static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } -}; - -template <class R, class A> -class OperatorEvaluatorPos { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); - *r_ret = a; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<R>::change(r_ret); - *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<R>::encode(PtrToArg<A>::convert(left), r_ret); - } - static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } -}; - -template <class R, class A, class B> -class OperatorEvaluatorShiftLeft { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); - const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); - -#if defined(DEBUG_ENABLED) - if (b < 0 || a < 0) { - *r_ret = "Invalid operands for bit shifting. Only positive operands are supported."; - r_valid = false; - return; - } -#endif - *r_ret = a << b; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<R>::change(r_ret); - *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) << *VariantGetInternalPtr<B>::get_ptr(right); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<R>::encode(PtrToArg<A>::convert(left) << PtrToArg<B>::convert(right), r_ret); - } - static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } -}; - -template <class R, class A, class B> -class OperatorEvaluatorShiftRight { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); - const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); - -#if defined(DEBUG_ENABLED) - if (b < 0 || a < 0) { - *r_ret = "Invalid operands for bit shifting. Only positive operands are supported."; - r_valid = false; - return; - } -#endif - *r_ret = a >> b; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<R>::change(r_ret); - *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) >> *VariantGetInternalPtr<B>::get_ptr(right); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<R>::encode(PtrToArg<A>::convert(left) >> PtrToArg<B>::convert(right), r_ret); - } - static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } -}; - -template <class R, class A, class B> -class OperatorEvaluatorBitOr { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); - const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); - *r_ret = a | b; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<R>::change(r_ret); - *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) | *VariantGetInternalPtr<B>::get_ptr(right); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<R>::encode(PtrToArg<A>::convert(left) | PtrToArg<B>::convert(right), r_ret); - } - static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } -}; - -template <class R, class A, class B> -class OperatorEvaluatorBitAnd { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); - const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); - *r_ret = a & b; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<R>::change(r_ret); - *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) & *VariantGetInternalPtr<B>::get_ptr(right); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<R>::encode(PtrToArg<A>::convert(left) & PtrToArg<B>::convert(right), r_ret); - } - static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } -}; - -template <class R, class A, class B> -class OperatorEvaluatorBitXor { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); - const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); - *r_ret = a ^ b; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<R>::change(r_ret); - *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) ^ *VariantGetInternalPtr<B>::get_ptr(right); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<R>::encode(PtrToArg<A>::convert(left) ^ PtrToArg<B>::convert(right), r_ret); - } - static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } -}; - -template <class R, class A> -class OperatorEvaluatorBitNeg { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); - *r_ret = ~a; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<R>::change(r_ret); - *VariantGetInternalPtr<R>::get_ptr(r_ret) = ~*VariantGetInternalPtr<A>::get_ptr(left); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<R>::encode(~PtrToArg<A>::convert(left), r_ret); - } - static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } -}; - -template <class A, class B> -class OperatorEvaluatorEqual { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); - const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); - *r_ret = a == b; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<bool>::change(r_ret); - *VariantGetInternalPtr<bool>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) == *VariantGetInternalPtr<B>::get_ptr(right); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<bool>::encode(PtrToArg<A>::convert(left) == PtrToArg<B>::convert(right), r_ret); - } - static Variant::Type get_return_type() { return Variant::BOOL; } -}; - -class OperatorEvaluatorEqualObject { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const Object *a = p_left.get_validated_object(); - const Object *b = p_right.get_validated_object(); - *r_ret = a == b; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - const Object *a = left->get_validated_object(); - const Object *b = right->get_validated_object(); - VariantTypeChanger<bool>::change(r_ret); - *VariantGetInternalPtr<bool>::get_ptr(r_ret) = a == b; - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<bool>::encode(PtrToArg<Object *>::convert(left) == PtrToArg<Object *>::convert(right), r_ret); - } - static Variant::Type get_return_type() { return Variant::BOOL; } -}; - -class OperatorEvaluatorEqualObjectNil { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const Object *a = p_left.get_validated_object(); - *r_ret = a == nullptr; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - const Object *a = left->get_validated_object(); - VariantTypeChanger<bool>::change(r_ret); - *VariantGetInternalPtr<bool>::get_ptr(r_ret) = a == nullptr; - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<bool>::encode(PtrToArg<Object *>::convert(left) == nullptr, r_ret); - } - static Variant::Type get_return_type() { return Variant::BOOL; } -}; - -class OperatorEvaluatorEqualNilObject { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const Object *b = p_right.get_validated_object(); - *r_ret = nullptr == b; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - const Object *b = right->get_validated_object(); - VariantTypeChanger<bool>::change(r_ret); - *VariantGetInternalPtr<bool>::get_ptr(r_ret) = nullptr == b; - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<bool>::encode(nullptr == PtrToArg<Object *>::convert(right), r_ret); - } - static Variant::Type get_return_type() { return Variant::BOOL; } -}; - -template <class A, class B> -class OperatorEvaluatorNotEqual { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); - const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); - *r_ret = a != b; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<bool>::change(r_ret); - *VariantGetInternalPtr<bool>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) != *VariantGetInternalPtr<B>::get_ptr(right); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<bool>::encode(PtrToArg<A>::convert(left) != PtrToArg<B>::convert(right), r_ret); - } - static Variant::Type get_return_type() { return Variant::BOOL; } -}; - -class OperatorEvaluatorNotEqualObject { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - Object *a = p_left.get_validated_object(); - Object *b = p_right.get_validated_object(); - *r_ret = a != b; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - Object *a = left->get_validated_object(); - Object *b = right->get_validated_object(); - VariantTypeChanger<bool>::change(r_ret); - *VariantGetInternalPtr<bool>::get_ptr(r_ret) = a != b; - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<bool>::encode(PtrToArg<Object *>::convert(left) != PtrToArg<Object *>::convert(right), r_ret); - } - static Variant::Type get_return_type() { return Variant::BOOL; } -}; - -class OperatorEvaluatorNotEqualObjectNil { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - Object *a = p_left.get_validated_object(); - *r_ret = a != nullptr; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - Object *a = left->get_validated_object(); - VariantTypeChanger<bool>::change(r_ret); - *VariantGetInternalPtr<bool>::get_ptr(r_ret) = a != nullptr; - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<bool>::encode(PtrToArg<Object *>::convert(left) != nullptr, r_ret); - } - static Variant::Type get_return_type() { return Variant::BOOL; } -}; - -class OperatorEvaluatorNotEqualNilObject { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - Object *b = p_right.get_validated_object(); - *r_ret = nullptr != b; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - Object *b = right->get_validated_object(); - VariantTypeChanger<bool>::change(r_ret); - *VariantGetInternalPtr<bool>::get_ptr(r_ret) = nullptr != b; - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<bool>::encode(nullptr != PtrToArg<Object *>::convert(right), r_ret); - } - static Variant::Type get_return_type() { return Variant::BOOL; } -}; - -template <class A, class B> -class OperatorEvaluatorLess { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); - const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); - *r_ret = a < b; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<bool>::change(r_ret); - *VariantGetInternalPtr<bool>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) < *VariantGetInternalPtr<B>::get_ptr(right); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<bool>::encode(PtrToArg<A>::convert(left) < PtrToArg<B>::convert(right), r_ret); - } - static Variant::Type get_return_type() { return Variant::BOOL; } -}; - -template <class A, class B> -class OperatorEvaluatorLessEqual { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); - const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); - *r_ret = a <= b; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<bool>::change(r_ret); - *VariantGetInternalPtr<bool>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) <= *VariantGetInternalPtr<B>::get_ptr(right); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<bool>::encode(PtrToArg<A>::convert(left) <= PtrToArg<B>::convert(right), r_ret); - } - static Variant::Type get_return_type() { return Variant::BOOL; } -}; - -template <class A, class B> -class OperatorEvaluatorGreater { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); - const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); - *r_ret = a > b; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<bool>::change(r_ret); - *VariantGetInternalPtr<bool>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) > *VariantGetInternalPtr<B>::get_ptr(right); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<bool>::encode(PtrToArg<A>::convert(left) > PtrToArg<B>::convert(right), r_ret); - } - static Variant::Type get_return_type() { return Variant::BOOL; } -}; - -template <class A, class B> -class OperatorEvaluatorGreaterEqual { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); - const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); - *r_ret = a >= b; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<bool>::change(r_ret); - *VariantGetInternalPtr<bool>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) >= *VariantGetInternalPtr<B>::get_ptr(right); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<bool>::encode(PtrToArg<A>::convert(left) >= PtrToArg<B>::convert(right), r_ret); - } - static Variant::Type get_return_type() { return Variant::BOOL; } -}; - -template <class A, class B> -class OperatorEvaluatorAnd { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); - const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); - *r_ret = a && b; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<bool>::change(r_ret); - *VariantGetInternalPtr<bool>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) && *VariantGetInternalPtr<B>::get_ptr(right); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<bool>::encode(PtrToArg<A>::convert(left) && PtrToArg<B>::convert(right), r_ret); - } - static Variant::Type get_return_type() { return Variant::BOOL; } -}; - -template <class A, class B> -class OperatorEvaluatorOr { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); - const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); - *r_ret = a || b; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<bool>::change(r_ret); - *VariantGetInternalPtr<bool>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) || *VariantGetInternalPtr<B>::get_ptr(right); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<bool>::encode(PtrToArg<A>::convert(left) || PtrToArg<B>::convert(right), r_ret); - } - static Variant::Type get_return_type() { return Variant::BOOL; } -}; - -#define XOR_OP(m_a, m_b) (((m_a) || (m_b)) && !((m_a) && (m_b))) -template <class A, class B> -class OperatorEvaluatorXor { -public: - _FORCE_INLINE_ static bool xor_op(const A &a, const B &b) { - return ((a) || (b)) && !((a) && (b)); - } - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); - const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); - *r_ret = xor_op(a, b); - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<bool>::change(r_ret); - *VariantGetInternalPtr<bool>::get_ptr(r_ret) = xor_op(*VariantGetInternalPtr<A>::get_ptr(left), *VariantGetInternalPtr<B>::get_ptr(right)); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<bool>::encode(xor_op(PtrToArg<A>::convert(left), PtrToArg<B>::convert(right)), r_ret); - } - static Variant::Type get_return_type() { return Variant::BOOL; } -}; - -template <class A> -class OperatorEvaluatorNot { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); - *r_ret = !a; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<bool>::change(r_ret); - *VariantGetInternalPtr<bool>::get_ptr(r_ret) = !*VariantGetInternalPtr<A>::get_ptr(left); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<bool>::encode(!PtrToArg<A>::convert(left)); - } - static Variant::Type get_return_type() { return Variant::BOOL; } -}; - -//// CUSTOM //// - -class OperatorEvaluatorAddArray { -public: - _FORCE_INLINE_ static void _add_arrays(Array &sum, const Array &array_a, const Array &array_b) { - int asize = array_a.size(); - int bsize = array_b.size(); - sum.resize(asize + bsize); - for (int i = 0; i < asize; i++) { - sum[i] = array_a[i]; - } - for (int i = 0; i < bsize; i++) { - sum[i + asize] = array_b[i]; - } - } - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const Array &array_a = *VariantGetInternalPtr<Array>::get_ptr(&p_left); - const Array &array_b = *VariantGetInternalPtr<Array>::get_ptr(&p_right); - Array sum; - _add_arrays(sum, array_a, array_b); - *r_ret = sum; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<Array>::change(r_ret); - _add_arrays(*VariantGetInternalPtr<Array>::get_ptr(r_ret), *VariantGetInternalPtr<Array>::get_ptr(left), *VariantGetInternalPtr<Array>::get_ptr(right)); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - Array ret; - _add_arrays(ret, PtrToArg<Array>::convert(left), PtrToArg<Array>::convert(right)); - PtrToArg<Array>::encode(ret, r_ret); - } - static Variant::Type get_return_type() { return Variant::ARRAY; } -}; - -template <class T> -class OperatorEvaluatorAppendArray { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const Vector<T> &array_a = *VariantGetInternalPtr<Vector<T>>::get_ptr(&p_left); - const Vector<T> &array_b = *VariantGetInternalPtr<Vector<T>>::get_ptr(&p_right); - Vector<T> sum = array_a; - sum.append_array(array_b); - *r_ret = sum; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<Vector<T>>::change(r_ret); - *VariantGetInternalPtr<Vector<T>>::get_ptr(r_ret) = *VariantGetInternalPtr<Vector<T>>::get_ptr(left); - VariantGetInternalPtr<Vector<T>>::get_ptr(r_ret)->append_array(*VariantGetInternalPtr<Vector<T>>::get_ptr(right)); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - Vector<T> sum = PtrToArg<Vector<T>>::convert(left); - sum.append_array(PtrToArg<Vector<T>>::convert(right)); - PtrToArg<Vector<T>>::encode(sum, r_ret); - } - static Variant::Type get_return_type() { return GetTypeInfo<Vector<T>>::VARIANT_TYPE; } -}; - -class OperatorEvaluatorStringModNil { -public: - _FORCE_INLINE_ static String do_mod(const String &s, bool *r_valid) { - Array values; - values.push_back(Variant()); - - String a = s.sprintf(values, r_valid); - if (r_valid) { - *r_valid = !*r_valid; - } - return a; - } - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const String &a = *VariantGetInternalPtr<String>::get_ptr(&p_left); - *r_ret = do_mod(a, &r_valid); - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<String>::change(r_ret); - *VariantGetInternalPtr<String>::get_ptr(r_ret) = do_mod(*VariantGetInternalPtr<String>::get_ptr(left), nullptr); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<String>::encode(do_mod(PtrToArg<String>::convert(left), nullptr), r_ret); - } - static Variant::Type get_return_type() { return Variant::STRING; } -}; - -class OperatorEvaluatorStringModArray { -public: - _FORCE_INLINE_ static String do_mod(const String &s, const Array &p_values, bool *r_valid) { - String a = s.sprintf(p_values, r_valid); - if (r_valid) { - *r_valid = !*r_valid; - } - return a; - } - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const String &a = *VariantGetInternalPtr<String>::get_ptr(&p_left); - *r_ret = do_mod(a, *VariantGetInternalPtr<Array>::get_ptr(&p_right), &r_valid); - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<String>::change(r_ret); - *VariantGetInternalPtr<String>::get_ptr(r_ret) = do_mod(*VariantGetInternalPtr<String>::get_ptr(left), *VariantGetInternalPtr<Array>::get_ptr(right), nullptr); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<String>::encode(do_mod(PtrToArg<String>::convert(left), PtrToArg<Array>::convert(right), nullptr), r_ret); - } - static Variant::Type get_return_type() { return Variant::STRING; } -}; - -class OperatorEvaluatorStringModObject { -public: - _FORCE_INLINE_ static String do_mod(const String &s, const Object *p_object, bool *r_valid) { - Array values; - values.push_back(p_object); - String a = s.sprintf(values, r_valid); - if (r_valid) { - *r_valid = !*r_valid; - } - - return a; - } - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const String &a = *VariantGetInternalPtr<String>::get_ptr(&p_left); - *r_ret = do_mod(a, p_right.get_validated_object(), &r_valid); - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<String>::change(r_ret); - *VariantGetInternalPtr<String>::get_ptr(r_ret) = do_mod(*VariantGetInternalPtr<String>::get_ptr(left), right->get_validated_object(), nullptr); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<String>::encode(do_mod(PtrToArg<String>::convert(left), PtrToArg<Object *>::convert(right), nullptr), r_ret); - } - static Variant::Type get_return_type() { return Variant::STRING; } -}; - -template <class T> -class OperatorEvaluatorStringModT { -public: - _FORCE_INLINE_ static String do_mod(const String &s, const T &p_value, bool *r_valid) { - Array values; - values.push_back(p_value); - String a = s.sprintf(values, r_valid); - if (r_valid) { - *r_valid = !*r_valid; - } - return a; - } - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const String &a = *VariantGetInternalPtr<String>::get_ptr(&p_left); - *r_ret = do_mod(a, *VariantGetInternalPtr<T>::get_ptr(&p_right), &r_valid); - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<String>::change(r_ret); - *VariantGetInternalPtr<String>::get_ptr(r_ret) = do_mod(*VariantGetInternalPtr<String>::get_ptr(left), *VariantGetInternalPtr<T>::get_ptr(right), nullptr); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<String>::encode(do_mod(PtrToArg<String>::convert(left), PtrToArg<T>::convert(right), nullptr), r_ret); - } - static Variant::Type get_return_type() { return Variant::STRING; } -}; - -template <Variant::Operator op, Variant::Type type_left, Variant::Type type_right> -class OperatorEvaluatorAlwaysTrue { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - *r_ret = true; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<bool>::change(r_ret); - *VariantGetInternalPtr<bool>::get_ptr(r_ret) = true; - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<bool>::encode(true, r_ret); - } - static Variant::Type get_return_type() { return Variant::BOOL; } -}; - -template <Variant::Operator op, Variant::Type type_left, Variant::Type type_right> -class OperatorEvaluatorAlwaysFalse { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - *r_ret = false; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<bool>::change(r_ret); - *VariantGetInternalPtr<bool>::get_ptr(r_ret) = false; - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<bool>::encode(false, r_ret); - } - static Variant::Type get_return_type() { return Variant::BOOL; } -}; - -///// OR /////// - -_FORCE_INLINE_ static bool _operate_or(bool p_left, bool p_right) { - return p_left || p_right; -} - -_FORCE_INLINE_ static bool _operate_and(bool p_left, bool p_right) { - return p_left && p_right; -} - -_FORCE_INLINE_ static bool _operate_xor(bool p_left, bool p_right) { - return (p_left || p_right) && !(p_left && p_right); -} - -_FORCE_INLINE_ static bool _operate_get_nil(const Variant *p_ptr) { - return p_ptr->get_validated_object() != nullptr; -} - -_FORCE_INLINE_ static bool _operate_get_bool(const Variant *p_ptr) { - return *VariantGetInternalPtr<bool>::get_ptr(p_ptr); -} - -_FORCE_INLINE_ static bool _operate_get_int(const Variant *p_ptr) { - return *VariantGetInternalPtr<int64_t>::get_ptr(p_ptr) != 0; -} - -_FORCE_INLINE_ static bool _operate_get_float(const Variant *p_ptr) { - return *VariantGetInternalPtr<double>::get_ptr(p_ptr) != 0.0; -} - -_FORCE_INLINE_ static bool _operate_get_object(const Variant *p_ptr) { - return p_ptr->get_validated_object() != nullptr; -} - -_FORCE_INLINE_ static bool _operate_get_ptr_nil(const void *p_ptr) { - return false; -} - -_FORCE_INLINE_ static bool _operate_get_ptr_bool(const void *p_ptr) { - return PtrToArg<bool>::convert(p_ptr); -} - -_FORCE_INLINE_ static bool _operate_get_ptr_int(const void *p_ptr) { - return PtrToArg<int64_t>::convert(p_ptr) != 0; -} - -_FORCE_INLINE_ static bool _operate_get_ptr_float(const void *p_ptr) { - return PtrToArg<double>::convert(p_ptr) != 0.0; -} - -_FORCE_INLINE_ static bool _operate_get_ptr_object(const void *p_ptr) { - return PtrToArg<Object *>::convert(p_ptr) != nullptr; -} - -#define OP_EVALUATOR(m_class_name, m_left, m_right, m_op) \ - class m_class_name { \ - public: \ - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { \ - *r_ret = m_op(_operate_get_##m_left(&p_left), _operate_get_##m_right(&p_right)); \ - r_valid = true; \ - } \ - \ - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { \ - VariantTypeChanger<bool>::change(r_ret); \ - *VariantGetInternalPtr<bool>::get_ptr(r_ret) = m_op(_operate_get_##m_left(left), _operate_get_##m_right(right)); \ - } \ - \ - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { \ - PtrToArg<bool>::encode(m_op(_operate_get_ptr_##m_left(left), _operate_get_ptr_##m_right(right)), r_ret); \ - } \ - \ - static Variant::Type get_return_type() { \ - return Variant::BOOL; \ - } \ - }; - -// OR - -// nil -OP_EVALUATOR(OperatorEvaluatorNilXBoolOr, nil, bool, _operate_or) -OP_EVALUATOR(OperatorEvaluatorBoolXNilOr, bool, nil, _operate_or) - -OP_EVALUATOR(OperatorEvaluatorNilXIntOr, nil, int, _operate_or) -OP_EVALUATOR(OperatorEvaluatorIntXNilOr, int, nil, _operate_or) - -OP_EVALUATOR(OperatorEvaluatorNilXFloatOr, nil, float, _operate_or) -OP_EVALUATOR(OperatorEvaluatorFloatXNilOr, float, nil, _operate_or) - -OP_EVALUATOR(OperatorEvaluatorObjectXNilOr, object, nil, _operate_or) -OP_EVALUATOR(OperatorEvaluatorNilXObjectOr, nil, object, _operate_or) - -// bool -OP_EVALUATOR(OperatorEvaluatorBoolXBoolOr, bool, bool, _operate_or) - -OP_EVALUATOR(OperatorEvaluatorBoolXIntOr, bool, int, _operate_or) -OP_EVALUATOR(OperatorEvaluatorIntXBoolOr, int, bool, _operate_or) - -OP_EVALUATOR(OperatorEvaluatorBoolXFloatOr, bool, float, _operate_or) -OP_EVALUATOR(OperatorEvaluatorFloatXBoolOr, float, bool, _operate_or) - -OP_EVALUATOR(OperatorEvaluatorBoolXObjectOr, bool, object, _operate_or) -OP_EVALUATOR(OperatorEvaluatorObjectXBoolOr, object, bool, _operate_or) - -// int -OP_EVALUATOR(OperatorEvaluatorIntXIntOr, int, int, _operate_or) - -OP_EVALUATOR(OperatorEvaluatorIntXFloatOr, int, float, _operate_or) -OP_EVALUATOR(OperatorEvaluatorFloatXIntOr, float, int, _operate_or) - -OP_EVALUATOR(OperatorEvaluatorIntXObjectOr, int, object, _operate_or) -OP_EVALUATOR(OperatorEvaluatorObjectXIntOr, object, int, _operate_or) - -// float -OP_EVALUATOR(OperatorEvaluatorFloatXFloatOr, float, float, _operate_or) - -OP_EVALUATOR(OperatorEvaluatorFloatXObjectOr, float, object, _operate_or) -OP_EVALUATOR(OperatorEvaluatorObjectXFloatOr, object, float, _operate_or) - -// object -OP_EVALUATOR(OperatorEvaluatorObjectXObjectOr, object, object, _operate_or) - -// AND - -// nil -OP_EVALUATOR(OperatorEvaluatorNilXBoolAnd, nil, bool, _operate_and) -OP_EVALUATOR(OperatorEvaluatorBoolXNilAnd, bool, nil, _operate_and) - -OP_EVALUATOR(OperatorEvaluatorNilXIntAnd, nil, int, _operate_and) -OP_EVALUATOR(OperatorEvaluatorIntXNilAnd, int, nil, _operate_and) - -OP_EVALUATOR(OperatorEvaluatorNilXFloatAnd, nil, float, _operate_and) -OP_EVALUATOR(OperatorEvaluatorFloatXNilAnd, float, nil, _operate_and) - -OP_EVALUATOR(OperatorEvaluatorObjectXNilAnd, object, nil, _operate_and) -OP_EVALUATOR(OperatorEvaluatorNilXObjectAnd, nil, object, _operate_and) - -// bool -OP_EVALUATOR(OperatorEvaluatorBoolXBoolAnd, bool, bool, _operate_and) - -OP_EVALUATOR(OperatorEvaluatorBoolXIntAnd, bool, int, _operate_and) -OP_EVALUATOR(OperatorEvaluatorIntXBoolAnd, int, bool, _operate_and) - -OP_EVALUATOR(OperatorEvaluatorBoolXFloatAnd, bool, float, _operate_and) -OP_EVALUATOR(OperatorEvaluatorFloatXBoolAnd, float, bool, _operate_and) - -OP_EVALUATOR(OperatorEvaluatorBoolXObjectAnd, bool, object, _operate_and) -OP_EVALUATOR(OperatorEvaluatorObjectXBoolAnd, object, bool, _operate_and) - -// int -OP_EVALUATOR(OperatorEvaluatorIntXIntAnd, int, int, _operate_and) - -OP_EVALUATOR(OperatorEvaluatorIntXFloatAnd, int, float, _operate_and) -OP_EVALUATOR(OperatorEvaluatorFloatXIntAnd, float, int, _operate_and) - -OP_EVALUATOR(OperatorEvaluatorIntXObjectAnd, int, object, _operate_and) -OP_EVALUATOR(OperatorEvaluatorObjectXIntAnd, object, int, _operate_and) - -// float -OP_EVALUATOR(OperatorEvaluatorFloatXFloatAnd, float, float, _operate_and) - -OP_EVALUATOR(OperatorEvaluatorFloatXObjectAnd, float, object, _operate_and) -OP_EVALUATOR(OperatorEvaluatorObjectXFloatAnd, object, float, _operate_and) - -// object -OP_EVALUATOR(OperatorEvaluatorObjectXObjectAnd, object, object, _operate_and) - -// XOR - -// nil -OP_EVALUATOR(OperatorEvaluatorNilXBoolXor, nil, bool, _operate_xor) -OP_EVALUATOR(OperatorEvaluatorBoolXNilXor, bool, nil, _operate_xor) - -OP_EVALUATOR(OperatorEvaluatorNilXIntXor, nil, int, _operate_xor) -OP_EVALUATOR(OperatorEvaluatorIntXNilXor, int, nil, _operate_xor) - -OP_EVALUATOR(OperatorEvaluatorNilXFloatXor, nil, float, _operate_xor) -OP_EVALUATOR(OperatorEvaluatorFloatXNilXor, float, nil, _operate_xor) - -OP_EVALUATOR(OperatorEvaluatorObjectXNilXor, object, nil, _operate_xor) -OP_EVALUATOR(OperatorEvaluatorNilXObjectXor, nil, object, _operate_xor) - -// bool -OP_EVALUATOR(OperatorEvaluatorBoolXBoolXor, bool, bool, _operate_xor) - -OP_EVALUATOR(OperatorEvaluatorBoolXIntXor, bool, int, _operate_xor) -OP_EVALUATOR(OperatorEvaluatorIntXBoolXor, int, bool, _operate_xor) - -OP_EVALUATOR(OperatorEvaluatorBoolXFloatXor, bool, float, _operate_xor) -OP_EVALUATOR(OperatorEvaluatorFloatXBoolXor, float, bool, _operate_xor) - -OP_EVALUATOR(OperatorEvaluatorBoolXObjectXor, bool, object, _operate_xor) -OP_EVALUATOR(OperatorEvaluatorObjectXBoolXor, object, bool, _operate_xor) - -// int -OP_EVALUATOR(OperatorEvaluatorIntXIntXor, int, int, _operate_xor) - -OP_EVALUATOR(OperatorEvaluatorIntXFloatXor, int, float, _operate_xor) -OP_EVALUATOR(OperatorEvaluatorFloatXIntXor, float, int, _operate_xor) - -OP_EVALUATOR(OperatorEvaluatorIntXObjectXor, int, object, _operate_xor) -OP_EVALUATOR(OperatorEvaluatorObjectXIntXor, object, int, _operate_xor) - -// float -OP_EVALUATOR(OperatorEvaluatorFloatXFloatXor, float, float, _operate_xor) - -OP_EVALUATOR(OperatorEvaluatorFloatXObjectXor, float, object, _operate_xor) -OP_EVALUATOR(OperatorEvaluatorObjectXFloatXor, object, float, _operate_xor) - -// object -OP_EVALUATOR(OperatorEvaluatorObjectXObjectXor, object, object, _operate_xor) - -class OperatorEvaluatorNotBool { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - *r_ret = !*VariantGetInternalPtr<bool>::get_ptr(&p_left); - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<bool>::change(r_ret); - *VariantGetInternalPtr<bool>::get_ptr(r_ret) = !*VariantGetInternalPtr<bool>::get_ptr(left); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<bool>::encode(!PtrToArg<bool>::convert(left), r_ret); - } - static Variant::Type get_return_type() { return Variant::BOOL; } -}; - -class OperatorEvaluatorNotInt { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - *r_ret = !*VariantGetInternalPtr<int64_t>::get_ptr(&p_left); - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<bool>::change(r_ret); - *VariantGetInternalPtr<bool>::get_ptr(r_ret) = !*VariantGetInternalPtr<int64_t>::get_ptr(left); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<bool>::encode(!PtrToArg<int64_t>::convert(left), r_ret); - } - static Variant::Type get_return_type() { return Variant::BOOL; } -}; - -class OperatorEvaluatorNotFloat { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - *r_ret = !*VariantGetInternalPtr<double>::get_ptr(&p_left); - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<bool>::change(r_ret); - *VariantGetInternalPtr<bool>::get_ptr(r_ret) = !*VariantGetInternalPtr<double>::get_ptr(left); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<bool>::encode(!PtrToArg<double>::convert(left), r_ret); - } - static Variant::Type get_return_type() { return Variant::BOOL; } -}; - -class OperatorEvaluatorNotObject { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - *r_ret = p_left.get_validated_object() == nullptr; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<bool>::change(r_ret); - *VariantGetInternalPtr<bool>::get_ptr(r_ret) = left->get_validated_object() == nullptr; - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<bool>::encode(PtrToArg<Object *>::convert(left) == nullptr, r_ret); - } - static Variant::Type get_return_type() { return Variant::BOOL; } -}; - -//// - -class OperatorEvaluatorInStringFind { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const String &str_a = *VariantGetInternalPtr<String>::get_ptr(&p_left); - const String &str_b = *VariantGetInternalPtr<String>::get_ptr(&p_right); - - *r_ret = str_b.find(str_a) != -1; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - const String &str_a = *VariantGetInternalPtr<String>::get_ptr(left); - const String &str_b = *VariantGetInternalPtr<String>::get_ptr(right); - VariantTypeChanger<bool>::change(r_ret); - *VariantGetInternalPtr<bool>::get_ptr(r_ret) = str_b.find(str_a) != -1; - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<bool>::encode(PtrToArg<String>::convert(right).find(PtrToArg<String>::convert(left)) != -1, r_ret); - } - static Variant::Type get_return_type() { return Variant::BOOL; } -}; - -template <class A, class B> -class OperatorEvaluatorInArrayFind { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); - const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); - - *r_ret = b.find(a) != -1; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - const A &a = *VariantGetInternalPtr<A>::get_ptr(left); - const B &b = *VariantGetInternalPtr<B>::get_ptr(right); - VariantTypeChanger<bool>::change(r_ret); - *VariantGetInternalPtr<bool>::get_ptr(r_ret) = b.find(a) != -1; - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<bool>::encode(PtrToArg<B>::convert(right).find(PtrToArg<A>::convert(left)) != -1, r_ret); - } - static Variant::Type get_return_type() { return Variant::BOOL; } -}; - -class OperatorEvaluatorInArrayFindNil { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const Array &b = *VariantGetInternalPtr<Array>::get_ptr(&p_right); - *r_ret = b.find(Variant()) != -1; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - const Array &b = *VariantGetInternalPtr<Array>::get_ptr(right); - VariantTypeChanger<bool>::change(r_ret); - *VariantGetInternalPtr<bool>::get_ptr(r_ret) = b.find(Variant()) != -1; - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<bool>::encode(PtrToArg<Array>::convert(right).find(Variant()) != -1, r_ret); - } - static Variant::Type get_return_type() { return Variant::BOOL; } -}; - -class OperatorEvaluatorInArrayFindObject { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const Array &b = *VariantGetInternalPtr<Array>::get_ptr(&p_right); - *r_ret = b.find(p_left) != -1; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - const Array &b = *VariantGetInternalPtr<Array>::get_ptr(right); - VariantTypeChanger<bool>::change(r_ret); - *VariantGetInternalPtr<bool>::get_ptr(r_ret) = b.find(*left) != -1; - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<bool>::encode(PtrToArg<Array>::convert(right).find(PtrToArg<Object *>::convert(left)) != -1, r_ret); - } - static Variant::Type get_return_type() { return Variant::BOOL; } -}; - -template <class A> -class OperatorEvaluatorInDictionaryHas { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const Dictionary &b = *VariantGetInternalPtr<Dictionary>::get_ptr(&p_right); - const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); - - *r_ret = b.has(a); - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - const Dictionary &b = *VariantGetInternalPtr<Dictionary>::get_ptr(right); - const A &a = *VariantGetInternalPtr<A>::get_ptr(left); - VariantTypeChanger<bool>::change(r_ret); - *VariantGetInternalPtr<bool>::get_ptr(r_ret) = b.has(a); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<bool>::encode(PtrToArg<Dictionary>::convert(right).has(PtrToArg<A>::convert(left)), r_ret); - } - static Variant::Type get_return_type() { return Variant::BOOL; } -}; - -class OperatorEvaluatorInDictionaryHasNil { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const Dictionary &b = *VariantGetInternalPtr<Dictionary>::get_ptr(&p_right); - - *r_ret = b.has(Variant()); - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - const Dictionary &b = *VariantGetInternalPtr<Dictionary>::get_ptr(right); - VariantTypeChanger<bool>::change(r_ret); - *VariantGetInternalPtr<bool>::get_ptr(r_ret) = b.has(Variant()); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<bool>::encode(PtrToArg<Dictionary>::convert(right).has(Variant()), r_ret); - } - static Variant::Type get_return_type() { return Variant::BOOL; } -}; - -class OperatorEvaluatorInDictionaryHasObject { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const Dictionary &b = *VariantGetInternalPtr<Dictionary>::get_ptr(&p_right); - - *r_ret = b.has(p_left); - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - const Dictionary &b = *VariantGetInternalPtr<Dictionary>::get_ptr(right); - VariantTypeChanger<bool>::change(r_ret); - *VariantGetInternalPtr<bool>::get_ptr(r_ret) = b.has(*left); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<bool>::encode(PtrToArg<Dictionary>::convert(right).has(PtrToArg<Object *>::convert(left)), r_ret); - } - static Variant::Type get_return_type() { return Variant::BOOL; } -}; - -class OperatorEvaluatorObjectHasPropertyString { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - Object *b = p_right.get_validated_object(); - if (!b) { - *r_ret = "Invalid base object for 'in'"; - r_valid = false; - return; - } - - const String &a = *VariantGetInternalPtr<String>::get_ptr(&p_left); - - b->get(a, &r_valid); - *r_ret = r_valid; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - Object *l = right->get_validated_object(); - ERR_FAIL_COND(l == nullptr); - const String &a = *VariantGetInternalPtr<String>::get_ptr(left); - - bool valid; - l->get(a, &valid); - VariantTypeChanger<bool>::change(r_ret); - *VariantGetInternalPtr<bool>::get_ptr(r_ret) = valid; - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - bool valid; - PtrToArg<Object *>::convert(right)->get(PtrToArg<String>::convert(left), &valid); - PtrToArg<bool>::encode(valid, r_ret); - } - static Variant::Type get_return_type() { return Variant::BOOL; } -}; - -class OperatorEvaluatorObjectHasPropertyStringName { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - Object *b = p_right.get_validated_object(); - if (!b) { - *r_ret = "Invalid base object for 'in'"; - r_valid = false; - return; - } - - const StringName &a = *VariantGetInternalPtr<StringName>::get_ptr(&p_left); - - b->get(a, &r_valid); - *r_ret = r_valid; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - Object *l = right->get_validated_object(); - ERR_FAIL_COND(l == nullptr); - const StringName &a = *VariantGetInternalPtr<StringName>::get_ptr(left); - - bool valid; - l->get(a, &valid); - VariantTypeChanger<bool>::change(r_ret); - *VariantGetInternalPtr<bool>::get_ptr(r_ret) = valid; - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - bool valid; - PtrToArg<Object *>::convert(right)->get(PtrToArg<StringName>::convert(left), &valid); - PtrToArg<bool>::encode(valid, r_ret); - } - static Variant::Type get_return_type() { return Variant::BOOL; } -}; +#include "variant_op.h" typedef void (*VariantEvaluatorFunction)(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid); @@ -1458,6 +123,8 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorMul<Color, Color, double>>(Variant::OP_MULTIPLY, Variant::COLOR, Variant::FLOAT); register_op<OperatorEvaluatorMul<Transform2D, Transform2D, Transform2D>>(Variant::OP_MULTIPLY, Variant::TRANSFORM2D, Variant::TRANSFORM2D); + register_op<OperatorEvaluatorMul<Transform2D, Transform2D, int64_t>>(Variant::OP_MULTIPLY, Variant::TRANSFORM2D, Variant::INT); + register_op<OperatorEvaluatorMul<Transform2D, Transform2D, double>>(Variant::OP_MULTIPLY, Variant::TRANSFORM2D, Variant::FLOAT); register_op<OperatorEvaluatorXForm<Vector2, Transform2D, Vector2>>(Variant::OP_MULTIPLY, Variant::TRANSFORM2D, Variant::VECTOR2); register_op<OperatorEvaluatorXFormInv<Vector2, Vector2, Transform2D>>(Variant::OP_MULTIPLY, Variant::VECTOR2, Variant::TRANSFORM2D); register_op<OperatorEvaluatorXForm<Rect2, Transform2D, Rect2>>(Variant::OP_MULTIPLY, Variant::TRANSFORM2D, Variant::RECT2); @@ -1466,6 +133,8 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorXFormInv<Vector<Vector2>, Vector<Vector2>, Transform2D>>(Variant::OP_MULTIPLY, Variant::PACKED_VECTOR2_ARRAY, Variant::TRANSFORM2D); register_op<OperatorEvaluatorMul<Transform3D, Transform3D, Transform3D>>(Variant::OP_MULTIPLY, Variant::TRANSFORM3D, Variant::TRANSFORM3D); + register_op<OperatorEvaluatorMul<Transform3D, Transform3D, int64_t>>(Variant::OP_MULTIPLY, Variant::TRANSFORM3D, Variant::INT); + register_op<OperatorEvaluatorMul<Transform3D, Transform3D, double>>(Variant::OP_MULTIPLY, Variant::TRANSFORM3D, Variant::FLOAT); register_op<OperatorEvaluatorXForm<Vector3, Transform3D, Vector3>>(Variant::OP_MULTIPLY, Variant::TRANSFORM3D, Variant::VECTOR3); register_op<OperatorEvaluatorXFormInv<Vector3, Vector3, Transform3D>>(Variant::OP_MULTIPLY, Variant::VECTOR3, Variant::TRANSFORM3D); register_op<OperatorEvaluatorXForm<::AABB, Transform3D, ::AABB>>(Variant::OP_MULTIPLY, Variant::TRANSFORM3D, Variant::AABB); @@ -1474,6 +143,8 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorXFormInv<Vector<Vector3>, Vector<Vector3>, Transform3D>>(Variant::OP_MULTIPLY, Variant::PACKED_VECTOR3_ARRAY, Variant::TRANSFORM3D); register_op<OperatorEvaluatorMul<Basis, Basis, Basis>>(Variant::OP_MULTIPLY, Variant::BASIS, Variant::BASIS); + register_op<OperatorEvaluatorMul<Basis, Basis, int64_t>>(Variant::OP_MULTIPLY, Variant::BASIS, Variant::INT); + register_op<OperatorEvaluatorMul<Basis, Basis, double>>(Variant::OP_MULTIPLY, Variant::BASIS, Variant::FLOAT); register_op<OperatorEvaluatorXForm<Vector3, Basis, Vector3>>(Variant::OP_MULTIPLY, Variant::BASIS, Variant::VECTOR3); register_op<OperatorEvaluatorXFormInv<Vector3, Vector3, Basis>>(Variant::OP_MULTIPLY, Variant::VECTOR3, Variant::BASIS); @@ -1500,7 +171,7 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorDiv<Vector2, Vector2, double>>(Variant::OP_DIVIDE, Variant::VECTOR2, Variant::FLOAT); register_op<OperatorEvaluatorDiv<Vector2, Vector2, int64_t>>(Variant::OP_DIVIDE, Variant::VECTOR2, Variant::INT); - register_op<OperatorEvaluatorDiv<Vector2i, Vector2i, Vector2i>>(Variant::OP_DIVIDE, Variant::VECTOR2I, Variant::VECTOR2I); + register_op<OperatorEvaluatorDivNZ<Vector2i, Vector2i, Vector2i>>(Variant::OP_DIVIDE, Variant::VECTOR2I, Variant::VECTOR2I); register_op<OperatorEvaluatorDivNZ<Vector2i, Vector2i, double>>(Variant::OP_DIVIDE, Variant::VECTOR2I, Variant::FLOAT); register_op<OperatorEvaluatorDivNZ<Vector2i, Vector2i, int64_t>>(Variant::OP_DIVIDE, Variant::VECTOR2I, Variant::INT); @@ -1512,7 +183,7 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorDiv<Vector3, Vector3, double>>(Variant::OP_DIVIDE, Variant::VECTOR3, Variant::FLOAT); register_op<OperatorEvaluatorDiv<Vector3, Vector3, int64_t>>(Variant::OP_DIVIDE, Variant::VECTOR3, Variant::INT); - register_op<OperatorEvaluatorDiv<Vector3i, Vector3i, Vector3i>>(Variant::OP_DIVIDE, Variant::VECTOR3I, Variant::VECTOR3I); + register_op<OperatorEvaluatorDivNZ<Vector3i, Vector3i, Vector3i>>(Variant::OP_DIVIDE, Variant::VECTOR3I, Variant::VECTOR3I); register_op<OperatorEvaluatorDivNZ<Vector3i, Vector3i, double>>(Variant::OP_DIVIDE, Variant::VECTOR3I, Variant::FLOAT); register_op<OperatorEvaluatorDivNZ<Vector3i, Vector3i, int64_t>>(Variant::OP_DIVIDE, Variant::VECTOR3I, Variant::INT); @@ -1524,10 +195,10 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorDiv<Color, Color, int64_t>>(Variant::OP_DIVIDE, Variant::COLOR, Variant::INT); register_op<OperatorEvaluatorModNZ<int64_t, int64_t, int64_t>>(Variant::OP_MODULE, Variant::INT, Variant::INT); - register_op<OperatorEvaluatorMod<Vector2i, Vector2i, Vector2i>>(Variant::OP_MODULE, Variant::VECTOR2I, Variant::VECTOR2I); + register_op<OperatorEvaluatorModNZ<Vector2i, Vector2i, Vector2i>>(Variant::OP_MODULE, Variant::VECTOR2I, Variant::VECTOR2I); register_op<OperatorEvaluatorModNZ<Vector2i, Vector2i, int64_t>>(Variant::OP_MODULE, Variant::VECTOR2I, Variant::INT); - register_op<OperatorEvaluatorMod<Vector3i, Vector3i, Vector3i>>(Variant::OP_MODULE, Variant::VECTOR3I, Variant::VECTOR3I); + register_op<OperatorEvaluatorModNZ<Vector3i, Vector3i, Vector3i>>(Variant::OP_MODULE, Variant::VECTOR3I, Variant::VECTOR3I); register_op<OperatorEvaluatorModNZ<Vector3i, Vector3i, int64_t>>(Variant::OP_MODULE, Variant::VECTOR3I, Variant::INT); register_op<OperatorEvaluatorStringModNil>(Variant::OP_MODULE, Variant::STRING, Variant::NIL); @@ -1990,8 +661,8 @@ static const char *_op_names[Variant::OP_MAX] = { "-", "*", "/", - "-", - "+", + "unary-", + "unary+", "%", "<<", ">>", diff --git a/core/variant/variant_op.h b/core/variant/variant_op.h new file mode 100644 index 0000000000..3c9f849a4f --- /dev/null +++ b/core/variant/variant_op.h @@ -0,0 +1,1416 @@ +/*************************************************************************/ +/* variant_op.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef VARIANT_OP_H +#define VARIANT_OP_H + +#include "variant.h" + +#include "core/core_string_names.h" +#include "core/debugger/engine_debugger.h" +#include "core/object/class_db.h" + +template <class R, class A, class B> +class OperatorEvaluatorAdd { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + *r_ret = a + b; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) + *VariantGetInternalPtr<B>::get_ptr(right); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<R>::encode(PtrToArg<A>::convert(left) + PtrToArg<B>::convert(right), r_ret); + } + static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } +}; + +template <class R, class A, class B> +class OperatorEvaluatorSub { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + *r_ret = a - b; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) - *VariantGetInternalPtr<B>::get_ptr(right); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<R>::encode(PtrToArg<A>::convert(left) - PtrToArg<B>::convert(right), r_ret); + } + static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } +}; + +template <class R, class A, class B> +class OperatorEvaluatorMul { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + *r_ret = a * b; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) * *VariantGetInternalPtr<B>::get_ptr(right); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<R>::encode(PtrToArg<A>::convert(left) * PtrToArg<B>::convert(right), r_ret); + } + static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } +}; + +template <class R, class A, class B> +class OperatorEvaluatorXForm { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + *r_ret = a.xform(b); + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<R>::get_ptr(r_ret) = VariantGetInternalPtr<A>::get_ptr(left)->xform(*VariantGetInternalPtr<B>::get_ptr(right)); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<R>::encode(PtrToArg<A>::convert(left).xform(PtrToArg<B>::convert(right)), r_ret); + } + static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } +}; + +template <class R, class A, class B> +class OperatorEvaluatorXFormInv { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + *r_ret = b.xform_inv(a); + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<R>::get_ptr(r_ret) = VariantGetInternalPtr<B>::get_ptr(right)->xform_inv(*VariantGetInternalPtr<A>::get_ptr(left)); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<R>::encode(PtrToArg<B>::convert(right).xform_inv(PtrToArg<A>::convert(left)), r_ret); + } + static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } +}; + +template <class R, class A, class B> +class OperatorEvaluatorDiv { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + *r_ret = a / b; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) / *VariantGetInternalPtr<B>::get_ptr(right); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<R>::encode(PtrToArg<A>::convert(left) / PtrToArg<B>::convert(right), r_ret); + } + static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } +}; + +template <class R, class A, class B> +class OperatorEvaluatorDivNZ { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + if (b == 0) { + r_valid = false; + *r_ret = "Division by zero error"; + return; + } + *r_ret = a / b; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) / *VariantGetInternalPtr<B>::get_ptr(right); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<R>::encode(PtrToArg<A>::convert(left) / PtrToArg<B>::convert(right), r_ret); + } + static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } +}; + +template <> +class OperatorEvaluatorDivNZ<Vector2i, Vector2i, Vector2i> { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const Vector2i &a = *VariantGetInternalPtr<Vector2i>::get_ptr(&p_left); + const Vector2i &b = *VariantGetInternalPtr<Vector2i>::get_ptr(&p_right); + if (unlikely(b.x == 0 || b.y == 0)) { + r_valid = false; + *r_ret = "Division by zero error"; + return; + } + *r_ret = a / b; + r_valid = true; + } + static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<Vector2i>::change(r_ret); + *VariantGetInternalPtr<Vector2i>::get_ptr(r_ret) = *VariantGetInternalPtr<Vector2i>::get_ptr(left) / *VariantGetInternalPtr<Vector2i>::get_ptr(right); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<Vector2i>::encode(PtrToArg<Vector2i>::convert(left) / PtrToArg<Vector2i>::convert(right), r_ret); + } + static Variant::Type get_return_type() { return GetTypeInfo<Vector2i>::VARIANT_TYPE; } +}; + +template <> +class OperatorEvaluatorDivNZ<Vector3i, Vector3i, Vector3i> { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const Vector3i &a = *VariantGetInternalPtr<Vector3i>::get_ptr(&p_left); + const Vector3i &b = *VariantGetInternalPtr<Vector3i>::get_ptr(&p_right); + if (unlikely(b.x == 0 || b.y == 0 || b.z == 0)) { + r_valid = false; + *r_ret = "Division by zero error"; + return; + } + *r_ret = a / b; + r_valid = true; + } + static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<Vector3i>::change(r_ret); + *VariantGetInternalPtr<Vector3i>::get_ptr(r_ret) = *VariantGetInternalPtr<Vector3i>::get_ptr(left) / *VariantGetInternalPtr<Vector3i>::get_ptr(right); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<Vector3i>::encode(PtrToArg<Vector3i>::convert(left) / PtrToArg<Vector3i>::convert(right), r_ret); + } + static Variant::Type get_return_type() { return GetTypeInfo<Vector3i>::VARIANT_TYPE; } +}; + +template <class R, class A, class B> +class OperatorEvaluatorMod { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + *r_ret = a % b; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) % *VariantGetInternalPtr<B>::get_ptr(right); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<R>::encode(PtrToArg<A>::convert(left) % PtrToArg<B>::convert(right), r_ret); + } + static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } +}; + +template <class R, class A, class B> +class OperatorEvaluatorModNZ { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + if (b == 0) { + r_valid = false; + *r_ret = "Module by zero error"; + return; + } + *r_ret = a % b; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) % *VariantGetInternalPtr<B>::get_ptr(right); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<R>::encode(PtrToArg<A>::convert(left) % PtrToArg<B>::convert(right), r_ret); + } + static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } +}; + +template <> +class OperatorEvaluatorModNZ<Vector2i, Vector2i, Vector2i> { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const Vector2i &a = *VariantGetInternalPtr<Vector2i>::get_ptr(&p_left); + const Vector2i &b = *VariantGetInternalPtr<Vector2i>::get_ptr(&p_right); + if (unlikely(b.x == 0 || b.y == 0)) { + r_valid = false; + *r_ret = "Module by zero error"; + return; + } + *r_ret = a % b; + r_valid = true; + } + static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<Vector2i>::change(r_ret); + *VariantGetInternalPtr<Vector2i>::get_ptr(r_ret) = *VariantGetInternalPtr<Vector2i>::get_ptr(left) % *VariantGetInternalPtr<Vector2i>::get_ptr(right); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<Vector2i>::encode(PtrToArg<Vector2i>::convert(left) / PtrToArg<Vector2i>::convert(right), r_ret); + } + static Variant::Type get_return_type() { return GetTypeInfo<Vector2i>::VARIANT_TYPE; } +}; + +template <> +class OperatorEvaluatorModNZ<Vector3i, Vector3i, Vector3i> { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const Vector3i &a = *VariantGetInternalPtr<Vector3i>::get_ptr(&p_left); + const Vector3i &b = *VariantGetInternalPtr<Vector3i>::get_ptr(&p_right); + if (unlikely(b.x == 0 || b.y == 0 || b.z == 0)) { + r_valid = false; + *r_ret = "Module by zero error"; + return; + } + *r_ret = a % b; + r_valid = true; + } + static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<Vector3i>::change(r_ret); + *VariantGetInternalPtr<Vector3i>::get_ptr(r_ret) = *VariantGetInternalPtr<Vector3i>::get_ptr(left) % *VariantGetInternalPtr<Vector3i>::get_ptr(right); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<Vector3i>::encode(PtrToArg<Vector3i>::convert(left) % PtrToArg<Vector3i>::convert(right), r_ret); + } + static Variant::Type get_return_type() { return GetTypeInfo<Vector3i>::VARIANT_TYPE; } +}; + +template <class R, class A> +class OperatorEvaluatorNeg { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + *r_ret = -a; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<R>::get_ptr(r_ret) = -*VariantGetInternalPtr<A>::get_ptr(left); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<R>::encode(-PtrToArg<A>::convert(left), r_ret); + } + static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } +}; + +template <class R, class A> +class OperatorEvaluatorPos { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + *r_ret = a; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<R>::encode(PtrToArg<A>::convert(left), r_ret); + } + static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } +}; + +template <class R, class A, class B> +class OperatorEvaluatorShiftLeft { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + +#if defined(DEBUG_ENABLED) + if (b < 0 || a < 0) { + *r_ret = "Invalid operands for bit shifting. Only positive operands are supported."; + r_valid = false; + return; + } +#endif + *r_ret = a << b; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) << *VariantGetInternalPtr<B>::get_ptr(right); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<R>::encode(PtrToArg<A>::convert(left) << PtrToArg<B>::convert(right), r_ret); + } + static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } +}; + +template <class R, class A, class B> +class OperatorEvaluatorShiftRight { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + +#if defined(DEBUG_ENABLED) + if (b < 0 || a < 0) { + *r_ret = "Invalid operands for bit shifting. Only positive operands are supported."; + r_valid = false; + return; + } +#endif + *r_ret = a >> b; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) >> *VariantGetInternalPtr<B>::get_ptr(right); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<R>::encode(PtrToArg<A>::convert(left) >> PtrToArg<B>::convert(right), r_ret); + } + static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } +}; + +template <class R, class A, class B> +class OperatorEvaluatorBitOr { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + *r_ret = a | b; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) | *VariantGetInternalPtr<B>::get_ptr(right); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<R>::encode(PtrToArg<A>::convert(left) | PtrToArg<B>::convert(right), r_ret); + } + static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } +}; + +template <class R, class A, class B> +class OperatorEvaluatorBitAnd { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + *r_ret = a & b; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) & *VariantGetInternalPtr<B>::get_ptr(right); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<R>::encode(PtrToArg<A>::convert(left) & PtrToArg<B>::convert(right), r_ret); + } + static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } +}; + +template <class R, class A, class B> +class OperatorEvaluatorBitXor { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + *r_ret = a ^ b; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) ^ *VariantGetInternalPtr<B>::get_ptr(right); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<R>::encode(PtrToArg<A>::convert(left) ^ PtrToArg<B>::convert(right), r_ret); + } + static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } +}; + +template <class R, class A> +class OperatorEvaluatorBitNeg { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + *r_ret = ~a; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<R>::get_ptr(r_ret) = ~*VariantGetInternalPtr<A>::get_ptr(left); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<R>::encode(~PtrToArg<A>::convert(left), r_ret); + } + static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } +}; + +template <class A, class B> +class OperatorEvaluatorEqual { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + *r_ret = a == b; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) == *VariantGetInternalPtr<B>::get_ptr(right); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(PtrToArg<A>::convert(left) == PtrToArg<B>::convert(right), r_ret); + } + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +class OperatorEvaluatorEqualObject { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const Object *a = p_left.get_validated_object(); + const Object *b = p_right.get_validated_object(); + *r_ret = a == b; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + const Object *a = left->get_validated_object(); + const Object *b = right->get_validated_object(); + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = a == b; + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(PtrToArg<Object *>::convert(left) == PtrToArg<Object *>::convert(right), r_ret); + } + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +class OperatorEvaluatorEqualObjectNil { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const Object *a = p_left.get_validated_object(); + *r_ret = a == nullptr; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + const Object *a = left->get_validated_object(); + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = a == nullptr; + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(PtrToArg<Object *>::convert(left) == nullptr, r_ret); + } + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +class OperatorEvaluatorEqualNilObject { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const Object *b = p_right.get_validated_object(); + *r_ret = nullptr == b; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + const Object *b = right->get_validated_object(); + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = nullptr == b; + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(nullptr == PtrToArg<Object *>::convert(right), r_ret); + } + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +template <class A, class B> +class OperatorEvaluatorNotEqual { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + *r_ret = a != b; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) != *VariantGetInternalPtr<B>::get_ptr(right); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(PtrToArg<A>::convert(left) != PtrToArg<B>::convert(right), r_ret); + } + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +class OperatorEvaluatorNotEqualObject { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + Object *a = p_left.get_validated_object(); + Object *b = p_right.get_validated_object(); + *r_ret = a != b; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + Object *a = left->get_validated_object(); + Object *b = right->get_validated_object(); + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = a != b; + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(PtrToArg<Object *>::convert(left) != PtrToArg<Object *>::convert(right), r_ret); + } + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +class OperatorEvaluatorNotEqualObjectNil { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + Object *a = p_left.get_validated_object(); + *r_ret = a != nullptr; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + Object *a = left->get_validated_object(); + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = a != nullptr; + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(PtrToArg<Object *>::convert(left) != nullptr, r_ret); + } + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +class OperatorEvaluatorNotEqualNilObject { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + Object *b = p_right.get_validated_object(); + *r_ret = nullptr != b; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + Object *b = right->get_validated_object(); + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = nullptr != b; + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(nullptr != PtrToArg<Object *>::convert(right), r_ret); + } + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +template <class A, class B> +class OperatorEvaluatorLess { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + *r_ret = a < b; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) < *VariantGetInternalPtr<B>::get_ptr(right); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(PtrToArg<A>::convert(left) < PtrToArg<B>::convert(right), r_ret); + } + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +template <class A, class B> +class OperatorEvaluatorLessEqual { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + *r_ret = a <= b; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) <= *VariantGetInternalPtr<B>::get_ptr(right); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(PtrToArg<A>::convert(left) <= PtrToArg<B>::convert(right), r_ret); + } + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +template <class A, class B> +class OperatorEvaluatorGreater { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + *r_ret = a > b; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) > *VariantGetInternalPtr<B>::get_ptr(right); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(PtrToArg<A>::convert(left) > PtrToArg<B>::convert(right), r_ret); + } + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +template <class A, class B> +class OperatorEvaluatorGreaterEqual { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + *r_ret = a >= b; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) >= *VariantGetInternalPtr<B>::get_ptr(right); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(PtrToArg<A>::convert(left) >= PtrToArg<B>::convert(right), r_ret); + } + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +template <class A, class B> +class OperatorEvaluatorAnd { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + *r_ret = a && b; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) && *VariantGetInternalPtr<B>::get_ptr(right); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(PtrToArg<A>::convert(left) && PtrToArg<B>::convert(right), r_ret); + } + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +template <class A, class B> +class OperatorEvaluatorOr { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + *r_ret = a || b; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) || *VariantGetInternalPtr<B>::get_ptr(right); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(PtrToArg<A>::convert(left) || PtrToArg<B>::convert(right), r_ret); + } + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +#define XOR_OP(m_a, m_b) (((m_a) || (m_b)) && !((m_a) && (m_b))) +template <class A, class B> +class OperatorEvaluatorXor { +public: + _FORCE_INLINE_ static bool xor_op(const A &a, const B &b) { + return ((a) || (b)) && !((a) && (b)); + } + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + *r_ret = xor_op(a, b); + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = xor_op(*VariantGetInternalPtr<A>::get_ptr(left), *VariantGetInternalPtr<B>::get_ptr(right)); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(xor_op(PtrToArg<A>::convert(left), PtrToArg<B>::convert(right)), r_ret); + } + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +template <class A> +class OperatorEvaluatorNot { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + *r_ret = !a; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = !*VariantGetInternalPtr<A>::get_ptr(left); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(!PtrToArg<A>::convert(left)); + } + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +//// CUSTOM //// + +class OperatorEvaluatorAddArray { +public: + _FORCE_INLINE_ static void _add_arrays(Array &sum, const Array &array_a, const Array &array_b) { + int asize = array_a.size(); + int bsize = array_b.size(); + sum.resize(asize + bsize); + for (int i = 0; i < asize; i++) { + sum[i] = array_a[i]; + } + for (int i = 0; i < bsize; i++) { + sum[i + asize] = array_b[i]; + } + } + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const Array &array_a = *VariantGetInternalPtr<Array>::get_ptr(&p_left); + const Array &array_b = *VariantGetInternalPtr<Array>::get_ptr(&p_right); + Array sum; + _add_arrays(sum, array_a, array_b); + *r_ret = sum; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + _add_arrays(*VariantGetInternalPtr<Array>::get_ptr(r_ret), *VariantGetInternalPtr<Array>::get_ptr(left), *VariantGetInternalPtr<Array>::get_ptr(right)); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + Array ret; + _add_arrays(ret, PtrToArg<Array>::convert(left), PtrToArg<Array>::convert(right)); + PtrToArg<Array>::encode(ret, r_ret); + } + static Variant::Type get_return_type() { return Variant::ARRAY; } +}; + +template <class T> +class OperatorEvaluatorAppendArray { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const Vector<T> &array_a = *VariantGetInternalPtr<Vector<T>>::get_ptr(&p_left); + const Vector<T> &array_b = *VariantGetInternalPtr<Vector<T>>::get_ptr(&p_right); + Vector<T> sum = array_a; + sum.append_array(array_b); + *r_ret = sum; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<Vector<T>>::get_ptr(r_ret) = *VariantGetInternalPtr<Vector<T>>::get_ptr(left); + VariantGetInternalPtr<Vector<T>>::get_ptr(r_ret)->append_array(*VariantGetInternalPtr<Vector<T>>::get_ptr(right)); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + Vector<T> sum = PtrToArg<Vector<T>>::convert(left); + sum.append_array(PtrToArg<Vector<T>>::convert(right)); + PtrToArg<Vector<T>>::encode(sum, r_ret); + } + static Variant::Type get_return_type() { return GetTypeInfo<Vector<T>>::VARIANT_TYPE; } +}; + +class OperatorEvaluatorStringModNil { +public: + _FORCE_INLINE_ static String do_mod(const String &s, bool *r_valid) { + Array values; + values.push_back(Variant()); + + String a = s.sprintf(values, r_valid); + if (r_valid) { + *r_valid = !*r_valid; + } + return a; + } + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const String &a = *VariantGetInternalPtr<String>::get_ptr(&p_left); + *r_ret = do_mod(a, &r_valid); + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<String>::get_ptr(r_ret) = do_mod(*VariantGetInternalPtr<String>::get_ptr(left), nullptr); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<String>::encode(do_mod(PtrToArg<String>::convert(left), nullptr), r_ret); + } + static Variant::Type get_return_type() { return Variant::STRING; } +}; + +class OperatorEvaluatorStringModArray { +public: + _FORCE_INLINE_ static String do_mod(const String &s, const Array &p_values, bool *r_valid) { + String a = s.sprintf(p_values, r_valid); + if (r_valid) { + *r_valid = !*r_valid; + } + return a; + } + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const String &a = *VariantGetInternalPtr<String>::get_ptr(&p_left); + *r_ret = do_mod(a, *VariantGetInternalPtr<Array>::get_ptr(&p_right), &r_valid); + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<String>::get_ptr(r_ret) = do_mod(*VariantGetInternalPtr<String>::get_ptr(left), *VariantGetInternalPtr<Array>::get_ptr(right), nullptr); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<String>::encode(do_mod(PtrToArg<String>::convert(left), PtrToArg<Array>::convert(right), nullptr), r_ret); + } + static Variant::Type get_return_type() { return Variant::STRING; } +}; + +class OperatorEvaluatorStringModObject { +public: + _FORCE_INLINE_ static String do_mod(const String &s, const Object *p_object, bool *r_valid) { + Array values; + values.push_back(p_object); + String a = s.sprintf(values, r_valid); + if (r_valid) { + *r_valid = !*r_valid; + } + + return a; + } + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const String &a = *VariantGetInternalPtr<String>::get_ptr(&p_left); + *r_ret = do_mod(a, p_right.get_validated_object(), &r_valid); + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<String>::get_ptr(r_ret) = do_mod(*VariantGetInternalPtr<String>::get_ptr(left), right->get_validated_object(), nullptr); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<String>::encode(do_mod(PtrToArg<String>::convert(left), PtrToArg<Object *>::convert(right), nullptr), r_ret); + } + static Variant::Type get_return_type() { return Variant::STRING; } +}; + +template <class T> +class OperatorEvaluatorStringModT { +public: + _FORCE_INLINE_ static String do_mod(const String &s, const T &p_value, bool *r_valid) { + Array values; + values.push_back(p_value); + String a = s.sprintf(values, r_valid); + if (r_valid) { + *r_valid = !*r_valid; + } + return a; + } + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const String &a = *VariantGetInternalPtr<String>::get_ptr(&p_left); + *r_ret = do_mod(a, *VariantGetInternalPtr<T>::get_ptr(&p_right), &r_valid); + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<String>::get_ptr(r_ret) = do_mod(*VariantGetInternalPtr<String>::get_ptr(left), *VariantGetInternalPtr<T>::get_ptr(right), nullptr); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<String>::encode(do_mod(PtrToArg<String>::convert(left), PtrToArg<T>::convert(right), nullptr), r_ret); + } + static Variant::Type get_return_type() { return Variant::STRING; } +}; + +template <Variant::Operator op, Variant::Type type_left, Variant::Type type_right> +class OperatorEvaluatorAlwaysTrue { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + *r_ret = true; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = true; + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(true, r_ret); + } + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +template <Variant::Operator op, Variant::Type type_left, Variant::Type type_right> +class OperatorEvaluatorAlwaysFalse { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + *r_ret = false; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = false; + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(false, r_ret); + } + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +///// OR /////// + +_FORCE_INLINE_ static bool _operate_or(bool p_left, bool p_right) { + return p_left || p_right; +} + +_FORCE_INLINE_ static bool _operate_and(bool p_left, bool p_right) { + return p_left && p_right; +} + +_FORCE_INLINE_ static bool _operate_xor(bool p_left, bool p_right) { + return (p_left || p_right) && !(p_left && p_right); +} + +_FORCE_INLINE_ static bool _operate_get_nil(const Variant *p_ptr) { + return p_ptr->get_validated_object() != nullptr; +} + +_FORCE_INLINE_ static bool _operate_get_bool(const Variant *p_ptr) { + return *VariantGetInternalPtr<bool>::get_ptr(p_ptr); +} + +_FORCE_INLINE_ static bool _operate_get_int(const Variant *p_ptr) { + return *VariantGetInternalPtr<int64_t>::get_ptr(p_ptr) != 0; +} + +_FORCE_INLINE_ static bool _operate_get_float(const Variant *p_ptr) { + return *VariantGetInternalPtr<double>::get_ptr(p_ptr) != 0.0; +} + +_FORCE_INLINE_ static bool _operate_get_object(const Variant *p_ptr) { + return p_ptr->get_validated_object() != nullptr; +} + +_FORCE_INLINE_ static bool _operate_get_ptr_nil(const void *p_ptr) { + return false; +} + +_FORCE_INLINE_ static bool _operate_get_ptr_bool(const void *p_ptr) { + return PtrToArg<bool>::convert(p_ptr); +} + +_FORCE_INLINE_ static bool _operate_get_ptr_int(const void *p_ptr) { + return PtrToArg<int64_t>::convert(p_ptr) != 0; +} + +_FORCE_INLINE_ static bool _operate_get_ptr_float(const void *p_ptr) { + return PtrToArg<double>::convert(p_ptr) != 0.0; +} + +_FORCE_INLINE_ static bool _operate_get_ptr_object(const void *p_ptr) { + return PtrToArg<Object *>::convert(p_ptr) != nullptr; +} + +#define OP_EVALUATOR(m_class_name, m_left, m_right, m_op) \ + class m_class_name { \ + public: \ + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { \ + *r_ret = m_op(_operate_get_##m_left(&p_left), _operate_get_##m_right(&p_right)); \ + r_valid = true; \ + } \ + \ + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { \ + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = m_op(_operate_get_##m_left(left), _operate_get_##m_right(right)); \ + } \ + \ + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { \ + PtrToArg<bool>::encode(m_op(_operate_get_ptr_##m_left(left), _operate_get_ptr_##m_right(right)), r_ret); \ + } \ + \ + static Variant::Type get_return_type() { \ + return Variant::BOOL; \ + } \ + }; + +// OR + +// nil +OP_EVALUATOR(OperatorEvaluatorNilXBoolOr, nil, bool, _operate_or) +OP_EVALUATOR(OperatorEvaluatorBoolXNilOr, bool, nil, _operate_or) + +OP_EVALUATOR(OperatorEvaluatorNilXIntOr, nil, int, _operate_or) +OP_EVALUATOR(OperatorEvaluatorIntXNilOr, int, nil, _operate_or) + +OP_EVALUATOR(OperatorEvaluatorNilXFloatOr, nil, float, _operate_or) +OP_EVALUATOR(OperatorEvaluatorFloatXNilOr, float, nil, _operate_or) + +OP_EVALUATOR(OperatorEvaluatorObjectXNilOr, object, nil, _operate_or) +OP_EVALUATOR(OperatorEvaluatorNilXObjectOr, nil, object, _operate_or) + +// bool +OP_EVALUATOR(OperatorEvaluatorBoolXBoolOr, bool, bool, _operate_or) + +OP_EVALUATOR(OperatorEvaluatorBoolXIntOr, bool, int, _operate_or) +OP_EVALUATOR(OperatorEvaluatorIntXBoolOr, int, bool, _operate_or) + +OP_EVALUATOR(OperatorEvaluatorBoolXFloatOr, bool, float, _operate_or) +OP_EVALUATOR(OperatorEvaluatorFloatXBoolOr, float, bool, _operate_or) + +OP_EVALUATOR(OperatorEvaluatorBoolXObjectOr, bool, object, _operate_or) +OP_EVALUATOR(OperatorEvaluatorObjectXBoolOr, object, bool, _operate_or) + +// int +OP_EVALUATOR(OperatorEvaluatorIntXIntOr, int, int, _operate_or) + +OP_EVALUATOR(OperatorEvaluatorIntXFloatOr, int, float, _operate_or) +OP_EVALUATOR(OperatorEvaluatorFloatXIntOr, float, int, _operate_or) + +OP_EVALUATOR(OperatorEvaluatorIntXObjectOr, int, object, _operate_or) +OP_EVALUATOR(OperatorEvaluatorObjectXIntOr, object, int, _operate_or) + +// float +OP_EVALUATOR(OperatorEvaluatorFloatXFloatOr, float, float, _operate_or) + +OP_EVALUATOR(OperatorEvaluatorFloatXObjectOr, float, object, _operate_or) +OP_EVALUATOR(OperatorEvaluatorObjectXFloatOr, object, float, _operate_or) + +// object +OP_EVALUATOR(OperatorEvaluatorObjectXObjectOr, object, object, _operate_or) + +// AND + +// nil +OP_EVALUATOR(OperatorEvaluatorNilXBoolAnd, nil, bool, _operate_and) +OP_EVALUATOR(OperatorEvaluatorBoolXNilAnd, bool, nil, _operate_and) + +OP_EVALUATOR(OperatorEvaluatorNilXIntAnd, nil, int, _operate_and) +OP_EVALUATOR(OperatorEvaluatorIntXNilAnd, int, nil, _operate_and) + +OP_EVALUATOR(OperatorEvaluatorNilXFloatAnd, nil, float, _operate_and) +OP_EVALUATOR(OperatorEvaluatorFloatXNilAnd, float, nil, _operate_and) + +OP_EVALUATOR(OperatorEvaluatorObjectXNilAnd, object, nil, _operate_and) +OP_EVALUATOR(OperatorEvaluatorNilXObjectAnd, nil, object, _operate_and) + +// bool +OP_EVALUATOR(OperatorEvaluatorBoolXBoolAnd, bool, bool, _operate_and) + +OP_EVALUATOR(OperatorEvaluatorBoolXIntAnd, bool, int, _operate_and) +OP_EVALUATOR(OperatorEvaluatorIntXBoolAnd, int, bool, _operate_and) + +OP_EVALUATOR(OperatorEvaluatorBoolXFloatAnd, bool, float, _operate_and) +OP_EVALUATOR(OperatorEvaluatorFloatXBoolAnd, float, bool, _operate_and) + +OP_EVALUATOR(OperatorEvaluatorBoolXObjectAnd, bool, object, _operate_and) +OP_EVALUATOR(OperatorEvaluatorObjectXBoolAnd, object, bool, _operate_and) + +// int +OP_EVALUATOR(OperatorEvaluatorIntXIntAnd, int, int, _operate_and) + +OP_EVALUATOR(OperatorEvaluatorIntXFloatAnd, int, float, _operate_and) +OP_EVALUATOR(OperatorEvaluatorFloatXIntAnd, float, int, _operate_and) + +OP_EVALUATOR(OperatorEvaluatorIntXObjectAnd, int, object, _operate_and) +OP_EVALUATOR(OperatorEvaluatorObjectXIntAnd, object, int, _operate_and) + +// float +OP_EVALUATOR(OperatorEvaluatorFloatXFloatAnd, float, float, _operate_and) + +OP_EVALUATOR(OperatorEvaluatorFloatXObjectAnd, float, object, _operate_and) +OP_EVALUATOR(OperatorEvaluatorObjectXFloatAnd, object, float, _operate_and) + +// object +OP_EVALUATOR(OperatorEvaluatorObjectXObjectAnd, object, object, _operate_and) + +// XOR + +// nil +OP_EVALUATOR(OperatorEvaluatorNilXBoolXor, nil, bool, _operate_xor) +OP_EVALUATOR(OperatorEvaluatorBoolXNilXor, bool, nil, _operate_xor) + +OP_EVALUATOR(OperatorEvaluatorNilXIntXor, nil, int, _operate_xor) +OP_EVALUATOR(OperatorEvaluatorIntXNilXor, int, nil, _operate_xor) + +OP_EVALUATOR(OperatorEvaluatorNilXFloatXor, nil, float, _operate_xor) +OP_EVALUATOR(OperatorEvaluatorFloatXNilXor, float, nil, _operate_xor) + +OP_EVALUATOR(OperatorEvaluatorObjectXNilXor, object, nil, _operate_xor) +OP_EVALUATOR(OperatorEvaluatorNilXObjectXor, nil, object, _operate_xor) + +// bool +OP_EVALUATOR(OperatorEvaluatorBoolXBoolXor, bool, bool, _operate_xor) + +OP_EVALUATOR(OperatorEvaluatorBoolXIntXor, bool, int, _operate_xor) +OP_EVALUATOR(OperatorEvaluatorIntXBoolXor, int, bool, _operate_xor) + +OP_EVALUATOR(OperatorEvaluatorBoolXFloatXor, bool, float, _operate_xor) +OP_EVALUATOR(OperatorEvaluatorFloatXBoolXor, float, bool, _operate_xor) + +OP_EVALUATOR(OperatorEvaluatorBoolXObjectXor, bool, object, _operate_xor) +OP_EVALUATOR(OperatorEvaluatorObjectXBoolXor, object, bool, _operate_xor) + +// int +OP_EVALUATOR(OperatorEvaluatorIntXIntXor, int, int, _operate_xor) + +OP_EVALUATOR(OperatorEvaluatorIntXFloatXor, int, float, _operate_xor) +OP_EVALUATOR(OperatorEvaluatorFloatXIntXor, float, int, _operate_xor) + +OP_EVALUATOR(OperatorEvaluatorIntXObjectXor, int, object, _operate_xor) +OP_EVALUATOR(OperatorEvaluatorObjectXIntXor, object, int, _operate_xor) + +// float +OP_EVALUATOR(OperatorEvaluatorFloatXFloatXor, float, float, _operate_xor) + +OP_EVALUATOR(OperatorEvaluatorFloatXObjectXor, float, object, _operate_xor) +OP_EVALUATOR(OperatorEvaluatorObjectXFloatXor, object, float, _operate_xor) + +// object +OP_EVALUATOR(OperatorEvaluatorObjectXObjectXor, object, object, _operate_xor) + +class OperatorEvaluatorNotBool { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + *r_ret = !*VariantGetInternalPtr<bool>::get_ptr(&p_left); + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = !*VariantGetInternalPtr<bool>::get_ptr(left); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(!PtrToArg<bool>::convert(left), r_ret); + } + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +class OperatorEvaluatorNotInt { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + *r_ret = !*VariantGetInternalPtr<int64_t>::get_ptr(&p_left); + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = !*VariantGetInternalPtr<int64_t>::get_ptr(left); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(!PtrToArg<int64_t>::convert(left), r_ret); + } + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +class OperatorEvaluatorNotFloat { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + *r_ret = !*VariantGetInternalPtr<double>::get_ptr(&p_left); + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = !*VariantGetInternalPtr<double>::get_ptr(left); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(!PtrToArg<double>::convert(left), r_ret); + } + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +class OperatorEvaluatorNotObject { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + *r_ret = p_left.get_validated_object() == nullptr; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = left->get_validated_object() == nullptr; + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(PtrToArg<Object *>::convert(left) == nullptr, r_ret); + } + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +//// + +class OperatorEvaluatorInStringFind { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const String &str_a = *VariantGetInternalPtr<String>::get_ptr(&p_left); + const String &str_b = *VariantGetInternalPtr<String>::get_ptr(&p_right); + + *r_ret = str_b.find(str_a) != -1; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + const String &str_a = *VariantGetInternalPtr<String>::get_ptr(left); + const String &str_b = *VariantGetInternalPtr<String>::get_ptr(right); + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = str_b.find(str_a) != -1; + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(PtrToArg<String>::convert(right).find(PtrToArg<String>::convert(left)) != -1, r_ret); + } + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +template <class A, class B> +class OperatorEvaluatorInArrayFind { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + + *r_ret = b.find(a) != -1; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(right); + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = b.find(a) != -1; + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(PtrToArg<B>::convert(right).find(PtrToArg<A>::convert(left)) != -1, r_ret); + } + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +class OperatorEvaluatorInArrayFindNil { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const Array &b = *VariantGetInternalPtr<Array>::get_ptr(&p_right); + *r_ret = b.find(Variant()) != -1; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + const Array &b = *VariantGetInternalPtr<Array>::get_ptr(right); + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = b.find(Variant()) != -1; + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(PtrToArg<Array>::convert(right).find(Variant()) != -1, r_ret); + } + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +class OperatorEvaluatorInArrayFindObject { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const Array &b = *VariantGetInternalPtr<Array>::get_ptr(&p_right); + *r_ret = b.find(p_left) != -1; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + const Array &b = *VariantGetInternalPtr<Array>::get_ptr(right); + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = b.find(*left) != -1; + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(PtrToArg<Array>::convert(right).find(PtrToArg<Object *>::convert(left)) != -1, r_ret); + } + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +template <class A> +class OperatorEvaluatorInDictionaryHas { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const Dictionary &b = *VariantGetInternalPtr<Dictionary>::get_ptr(&p_right); + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + + *r_ret = b.has(a); + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + const Dictionary &b = *VariantGetInternalPtr<Dictionary>::get_ptr(right); + const A &a = *VariantGetInternalPtr<A>::get_ptr(left); + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = b.has(a); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(PtrToArg<Dictionary>::convert(right).has(PtrToArg<A>::convert(left)), r_ret); + } + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +class OperatorEvaluatorInDictionaryHasNil { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const Dictionary &b = *VariantGetInternalPtr<Dictionary>::get_ptr(&p_right); + + *r_ret = b.has(Variant()); + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + const Dictionary &b = *VariantGetInternalPtr<Dictionary>::get_ptr(right); + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = b.has(Variant()); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(PtrToArg<Dictionary>::convert(right).has(Variant()), r_ret); + } + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +class OperatorEvaluatorInDictionaryHasObject { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const Dictionary &b = *VariantGetInternalPtr<Dictionary>::get_ptr(&p_right); + + *r_ret = b.has(p_left); + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + const Dictionary &b = *VariantGetInternalPtr<Dictionary>::get_ptr(right); + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = b.has(*left); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(PtrToArg<Dictionary>::convert(right).has(PtrToArg<Object *>::convert(left)), r_ret); + } + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +class OperatorEvaluatorObjectHasPropertyString { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + Object *b = p_right.get_validated_object(); + if (!b) { + *r_ret = "Invalid base object for 'in'"; + r_valid = false; + return; + } + + const String &a = *VariantGetInternalPtr<String>::get_ptr(&p_left); + + bool exist; + b->get(a, &exist); + *r_ret = exist; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + Object *l = right->get_validated_object(); + ERR_FAIL_COND(l == nullptr); + const String &a = *VariantGetInternalPtr<String>::get_ptr(left); + + bool valid; + l->get(a, &valid); + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = valid; + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + bool valid; + PtrToArg<Object *>::convert(right)->get(PtrToArg<String>::convert(left), &valid); + PtrToArg<bool>::encode(valid, r_ret); + } + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +class OperatorEvaluatorObjectHasPropertyStringName { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + Object *b = p_right.get_validated_object(); + if (!b) { + *r_ret = "Invalid base object for 'in'"; + r_valid = false; + return; + } + + const StringName &a = *VariantGetInternalPtr<StringName>::get_ptr(&p_left); + + bool exist; + b->get(a, &exist); + *r_ret = exist; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + Object *l = right->get_validated_object(); + ERR_FAIL_COND(l == nullptr); + const StringName &a = *VariantGetInternalPtr<StringName>::get_ptr(left); + + bool valid; + l->get(a, &valid); + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = valid; + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + bool valid; + PtrToArg<Object *>::convert(right)->get(PtrToArg<StringName>::convert(left), &valid); + PtrToArg<bool>::encode(valid, r_ret); + } + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +#endif // VARIANT_OP_H diff --git a/core/variant/variant_parser.cpp b/core/variant/variant_parser.cpp index 751cb64c62..a214a238a6 100644 --- a/core/variant/variant_parser.cpp +++ b/core/variant/variant_parser.cpp @@ -506,9 +506,9 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream, } else if (id == "null" || id == "nil") { value = Variant(); } else if (id == "inf") { - value = Math_INF; + value = INFINITY; } else if (id == "nan") { - value = Math_NAN; + value = NAN; } else if (id == "Vector2") { Vector<real_t> args; Error err = _parse_construct<real_t>(p_stream, args, line, r_err_str); @@ -738,10 +738,10 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream, String type = token.value; - Object *obj = ClassDB::instance(type); + Object *obj = ClassDB::instantiate(type); if (!obj) { - r_err_str = "Can't instance Object() of type: " + type; + r_err_str = "Can't instantiate Object() of type: " + type; return ERR_PARSE_ERROR; } @@ -1204,16 +1204,32 @@ Error VariantParser::_parse_tag(Token &token, Stream *p_stream, int &line, Strin r_tag.name = ""; r_tag.fields.clear(); - while (true) { - char32_t c = p_stream->get_char(); - if (p_stream->is_eof()) { - r_err_str = "Unexpected EOF while parsing simple tag"; - return ERR_PARSE_ERROR; + if (p_stream->is_utf8()) { + CharString cs; + while (true) { + char c = p_stream->get_char(); + if (p_stream->is_eof()) { + r_err_str = "Unexpected EOF while parsing simple tag"; + return ERR_PARSE_ERROR; + } + if (c == ']') { + break; + } + cs += c; } - if (c == ']') { - break; + r_tag.name.parse_utf8(cs.get_data(), cs.length()); + } else { + while (true) { + char32_t c = p_stream->get_char(); + if (p_stream->is_eof()) { + r_err_str = "Unexpected EOF while parsing simple tag"; + return ERR_PARSE_ERROR; + } + if (c == ']') { + break; + } + r_tag.name += String::chr(c); } - r_tag.name += String::chr(c); } r_tag.name = r_tag.name.strip_edges(); @@ -1407,7 +1423,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str p_store_string_func(p_store_string_ud, itos(p_variant.operator int64_t())); } break; case Variant::FLOAT: { - String s = rtosfix(p_variant.operator real_t()); + String s = rtosfix(p_variant.operator double()); if (s != "inf" && s != "nan") { if (s.find(".") == -1 && s.find("e") == -1) { s += ".0"; @@ -1423,47 +1439,47 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str } break; case Variant::VECTOR2: { Vector2 v = p_variant; - p_store_string_func(p_store_string_ud, "Vector2( " + rtosfix(v.x) + ", " + rtosfix(v.y) + " )"); + p_store_string_func(p_store_string_ud, "Vector2(" + rtosfix(v.x) + ", " + rtosfix(v.y) + ")"); } break; case Variant::VECTOR2I: { Vector2i v = p_variant; - p_store_string_func(p_store_string_ud, "Vector2i( " + itos(v.x) + ", " + itos(v.y) + " )"); + p_store_string_func(p_store_string_ud, "Vector2i(" + itos(v.x) + ", " + itos(v.y) + ")"); } break; case Variant::RECT2: { Rect2 aabb = p_variant; - p_store_string_func(p_store_string_ud, "Rect2( " + rtosfix(aabb.position.x) + ", " + rtosfix(aabb.position.y) + ", " + rtosfix(aabb.size.x) + ", " + rtosfix(aabb.size.y) + " )"); + p_store_string_func(p_store_string_ud, "Rect2(" + rtosfix(aabb.position.x) + ", " + rtosfix(aabb.position.y) + ", " + rtosfix(aabb.size.x) + ", " + rtosfix(aabb.size.y) + ")"); } break; case Variant::RECT2I: { Rect2i aabb = p_variant; - p_store_string_func(p_store_string_ud, "Rect2i( " + itos(aabb.position.x) + ", " + itos(aabb.position.y) + ", " + itos(aabb.size.x) + ", " + itos(aabb.size.y) + " )"); + p_store_string_func(p_store_string_ud, "Rect2i(" + itos(aabb.position.x) + ", " + itos(aabb.position.y) + ", " + itos(aabb.size.x) + ", " + itos(aabb.size.y) + ")"); } break; case Variant::VECTOR3: { Vector3 v = p_variant; - p_store_string_func(p_store_string_ud, "Vector3( " + rtosfix(v.x) + ", " + rtosfix(v.y) + ", " + rtosfix(v.z) + " )"); + p_store_string_func(p_store_string_ud, "Vector3(" + rtosfix(v.x) + ", " + rtosfix(v.y) + ", " + rtosfix(v.z) + ")"); } break; case Variant::VECTOR3I: { Vector3i v = p_variant; - p_store_string_func(p_store_string_ud, "Vector3i( " + itos(v.x) + ", " + itos(v.y) + ", " + itos(v.z) + " )"); + p_store_string_func(p_store_string_ud, "Vector3i(" + itos(v.x) + ", " + itos(v.y) + ", " + itos(v.z) + ")"); } break; case Variant::PLANE: { Plane p = p_variant; - p_store_string_func(p_store_string_ud, "Plane( " + rtosfix(p.normal.x) + ", " + rtosfix(p.normal.y) + ", " + rtosfix(p.normal.z) + ", " + rtosfix(p.d) + " )"); + p_store_string_func(p_store_string_ud, "Plane(" + rtosfix(p.normal.x) + ", " + rtosfix(p.normal.y) + ", " + rtosfix(p.normal.z) + ", " + rtosfix(p.d) + ")"); } break; case Variant::AABB: { AABB aabb = p_variant; - p_store_string_func(p_store_string_ud, "AABB( " + rtosfix(aabb.position.x) + ", " + rtosfix(aabb.position.y) + ", " + rtosfix(aabb.position.z) + ", " + rtosfix(aabb.size.x) + ", " + rtosfix(aabb.size.y) + ", " + rtosfix(aabb.size.z) + " )"); + p_store_string_func(p_store_string_ud, "AABB(" + rtosfix(aabb.position.x) + ", " + rtosfix(aabb.position.y) + ", " + rtosfix(aabb.position.z) + ", " + rtosfix(aabb.size.x) + ", " + rtosfix(aabb.size.y) + ", " + rtosfix(aabb.size.z) + ")"); } break; case Variant::QUATERNION: { Quaternion quaternion = p_variant; - p_store_string_func(p_store_string_ud, "Quaternion( " + rtosfix(quaternion.x) + ", " + rtosfix(quaternion.y) + ", " + rtosfix(quaternion.z) + ", " + rtosfix(quaternion.w) + " )"); + p_store_string_func(p_store_string_ud, "Quaternion(" + rtosfix(quaternion.x) + ", " + rtosfix(quaternion.y) + ", " + rtosfix(quaternion.z) + ", " + rtosfix(quaternion.w) + ")"); } break; case Variant::TRANSFORM2D: { - String s = "Transform2D( "; + String s = "Transform2D("; Transform2D m3 = p_variant; for (int i = 0; i < 3; i++) { for (int j = 0; j < 2; j++) { @@ -1474,11 +1490,11 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str } } - p_store_string_func(p_store_string_ud, s + " )"); + p_store_string_func(p_store_string_ud, s + ")"); } break; case Variant::BASIS: { - String s = "Basis( "; + String s = "Basis("; Basis m3 = p_variant; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { @@ -1489,11 +1505,11 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str } } - p_store_string_func(p_store_string_ud, s + " )"); + p_store_string_func(p_store_string_ud, s + ")"); } break; case Variant::TRANSFORM3D: { - String s = "Transform3D( "; + String s = "Transform3D("; Transform3D t = p_variant; Basis &m3 = t.basis; for (int i = 0; i < 3; i++) { @@ -1507,13 +1523,13 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str s = s + ", " + rtosfix(t.origin.x) + ", " + rtosfix(t.origin.y) + ", " + rtosfix(t.origin.z); - p_store_string_func(p_store_string_ud, s + " )"); + p_store_string_func(p_store_string_ud, s + ")"); } break; // misc types case Variant::COLOR: { Color c = p_variant; - p_store_string_func(p_store_string_ud, "Color( " + rtosfix(c.r) + ", " + rtosfix(c.g) + ", " + rtosfix(c.b) + ", " + rtosfix(c.a) + " )"); + p_store_string_func(p_store_string_ud, "Color(" + rtosfix(c.r) + ", " + rtosfix(c.g) + ", " + rtosfix(c.b) + ", " + rtosfix(c.a) + ")"); } break; case Variant::STRING_NAME: { @@ -1553,7 +1569,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str if (res_text == String() && res->get_path().is_resource_file()) { //external resource String path = res->get_path(); - res_text = "Resource( \"" + path + "\")"; + res_text = "Resource(\"" + path + "\")"; } //could come up with some sort of text @@ -1570,8 +1586,8 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str List<PropertyInfo> props; obj->get_property_list(&props); bool first = true; - for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) { - if (E->get().usage & PROPERTY_USAGE_STORAGE || E->get().usage & PROPERTY_USAGE_SCRIPT_VARIABLE) { + for (const PropertyInfo &E : props) { + if (E.usage & PROPERTY_USAGE_STORAGE || E.usage & PROPERTY_USAGE_SCRIPT_VARIABLE) { //must be serialized if (first) { @@ -1580,8 +1596,8 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str p_store_string_func(p_store_string_ud, ","); } - p_store_string_func(p_store_string_ud, "\"" + E->get().name + "\":"); - write(obj->get(E->get().name), p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud); + p_store_string_func(p_store_string_ud, "\"" + E.name + "\":"); + write(obj->get(E.name), p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud); } } @@ -1599,7 +1615,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str p_store_string_func(p_store_string_ud, "{\n"); for (List<Variant>::Element *E = keys.front(); E; E = E->next()) { /* - if (!_check_type(dict[E->get()])) + if (!_check_type(dict[E])) continue; */ write(E->get(), p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud); @@ -1616,7 +1632,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str } break; case Variant::ARRAY: { - p_store_string_func(p_store_string_ud, "[ "); + p_store_string_func(p_store_string_ud, "["); Array array = p_variant; int len = array.size(); for (int i = 0; i < len; i++) { @@ -1625,12 +1641,12 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str } write(array[i], p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud); } - p_store_string_func(p_store_string_ud, " ]"); + p_store_string_func(p_store_string_ud, "]"); } break; case Variant::PACKED_BYTE_ARRAY: { - p_store_string_func(p_store_string_ud, "PackedByteArray( "); + p_store_string_func(p_store_string_ud, "PackedByteArray("); String s; Vector<uint8_t> data = p_variant; int len = data.size(); @@ -1644,11 +1660,11 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str p_store_string_func(p_store_string_ud, itos(ptr[i])); } - p_store_string_func(p_store_string_ud, " )"); + p_store_string_func(p_store_string_ud, ")"); } break; case Variant::PACKED_INT32_ARRAY: { - p_store_string_func(p_store_string_ud, "PackedInt32Array( "); + p_store_string_func(p_store_string_ud, "PackedInt32Array("); Vector<int32_t> data = p_variant; int32_t len = data.size(); const int32_t *ptr = data.ptr(); @@ -1661,11 +1677,11 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str p_store_string_func(p_store_string_ud, itos(ptr[i])); } - p_store_string_func(p_store_string_ud, " )"); + p_store_string_func(p_store_string_ud, ")"); } break; case Variant::PACKED_INT64_ARRAY: { - p_store_string_func(p_store_string_ud, "PackedInt64Array( "); + p_store_string_func(p_store_string_ud, "PackedInt64Array("); Vector<int64_t> data = p_variant; int64_t len = data.size(); const int64_t *ptr = data.ptr(); @@ -1678,11 +1694,11 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str p_store_string_func(p_store_string_ud, itos(ptr[i])); } - p_store_string_func(p_store_string_ud, " )"); + p_store_string_func(p_store_string_ud, ")"); } break; case Variant::PACKED_FLOAT32_ARRAY: { - p_store_string_func(p_store_string_ud, "PackedFloat32Array( "); + p_store_string_func(p_store_string_ud, "PackedFloat32Array("); Vector<float> data = p_variant; int len = data.size(); const float *ptr = data.ptr(); @@ -1694,11 +1710,11 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str p_store_string_func(p_store_string_ud, rtosfix(ptr[i])); } - p_store_string_func(p_store_string_ud, " )"); + p_store_string_func(p_store_string_ud, ")"); } break; case Variant::PACKED_FLOAT64_ARRAY: { - p_store_string_func(p_store_string_ud, "PackedFloat64Array( "); + p_store_string_func(p_store_string_ud, "PackedFloat64Array("); Vector<double> data = p_variant; int len = data.size(); const double *ptr = data.ptr(); @@ -1710,11 +1726,11 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str p_store_string_func(p_store_string_ud, rtosfix(ptr[i])); } - p_store_string_func(p_store_string_ud, " )"); + p_store_string_func(p_store_string_ud, ")"); } break; case Variant::PACKED_STRING_ARRAY: { - p_store_string_func(p_store_string_ud, "PackedStringArray( "); + p_store_string_func(p_store_string_ud, "PackedStringArray("); Vector<String> data = p_variant; int len = data.size(); const String *ptr = data.ptr(); @@ -1730,11 +1746,11 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str p_store_string_func(p_store_string_ud, "\"" + str.c_escape() + "\""); } - p_store_string_func(p_store_string_ud, " )"); + p_store_string_func(p_store_string_ud, ")"); } break; case Variant::PACKED_VECTOR2_ARRAY: { - p_store_string_func(p_store_string_ud, "PackedVector2Array( "); + p_store_string_func(p_store_string_ud, "PackedVector2Array("); Vector<Vector2> data = p_variant; int len = data.size(); const Vector2 *ptr = data.ptr(); @@ -1746,11 +1762,11 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str p_store_string_func(p_store_string_ud, rtosfix(ptr[i].x) + ", " + rtosfix(ptr[i].y)); } - p_store_string_func(p_store_string_ud, " )"); + p_store_string_func(p_store_string_ud, ")"); } break; case Variant::PACKED_VECTOR3_ARRAY: { - p_store_string_func(p_store_string_ud, "PackedVector3Array( "); + p_store_string_func(p_store_string_ud, "PackedVector3Array("); Vector<Vector3> data = p_variant; int len = data.size(); const Vector3 *ptr = data.ptr(); @@ -1762,12 +1778,11 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str p_store_string_func(p_store_string_ud, rtosfix(ptr[i].x) + ", " + rtosfix(ptr[i].y) + ", " + rtosfix(ptr[i].z)); } - p_store_string_func(p_store_string_ud, " )"); + p_store_string_func(p_store_string_ud, ")"); } break; case Variant::PACKED_COLOR_ARRAY: { - p_store_string_func(p_store_string_ud, "PackedColorArray( "); - + p_store_string_func(p_store_string_ud, "PackedColorArray("); Vector<Color> data = p_variant; int len = data.size(); const Color *ptr = data.ptr(); @@ -1779,7 +1794,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str p_store_string_func(p_store_string_ud, rtosfix(ptr[i].r) + ", " + rtosfix(ptr[i].g) + ", " + rtosfix(ptr[i].b) + ", " + rtosfix(ptr[i].a)); } - p_store_string_func(p_store_string_ud, " )"); + p_store_string_func(p_store_string_ud, ")"); } break; default: { diff --git a/core/variant/variant_parser.h b/core/variant/variant_parser.h index 05fc29b5e0..1ba26db6ed 100644 --- a/core/variant/variant_parser.h +++ b/core/variant/variant_parser.h @@ -73,9 +73,9 @@ public: struct ResourceParser { void *userdata = nullptr; - ParseResourceFunc func; - ParseResourceFunc ext_func; - ParseResourceFunc sub_func; + ParseResourceFunc func = nullptr; + ParseResourceFunc ext_func = nullptr; + ParseResourceFunc sub_func = nullptr; }; enum TokenType { diff --git a/core/variant/variant_setget.cpp b/core/variant/variant_setget.cpp index ae2795f2fd..ae3c7685fd 100644 --- a/core/variant/variant_setget.cpp +++ b/core/variant/variant_setget.cpp @@ -28,282 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "variant.h" - -#include "core/core_string_names.h" -#include "core/debugger/engine_debugger.h" -#include "core/object/class_db.h" -#include "core/templates/local_vector.h" -#include "core/variant/variant_internal.h" - -/**** NAMED SETTERS AND GETTERS ****/ - -#define SETGET_STRUCT(m_base_type, m_member_type, m_member) \ - struct VariantSetGet_##m_base_type##_##m_member { \ - static void get(const Variant *base, Variant *member) { \ - VariantTypeAdjust<m_member_type>::adjust(member); \ - *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_member; \ - } \ - static void ptr_get(const void *base, void *member) { \ - PtrToArg<m_member_type>::encode(PtrToArg<m_base_type>::convert(base).m_member, member); \ - } \ - static void set(Variant *base, const Variant *value, bool &valid) { \ - if (value->get_type() == GetTypeInfo<m_member_type>::VARIANT_TYPE) { \ - VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_member = *VariantGetInternalPtr<m_member_type>::get_ptr(value); \ - valid = true; \ - } else { \ - valid = false; \ - } \ - } \ - static void validated_set(Variant *base, const Variant *value) { \ - VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_member = *VariantGetInternalPtr<m_member_type>::get_ptr(value); \ - } \ - static void ptr_set(void *base, const void *member) { \ - m_base_type b = PtrToArg<m_base_type>::convert(base); \ - b.m_member = PtrToArg<m_member_type>::convert(member); \ - PtrToArg<m_base_type>::encode(b, base); \ - } \ - static Variant::Type get_type() { return GetTypeInfo<m_member_type>::VARIANT_TYPE; } \ - }; - -#define SETGET_NUMBER_STRUCT(m_base_type, m_member_type, m_member) \ - struct VariantSetGet_##m_base_type##_##m_member { \ - static void get(const Variant *base, Variant *member) { \ - VariantTypeAdjust<m_member_type>::adjust(member); \ - *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_member; \ - } \ - static void ptr_get(const void *base, void *member) { \ - PtrToArg<m_member_type>::encode(PtrToArg<m_base_type>::convert(base).m_member, member); \ - } \ - static void set(Variant *base, const Variant *value, bool &valid) { \ - if (value->get_type() == Variant::FLOAT) { \ - VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_member = *VariantGetInternalPtr<double>::get_ptr(value); \ - valid = true; \ - } else if (value->get_type() == Variant::INT) { \ - VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_member = *VariantGetInternalPtr<int64_t>::get_ptr(value); \ - valid = true; \ - } else { \ - valid = false; \ - } \ - } \ - static void validated_set(Variant *base, const Variant *value) { \ - VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_member = *VariantGetInternalPtr<m_member_type>::get_ptr(value); \ - } \ - static void ptr_set(void *base, const void *member) { \ - m_base_type b = PtrToArg<m_base_type>::convert(base); \ - b.m_member = PtrToArg<m_member_type>::convert(member); \ - PtrToArg<m_base_type>::encode(b, base); \ - } \ - static Variant::Type get_type() { return GetTypeInfo<m_member_type>::VARIANT_TYPE; } \ - }; - -#define SETGET_STRUCT_CUSTOM(m_base_type, m_member_type, m_member, m_custom) \ - struct VariantSetGet_##m_base_type##_##m_member { \ - static void get(const Variant *base, Variant *member) { \ - VariantTypeAdjust<m_member_type>::adjust(member); \ - *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_custom; \ - } \ - static void ptr_get(const void *base, void *member) { \ - PtrToArg<m_member_type>::encode(PtrToArg<m_base_type>::convert(base).m_custom, member); \ - } \ - static void set(Variant *base, const Variant *value, bool &valid) { \ - if (value->get_type() == GetTypeInfo<m_member_type>::VARIANT_TYPE) { \ - VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_custom = *VariantGetInternalPtr<m_member_type>::get_ptr(value); \ - valid = true; \ - } else { \ - valid = false; \ - } \ - } \ - static void validated_set(Variant *base, const Variant *value) { \ - VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_custom = *VariantGetInternalPtr<m_member_type>::get_ptr(value); \ - } \ - static void ptr_set(void *base, const void *member) { \ - m_base_type b = PtrToArg<m_base_type>::convert(base); \ - b.m_custom = PtrToArg<m_member_type>::convert(member); \ - PtrToArg<m_base_type>::encode(b, base); \ - } \ - static Variant::Type get_type() { return GetTypeInfo<m_member_type>::VARIANT_TYPE; } \ - }; - -#define SETGET_NUMBER_STRUCT_CUSTOM(m_base_type, m_member_type, m_member, m_custom) \ - struct VariantSetGet_##m_base_type##_##m_member { \ - static void get(const Variant *base, Variant *member) { \ - VariantTypeAdjust<m_member_type>::adjust(member); \ - *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_custom; \ - } \ - static void ptr_get(const void *base, void *member) { \ - PtrToArg<m_member_type>::encode(PtrToArg<m_base_type>::convert(base).m_custom, member); \ - } \ - static void set(Variant *base, const Variant *value, bool &valid) { \ - if (value->get_type() == Variant::FLOAT) { \ - VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_custom = *VariantGetInternalPtr<double>::get_ptr(value); \ - valid = true; \ - } else if (value->get_type() == Variant::INT) { \ - VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_custom = *VariantGetInternalPtr<int64_t>::get_ptr(value); \ - valid = true; \ - } else { \ - valid = false; \ - } \ - } \ - static void validated_set(Variant *base, const Variant *value) { \ - VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_custom = *VariantGetInternalPtr<m_member_type>::get_ptr(value); \ - } \ - static void ptr_set(void *base, const void *member) { \ - m_base_type b = PtrToArg<m_base_type>::convert(base); \ - b.m_custom = PtrToArg<m_member_type>::convert(member); \ - PtrToArg<m_base_type>::encode(b, base); \ - } \ - static Variant::Type get_type() { return GetTypeInfo<m_member_type>::VARIANT_TYPE; } \ - }; - -#define SETGET_STRUCT_FUNC(m_base_type, m_member_type, m_member, m_setter, m_getter) \ - struct VariantSetGet_##m_base_type##_##m_member { \ - static void get(const Variant *base, Variant *member) { \ - VariantTypeAdjust<m_member_type>::adjust(member); \ - *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_getter(); \ - } \ - static void ptr_get(const void *base, void *member) { \ - PtrToArg<m_member_type>::encode(PtrToArg<m_base_type>::convert(base).m_getter(), member); \ - } \ - static void set(Variant *base, const Variant *value, bool &valid) { \ - if (value->get_type() == GetTypeInfo<m_member_type>::VARIANT_TYPE) { \ - VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_setter(*VariantGetInternalPtr<m_member_type>::get_ptr(value)); \ - valid = true; \ - } else { \ - valid = false; \ - } \ - } \ - static void validated_set(Variant *base, const Variant *value) { \ - VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_setter(*VariantGetInternalPtr<m_member_type>::get_ptr(value)); \ - } \ - static void ptr_set(void *base, const void *member) { \ - m_base_type b = PtrToArg<m_base_type>::convert(base); \ - b.m_setter(PtrToArg<m_member_type>::convert(member)); \ - PtrToArg<m_base_type>::encode(b, base); \ - } \ - static Variant::Type get_type() { return GetTypeInfo<m_member_type>::VARIANT_TYPE; } \ - }; - -#define SETGET_NUMBER_STRUCT_FUNC(m_base_type, m_member_type, m_member, m_setter, m_getter) \ - struct VariantSetGet_##m_base_type##_##m_member { \ - static void get(const Variant *base, Variant *member) { \ - VariantTypeAdjust<m_member_type>::adjust(member); \ - *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_getter(); \ - } \ - static void ptr_get(const void *base, void *member) { \ - PtrToArg<m_member_type>::encode(PtrToArg<m_base_type>::convert(base).m_getter(), member); \ - } \ - static void set(Variant *base, const Variant *value, bool &valid) { \ - if (value->get_type() == Variant::FLOAT) { \ - VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_setter(*VariantGetInternalPtr<double>::get_ptr(value)); \ - valid = true; \ - } else if (value->get_type() == Variant::INT) { \ - VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_setter(*VariantGetInternalPtr<int64_t>::get_ptr(value)); \ - valid = true; \ - } else { \ - valid = false; \ - } \ - } \ - static void validated_set(Variant *base, const Variant *value) { \ - VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_setter(*VariantGetInternalPtr<m_member_type>::get_ptr(value)); \ - } \ - static void ptr_set(void *base, const void *member) { \ - m_base_type b = PtrToArg<m_base_type>::convert(base); \ - b.m_setter(PtrToArg<m_member_type>::convert(member)); \ - PtrToArg<m_base_type>::encode(b, base); \ - } \ - static Variant::Type get_type() { return GetTypeInfo<m_member_type>::VARIANT_TYPE; } \ - }; - -#define SETGET_STRUCT_FUNC_INDEX(m_base_type, m_member_type, m_member, m_setter, m_getter, m_index) \ - struct VariantSetGet_##m_base_type##_##m_member { \ - static void get(const Variant *base, Variant *member) { \ - VariantTypeAdjust<m_member_type>::adjust(member); \ - *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_getter(m_index); \ - } \ - static void ptr_get(const void *base, void *member) { \ - PtrToArg<m_member_type>::encode(PtrToArg<m_base_type>::convert(base).m_getter(m_index), member); \ - } \ - static void set(Variant *base, const Variant *value, bool &valid) { \ - if (value->get_type() == GetTypeInfo<m_member_type>::VARIANT_TYPE) { \ - VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_setter(m_index, *VariantGetInternalPtr<m_member_type>::get_ptr(value)); \ - valid = true; \ - } else { \ - valid = false; \ - } \ - } \ - static void validated_set(Variant *base, const Variant *value) { \ - VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_setter(m_index, *VariantGetInternalPtr<m_member_type>::get_ptr(value)); \ - } \ - static void ptr_set(void *base, const void *member) { \ - m_base_type b = PtrToArg<m_base_type>::convert(base); \ - b.m_setter(m_index, PtrToArg<m_member_type>::convert(member)); \ - PtrToArg<m_base_type>::encode(b, base); \ - } \ - static Variant::Type get_type() { return GetTypeInfo<m_member_type>::VARIANT_TYPE; } \ - }; - -SETGET_NUMBER_STRUCT(Vector2, double, x) -SETGET_NUMBER_STRUCT(Vector2, double, y) - -SETGET_NUMBER_STRUCT(Vector2i, int64_t, x) -SETGET_NUMBER_STRUCT(Vector2i, int64_t, y) - -SETGET_NUMBER_STRUCT(Vector3, double, x) -SETGET_NUMBER_STRUCT(Vector3, double, y) -SETGET_NUMBER_STRUCT(Vector3, double, z) - -SETGET_NUMBER_STRUCT(Vector3i, int64_t, x) -SETGET_NUMBER_STRUCT(Vector3i, int64_t, y) -SETGET_NUMBER_STRUCT(Vector3i, int64_t, z) - -SETGET_STRUCT(Rect2, Vector2, position) -SETGET_STRUCT(Rect2, Vector2, size) -SETGET_STRUCT_FUNC(Rect2, Vector2, end, set_end, get_end) - -SETGET_STRUCT(Rect2i, Vector2i, position) -SETGET_STRUCT(Rect2i, Vector2i, size) -SETGET_STRUCT_FUNC(Rect2i, Vector2i, end, set_end, get_end) - -SETGET_STRUCT(AABB, Vector3, position) -SETGET_STRUCT(AABB, Vector3, size) -SETGET_STRUCT_FUNC(AABB, Vector3, end, set_end, get_end) - -SETGET_STRUCT_CUSTOM(Transform2D, Vector2, x, elements[0]) -SETGET_STRUCT_CUSTOM(Transform2D, Vector2, y, elements[1]) -SETGET_STRUCT_CUSTOM(Transform2D, Vector2, origin, elements[2]) - -SETGET_NUMBER_STRUCT_CUSTOM(Plane, double, x, normal.x) -SETGET_NUMBER_STRUCT_CUSTOM(Plane, double, y, normal.y) -SETGET_NUMBER_STRUCT_CUSTOM(Plane, double, z, normal.z) -SETGET_STRUCT(Plane, Vector3, normal) -SETGET_NUMBER_STRUCT(Plane, double, d) - -SETGET_NUMBER_STRUCT(Quaternion, double, x) -SETGET_NUMBER_STRUCT(Quaternion, double, y) -SETGET_NUMBER_STRUCT(Quaternion, double, z) -SETGET_NUMBER_STRUCT(Quaternion, double, w) - -SETGET_STRUCT_FUNC_INDEX(Basis, Vector3, x, set_axis, get_axis, 0) -SETGET_STRUCT_FUNC_INDEX(Basis, Vector3, y, set_axis, get_axis, 1) -SETGET_STRUCT_FUNC_INDEX(Basis, Vector3, z, set_axis, get_axis, 2) - -SETGET_STRUCT(Transform3D, Basis, basis) -SETGET_STRUCT(Transform3D, Vector3, origin) - -SETGET_NUMBER_STRUCT(Color, double, r) -SETGET_NUMBER_STRUCT(Color, double, g) -SETGET_NUMBER_STRUCT(Color, double, b) -SETGET_NUMBER_STRUCT(Color, double, a) - -SETGET_NUMBER_STRUCT_FUNC(Color, int64_t, r8, set_r8, get_r8) -SETGET_NUMBER_STRUCT_FUNC(Color, int64_t, g8, set_g8, get_g8) -SETGET_NUMBER_STRUCT_FUNC(Color, int64_t, b8, set_b8, get_b8) -SETGET_NUMBER_STRUCT_FUNC(Color, int64_t, a8, set_a8, get_a8) - -SETGET_NUMBER_STRUCT_FUNC(Color, double, h, set_h, get_h) -SETGET_NUMBER_STRUCT_FUNC(Color, double, s, set_s, get_s) -SETGET_NUMBER_STRUCT_FUNC(Color, double, v, set_v, get_v) +#include "variant_setget.h" struct VariantSetterGetterInfo { void (*setter)(Variant *base, const Variant *value, bool &valid); @@ -326,7 +51,7 @@ static void register_member(Variant::Type p_type, const StringName &p_member) { sgi.ptr_setter = T::ptr_set; sgi.getter = T::get; - sgi.validated_getter = T::get; + sgi.validated_getter = T::validated_get; sgi.ptr_getter = T::ptr_get; sgi.member_type = T::get_type(); @@ -1146,7 +871,7 @@ struct VariantKeyedSetGetDictionary { *r_valid = true; return VariantGetInternalPtr<Dictionary>::get_ptr(base)->has(*key); } - static bool ptr_has(const void *base, const void *key) { + static uint32_t ptr_has(const void *base, const void *key) { /* avoid ptrconvert for performance*/ const Dictionary &v = *reinterpret_cast<const Dictionary *>(base); return v.has(PtrToArg<Variant>::convert(key)); @@ -1196,7 +921,7 @@ struct VariantKeyedSetGetObject { obj->getvar(*key, &exists); return exists; } - static bool ptr_has(const void *base, const void *key) { + static uint32_t ptr_has(const void *base, const void *key) { const Object *obj = PtrToArg<Object *>::convert(base); ERR_FAIL_COND_V(!obj, false); bool valid; @@ -1368,9 +1093,9 @@ void Variant::get_property_list(List<PropertyInfo> *p_list) const { const Dictionary *dic = reinterpret_cast<const Dictionary *>(_data._mem); List<Variant> keys; dic->get_key_list(&keys); - for (List<Variant>::Element *E = keys.front(); E; E = E->next()) { - if (E->get().get_type() == Variant::STRING) { - p_list->push_back(PropertyInfo(Variant::STRING, E->get())); + for (const Variant &E : keys) { + if (E.get_type() == Variant::STRING) { + p_list->push_back(PropertyInfo(Variant::STRING, E)); } } } else if (type == OBJECT) { @@ -1381,10 +1106,10 @@ void Variant::get_property_list(List<PropertyInfo> *p_list) const { } else { List<StringName> members; get_member_list(type, &members); - for (List<StringName>::Element *E = members.front(); E; E = E->next()) { + for (const StringName &E : members) { PropertyInfo pi; - pi.name = E->get(); - pi.type = get_member_type(type, E->get()); + pi.name = E; + pi.type = get_member_type(type, E); p_list->push_back(pi); } } diff --git a/core/variant/variant_setget.h b/core/variant/variant_setget.h new file mode 100644 index 0000000000..dbf24ab3e3 --- /dev/null +++ b/core/variant/variant_setget.h @@ -0,0 +1,332 @@ +/*************************************************************************/ +/* variant_setget.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef VARIANT_SETGET_H +#define VARIANT_SETGET_H + +#include "variant.h" + +#include "core/core_string_names.h" +#include "core/debugger/engine_debugger.h" +#include "core/object/class_db.h" +#include "core/templates/local_vector.h" +#include "core/variant/variant_internal.h" + +/**** NAMED SETTERS AND GETTERS ****/ + +#define SETGET_STRUCT(m_base_type, m_member_type, m_member) \ + struct VariantSetGet_##m_base_type##_##m_member { \ + static void get(const Variant *base, Variant *member) { \ + VariantTypeAdjust<m_member_type>::adjust(member); \ + *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_member; \ + } \ + static inline void validated_get(const Variant *base, Variant *member) { \ + *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_member; \ + } \ + static void ptr_get(const void *base, void *member) { \ + PtrToArg<m_member_type>::encode(PtrToArg<m_base_type>::convert(base).m_member, member); \ + } \ + static void set(Variant *base, const Variant *value, bool &valid) { \ + if (value->get_type() == GetTypeInfo<m_member_type>::VARIANT_TYPE) { \ + VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_member = *VariantGetInternalPtr<m_member_type>::get_ptr(value); \ + valid = true; \ + } else { \ + valid = false; \ + } \ + } \ + static inline void validated_set(Variant *base, const Variant *value) { \ + VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_member = *VariantGetInternalPtr<m_member_type>::get_ptr(value); \ + } \ + static void ptr_set(void *base, const void *member) { \ + m_base_type b = PtrToArg<m_base_type>::convert(base); \ + b.m_member = PtrToArg<m_member_type>::convert(member); \ + PtrToArg<m_base_type>::encode(b, base); \ + } \ + static Variant::Type get_type() { return GetTypeInfo<m_member_type>::VARIANT_TYPE; } \ + }; + +#define SETGET_NUMBER_STRUCT(m_base_type, m_member_type, m_member) \ + struct VariantSetGet_##m_base_type##_##m_member { \ + static void get(const Variant *base, Variant *member) { \ + VariantTypeAdjust<m_member_type>::adjust(member); \ + *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_member; \ + } \ + static inline void validated_get(const Variant *base, Variant *member) { \ + *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_member; \ + } \ + static void ptr_get(const void *base, void *member) { \ + PtrToArg<m_member_type>::encode(PtrToArg<m_base_type>::convert(base).m_member, member); \ + } \ + static void set(Variant *base, const Variant *value, bool &valid) { \ + if (value->get_type() == Variant::FLOAT) { \ + VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_member = *VariantGetInternalPtr<double>::get_ptr(value); \ + valid = true; \ + } else if (value->get_type() == Variant::INT) { \ + VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_member = *VariantGetInternalPtr<int64_t>::get_ptr(value); \ + valid = true; \ + } else { \ + valid = false; \ + } \ + } \ + static inline void validated_set(Variant *base, const Variant *value) { \ + VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_member = *VariantGetInternalPtr<m_member_type>::get_ptr(value); \ + } \ + static void ptr_set(void *base, const void *member) { \ + m_base_type b = PtrToArg<m_base_type>::convert(base); \ + b.m_member = PtrToArg<m_member_type>::convert(member); \ + PtrToArg<m_base_type>::encode(b, base); \ + } \ + static Variant::Type get_type() { return GetTypeInfo<m_member_type>::VARIANT_TYPE; } \ + }; + +#define SETGET_STRUCT_CUSTOM(m_base_type, m_member_type, m_member, m_custom) \ + struct VariantSetGet_##m_base_type##_##m_member { \ + static void get(const Variant *base, Variant *member) { \ + VariantTypeAdjust<m_member_type>::adjust(member); \ + *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_custom; \ + } \ + static inline void validated_get(const Variant *base, Variant *member) { \ + *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_custom; \ + } \ + static void ptr_get(const void *base, void *member) { \ + PtrToArg<m_member_type>::encode(PtrToArg<m_base_type>::convert(base).m_custom, member); \ + } \ + static void set(Variant *base, const Variant *value, bool &valid) { \ + if (value->get_type() == GetTypeInfo<m_member_type>::VARIANT_TYPE) { \ + VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_custom = *VariantGetInternalPtr<m_member_type>::get_ptr(value); \ + valid = true; \ + } else { \ + valid = false; \ + } \ + } \ + static inline void validated_set(Variant *base, const Variant *value) { \ + VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_custom = *VariantGetInternalPtr<m_member_type>::get_ptr(value); \ + } \ + static void ptr_set(void *base, const void *member) { \ + m_base_type b = PtrToArg<m_base_type>::convert(base); \ + b.m_custom = PtrToArg<m_member_type>::convert(member); \ + PtrToArg<m_base_type>::encode(b, base); \ + } \ + static Variant::Type get_type() { return GetTypeInfo<m_member_type>::VARIANT_TYPE; } \ + }; + +#define SETGET_NUMBER_STRUCT_CUSTOM(m_base_type, m_member_type, m_member, m_custom) \ + struct VariantSetGet_##m_base_type##_##m_member { \ + static void get(const Variant *base, Variant *member) { \ + VariantTypeAdjust<m_member_type>::adjust(member); \ + *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_custom; \ + } \ + static inline void validated_get(const Variant *base, Variant *member) { \ + *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_custom; \ + } \ + static void ptr_get(const void *base, void *member) { \ + PtrToArg<m_member_type>::encode(PtrToArg<m_base_type>::convert(base).m_custom, member); \ + } \ + static void set(Variant *base, const Variant *value, bool &valid) { \ + if (value->get_type() == Variant::FLOAT) { \ + VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_custom = *VariantGetInternalPtr<double>::get_ptr(value); \ + valid = true; \ + } else if (value->get_type() == Variant::INT) { \ + VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_custom = *VariantGetInternalPtr<int64_t>::get_ptr(value); \ + valid = true; \ + } else { \ + valid = false; \ + } \ + } \ + static inline void validated_set(Variant *base, const Variant *value) { \ + VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_custom = *VariantGetInternalPtr<m_member_type>::get_ptr(value); \ + } \ + static void ptr_set(void *base, const void *member) { \ + m_base_type b = PtrToArg<m_base_type>::convert(base); \ + b.m_custom = PtrToArg<m_member_type>::convert(member); \ + PtrToArg<m_base_type>::encode(b, base); \ + } \ + static Variant::Type get_type() { return GetTypeInfo<m_member_type>::VARIANT_TYPE; } \ + }; + +#define SETGET_STRUCT_FUNC(m_base_type, m_member_type, m_member, m_setter, m_getter) \ + struct VariantSetGet_##m_base_type##_##m_member { \ + static void get(const Variant *base, Variant *member) { \ + VariantTypeAdjust<m_member_type>::adjust(member); \ + *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_getter(); \ + } \ + static inline void validated_get(const Variant *base, Variant *member) { \ + *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_getter(); \ + } \ + static void ptr_get(const void *base, void *member) { \ + PtrToArg<m_member_type>::encode(PtrToArg<m_base_type>::convert(base).m_getter(), member); \ + } \ + static void set(Variant *base, const Variant *value, bool &valid) { \ + if (value->get_type() == GetTypeInfo<m_member_type>::VARIANT_TYPE) { \ + VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_setter(*VariantGetInternalPtr<m_member_type>::get_ptr(value)); \ + valid = true; \ + } else { \ + valid = false; \ + } \ + } \ + static inline void validated_set(Variant *base, const Variant *value) { \ + VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_setter(*VariantGetInternalPtr<m_member_type>::get_ptr(value)); \ + } \ + static void ptr_set(void *base, const void *member) { \ + m_base_type b = PtrToArg<m_base_type>::convert(base); \ + b.m_setter(PtrToArg<m_member_type>::convert(member)); \ + PtrToArg<m_base_type>::encode(b, base); \ + } \ + static Variant::Type get_type() { return GetTypeInfo<m_member_type>::VARIANT_TYPE; } \ + }; + +#define SETGET_NUMBER_STRUCT_FUNC(m_base_type, m_member_type, m_member, m_setter, m_getter) \ + struct VariantSetGet_##m_base_type##_##m_member { \ + static void get(const Variant *base, Variant *member) { \ + VariantTypeAdjust<m_member_type>::adjust(member); \ + *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_getter(); \ + } \ + static inline void validated_get(const Variant *base, Variant *member) { \ + *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_getter(); \ + } \ + static void ptr_get(const void *base, void *member) { \ + PtrToArg<m_member_type>::encode(PtrToArg<m_base_type>::convert(base).m_getter(), member); \ + } \ + static void set(Variant *base, const Variant *value, bool &valid) { \ + if (value->get_type() == Variant::FLOAT) { \ + VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_setter(*VariantGetInternalPtr<double>::get_ptr(value)); \ + valid = true; \ + } else if (value->get_type() == Variant::INT) { \ + VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_setter(*VariantGetInternalPtr<int64_t>::get_ptr(value)); \ + valid = true; \ + } else { \ + valid = false; \ + } \ + } \ + static inline void validated_set(Variant *base, const Variant *value) { \ + VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_setter(*VariantGetInternalPtr<m_member_type>::get_ptr(value)); \ + } \ + static void ptr_set(void *base, const void *member) { \ + m_base_type b = PtrToArg<m_base_type>::convert(base); \ + b.m_setter(PtrToArg<m_member_type>::convert(member)); \ + PtrToArg<m_base_type>::encode(b, base); \ + } \ + static Variant::Type get_type() { return GetTypeInfo<m_member_type>::VARIANT_TYPE; } \ + }; + +#define SETGET_STRUCT_FUNC_INDEX(m_base_type, m_member_type, m_member, m_setter, m_getter, m_index) \ + struct VariantSetGet_##m_base_type##_##m_member { \ + static void get(const Variant *base, Variant *member) { \ + VariantTypeAdjust<m_member_type>::adjust(member); \ + *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_getter(m_index); \ + } \ + static inline void validated_get(const Variant *base, Variant *member) { \ + *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_getter(m_index); \ + } \ + static void ptr_get(const void *base, void *member) { \ + PtrToArg<m_member_type>::encode(PtrToArg<m_base_type>::convert(base).m_getter(m_index), member); \ + } \ + static void set(Variant *base, const Variant *value, bool &valid) { \ + if (value->get_type() == GetTypeInfo<m_member_type>::VARIANT_TYPE) { \ + VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_setter(m_index, *VariantGetInternalPtr<m_member_type>::get_ptr(value)); \ + valid = true; \ + } else { \ + valid = false; \ + } \ + } \ + static inline void validated_set(Variant *base, const Variant *value) { \ + VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_setter(m_index, *VariantGetInternalPtr<m_member_type>::get_ptr(value)); \ + } \ + static void ptr_set(void *base, const void *member) { \ + m_base_type b = PtrToArg<m_base_type>::convert(base); \ + b.m_setter(m_index, PtrToArg<m_member_type>::convert(member)); \ + PtrToArg<m_base_type>::encode(b, base); \ + } \ + static Variant::Type get_type() { return GetTypeInfo<m_member_type>::VARIANT_TYPE; } \ + }; + +SETGET_NUMBER_STRUCT(Vector2, double, x) +SETGET_NUMBER_STRUCT(Vector2, double, y) + +SETGET_NUMBER_STRUCT(Vector2i, int64_t, x) +SETGET_NUMBER_STRUCT(Vector2i, int64_t, y) + +SETGET_NUMBER_STRUCT(Vector3, double, x) +SETGET_NUMBER_STRUCT(Vector3, double, y) +SETGET_NUMBER_STRUCT(Vector3, double, z) + +SETGET_NUMBER_STRUCT(Vector3i, int64_t, x) +SETGET_NUMBER_STRUCT(Vector3i, int64_t, y) +SETGET_NUMBER_STRUCT(Vector3i, int64_t, z) + +SETGET_STRUCT(Rect2, Vector2, position) +SETGET_STRUCT(Rect2, Vector2, size) +SETGET_STRUCT_FUNC(Rect2, Vector2, end, set_end, get_end) + +SETGET_STRUCT(Rect2i, Vector2i, position) +SETGET_STRUCT(Rect2i, Vector2i, size) +SETGET_STRUCT_FUNC(Rect2i, Vector2i, end, set_end, get_end) + +SETGET_STRUCT(AABB, Vector3, position) +SETGET_STRUCT(AABB, Vector3, size) +SETGET_STRUCT_FUNC(AABB, Vector3, end, set_end, get_end) + +SETGET_STRUCT_CUSTOM(Transform2D, Vector2, x, elements[0]) +SETGET_STRUCT_CUSTOM(Transform2D, Vector2, y, elements[1]) +SETGET_STRUCT_CUSTOM(Transform2D, Vector2, origin, elements[2]) + +SETGET_NUMBER_STRUCT_CUSTOM(Plane, double, x, normal.x) +SETGET_NUMBER_STRUCT_CUSTOM(Plane, double, y, normal.y) +SETGET_NUMBER_STRUCT_CUSTOM(Plane, double, z, normal.z) +SETGET_STRUCT(Plane, Vector3, normal) +SETGET_NUMBER_STRUCT(Plane, double, d) + +SETGET_NUMBER_STRUCT(Quaternion, double, x) +SETGET_NUMBER_STRUCT(Quaternion, double, y) +SETGET_NUMBER_STRUCT(Quaternion, double, z) +SETGET_NUMBER_STRUCT(Quaternion, double, w) + +SETGET_STRUCT_FUNC_INDEX(Basis, Vector3, x, set_axis, get_axis, 0) +SETGET_STRUCT_FUNC_INDEX(Basis, Vector3, y, set_axis, get_axis, 1) +SETGET_STRUCT_FUNC_INDEX(Basis, Vector3, z, set_axis, get_axis, 2) + +SETGET_STRUCT(Transform3D, Basis, basis) +SETGET_STRUCT(Transform3D, Vector3, origin) + +SETGET_NUMBER_STRUCT(Color, double, r) +SETGET_NUMBER_STRUCT(Color, double, g) +SETGET_NUMBER_STRUCT(Color, double, b) +SETGET_NUMBER_STRUCT(Color, double, a) + +SETGET_NUMBER_STRUCT_FUNC(Color, int64_t, r8, set_r8, get_r8) +SETGET_NUMBER_STRUCT_FUNC(Color, int64_t, g8, set_g8, get_g8) +SETGET_NUMBER_STRUCT_FUNC(Color, int64_t, b8, set_b8, get_b8) +SETGET_NUMBER_STRUCT_FUNC(Color, int64_t, a8, set_a8, get_a8) + +SETGET_NUMBER_STRUCT_FUNC(Color, double, h, set_h, get_h) +SETGET_NUMBER_STRUCT_FUNC(Color, double, s, set_s, get_s) +SETGET_NUMBER_STRUCT_FUNC(Color, double, v, set_v, get_v) + +#endif // VARIANT_SETGET_H diff --git a/core/variant/variant_utility.cpp b/core/variant/variant_utility.cpp index 5d1efb4166..232054d0ca 100644 --- a/core/variant/variant_utility.cpp +++ b/core/variant/variant_utility.cpp @@ -35,6 +35,8 @@ #include "core/object/ref_counted.h" #include "core/os/os.h" #include "core/templates/oa_hash_map.h" +#include "core/templates/rid.h" +#include "core/templates/rid_owner.h" #include "core/variant/binder_common.h" #include "core/variant/variant_parser.h" @@ -249,10 +251,6 @@ struct VariantUtilityFunctions { return Math::move_toward(from, to, delta); } - static inline double dectime(double value, double amount, double step) { - return Math::dectime(value, amount, step); - } - static inline double deg2rad(double angle_deg) { return Math::deg2rad(angle_deg); } @@ -269,14 +267,6 @@ struct VariantUtilityFunctions { return Math::db2linear(db); } - static inline Vector2 polar2cartesian(double r, double th) { - return Vector2(r * Math::cos(th), r * Math::sin(th)); - } - - static inline Vector2 cartesian2polar(double x, double y) { - return Vector2(Math::sqrt(x * x + y * y), Math::atan2(y, x)); - } - static inline int64_t wrapi(int64_t value, int64_t min, int64_t max) { return Math::wrapi(value, min, max); } @@ -488,6 +478,14 @@ struct VariantUtilityFunctions { return str; } + static inline String error_string(Error error) { + if (error < 0 || error >= ERR_MAX) { + return String("(invalid error code)"); + } + + return String(error_names[error]); + } + static inline void print(const Variant **p_args, int p_arg_count, Callable::CallError &r_error) { if (p_arg_count < 1) { r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; @@ -724,6 +722,13 @@ struct VariantUtilityFunctions { } return p_instance.get_validated_object() != nullptr; } + + static inline uint64_t rid_allocate_id() { + return RID_AllocBase::_gen_id(); + } + static inline RID rid_from_int64(uint64_t p_base) { + return RID::from_uint64(p_base); + } }; #ifdef DEBUG_METHODS_ENABLED @@ -1195,16 +1200,12 @@ void Variant::_register_variant_utility_functions() { FUNCBINDR(smoothstep, sarray("from", "to", "x"), Variant::UTILITY_FUNC_TYPE_MATH); FUNCBINDR(move_toward, sarray("from", "to", "delta"), Variant::UTILITY_FUNC_TYPE_MATH); - FUNCBINDR(dectime, sarray("value", "amount", "step"), Variant::UTILITY_FUNC_TYPE_MATH); FUNCBINDR(deg2rad, sarray("deg"), Variant::UTILITY_FUNC_TYPE_MATH); FUNCBINDR(rad2deg, sarray("rad"), Variant::UTILITY_FUNC_TYPE_MATH); FUNCBINDR(linear2db, sarray("lin"), Variant::UTILITY_FUNC_TYPE_MATH); FUNCBINDR(db2linear, sarray("db"), Variant::UTILITY_FUNC_TYPE_MATH); - FUNCBINDR(polar2cartesian, sarray("r", "th"), Variant::UTILITY_FUNC_TYPE_MATH); - FUNCBINDR(cartesian2polar, sarray("x", "y"), Variant::UTILITY_FUNC_TYPE_MATH); - FUNCBINDR(wrapi, sarray("value", "min", "max"), Variant::UTILITY_FUNC_TYPE_MATH); FUNCBINDR(wrapf, sarray("value", "min", "max"), Variant::UTILITY_FUNC_TYPE_MATH); @@ -1239,6 +1240,7 @@ void Variant::_register_variant_utility_functions() { FUNCBINDVR(weakref, sarray("obj"), Variant::UTILITY_FUNC_TYPE_GENERAL); FUNCBINDR(_typeof, sarray("variable"), Variant::UTILITY_FUNC_TYPE_GENERAL); FUNCBINDVARARGS(str, sarray(), Variant::UTILITY_FUNC_TYPE_GENERAL); + FUNCBINDR(error_string, sarray("error"), Variant::UTILITY_FUNC_TYPE_GENERAL); FUNCBINDVARARGV(print, sarray(), Variant::UTILITY_FUNC_TYPE_GENERAL); FUNCBINDVARARGV(printerr, sarray(), Variant::UTILITY_FUNC_TYPE_GENERAL); FUNCBINDVARARGV(printt, sarray(), Variant::UTILITY_FUNC_TYPE_GENERAL); @@ -1261,6 +1263,9 @@ void Variant::_register_variant_utility_functions() { FUNCBINDR(instance_from_id, sarray("instance_id"), Variant::UTILITY_FUNC_TYPE_GENERAL); FUNCBINDR(is_instance_id_valid, sarray("id"), Variant::UTILITY_FUNC_TYPE_GENERAL); FUNCBINDR(is_instance_valid, sarray("instance"), Variant::UTILITY_FUNC_TYPE_GENERAL); + + FUNCBINDR(rid_allocate_id, Vector<String>(), Variant::UTILITY_FUNC_TYPE_GENERAL); + FUNCBINDR(rid_from_int64, sarray("base"), Variant::UTILITY_FUNC_TYPE_GENERAL); } void Variant::_unregister_variant_utility_functions() { @@ -1348,8 +1353,8 @@ String Variant::get_utility_function_argument_name(const StringName &p_name, int if (!bfi) { return String(); } - ERR_FAIL_COND_V(bfi->is_vararg, String()); ERR_FAIL_INDEX_V(p_arg, bfi->argnames.size(), String()); + ERR_FAIL_COND_V(bfi->is_vararg, String()); return bfi->argnames[p_arg]; } @@ -1379,9 +1384,26 @@ bool Variant::is_utility_function_vararg(const StringName &p_name) { return bfi->is_vararg; } +uint32_t Variant::get_utility_function_hash(const StringName &p_name) { + const VariantUtilityFunctionInfo *bfi = utility_function_table.lookup_ptr(p_name); + ERR_FAIL_COND_V(!bfi, 0); + + uint32_t hash = hash_djb2_one_32(bfi->is_vararg); + hash = hash_djb2_one_32(bfi->returns_value, hash); + if (bfi->returns_value) { + hash = hash_djb2_one_32(bfi->return_type, hash); + } + hash = hash_djb2_one_32(bfi->argcount, hash); + for (int i = 0; i < bfi->argcount; i++) { + hash = hash_djb2_one_32(bfi->get_arg_type(i), hash); + } + + return hash; +} + void Variant::get_utility_function_list(List<StringName> *r_functions) { - for (List<StringName>::Element *E = utility_function_name_table.front(); E; E = E->next()) { - r_functions->push_back(E->get()); + for (const StringName &E : utility_function_name_table) { + r_functions->push_back(E); } } |