diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/variant/variant_construct.cpp | 538 | ||||
-rw-r--r-- | core/variant/variant_construct.h | 572 | ||||
-rw-r--r-- | core/variant/variant_op.cpp | 1337 | ||||
-rw-r--r-- | core/variant/variant_op.h | 1316 | ||||
-rw-r--r-- | core/variant/variant_setget.cpp | 279 | ||||
-rw-r--r-- | core/variant/variant_setget.h | 332 |
6 files changed, 2224 insertions, 2150 deletions
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_op.cpp b/core/variant/variant_op.cpp index e7badd22b8..4a1950c9bf 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); diff --git a/core/variant/variant_op.h b/core/variant/variant_op.h new file mode 100644 index 0000000000..e744e76ea3 --- /dev/null +++ b/core/variant/variant_op.h @@ -0,0 +1,1316 @@ +/*************************************************************************/ +/* 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 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 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); + + b->get(a, &r_valid); + *r_ret = r_valid; + } + 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); + + b->get(a, &r_valid); + *r_ret = r_valid; + } + 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_setget.cpp b/core/variant/variant_setget.cpp index ae2795f2fd..5cb329e69a 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(); 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 |