summaryrefslogtreecommitdiff
path: root/core/variant
diff options
context:
space:
mode:
Diffstat (limited to 'core/variant')
-rw-r--r--core/variant/binder_common.h9
-rw-r--r--core/variant/callable.cpp4
-rw-r--r--core/variant/callable.h1
-rw-r--r--core/variant/dictionary.cpp59
-rw-r--r--core/variant/method_ptrcall.h14
-rw-r--r--core/variant/variant.cpp6
-rw-r--r--core/variant/variant.h5
-rw-r--r--core/variant/variant_call.cpp20
-rw-r--r--core/variant/variant_construct.cpp538
-rw-r--r--core/variant/variant_construct.h572
-rw-r--r--core/variant/variant_op.cpp1341
-rw-r--r--core/variant/variant_op.h1316
-rw-r--r--core/variant/variant_parser.cpp36
-rw-r--r--core/variant/variant_setget.cpp283
-rw-r--r--core/variant/variant_setget.h332
-rw-r--r--core/variant/variant_utility.cpp19
16 files changed, 2378 insertions, 2177 deletions
diff --git a/core/variant/binder_common.h b/core/variant/binder_common.h
index 830e0a5cbd..ef5867c685 100644
--- a/core/variant/binder_common.h
+++ b/core/variant/binder_common.h
@@ -31,6 +31,7 @@
#ifndef BINDER_COMMON_H
#define BINDER_COMMON_H
+#include "core/input/input_enums.h"
#include "core/object/object.h"
#include "core/templates/list.h"
#include "core/templates/simple_type.h"
@@ -76,6 +77,7 @@ struct VariantCaster<const T &> {
_FORCE_INLINE_ static m_enum convert(const void *p_ptr) { \
return m_enum(*reinterpret_cast<const int *>(p_ptr)); \
} \
+ typedef int64_t EncodeT; \
_FORCE_INLINE_ static void encode(m_enum p_val, const void *p_ptr) { \
*(int *)p_ptr = p_val; \
} \
@@ -90,6 +92,12 @@ VARIANT_ENUM_CAST(Error);
VARIANT_ENUM_CAST(Side);
VARIANT_ENUM_CAST(ClockDirection);
VARIANT_ENUM_CAST(Corner);
+VARIANT_ENUM_CAST(HatDir);
+VARIANT_ENUM_CAST(HatMask);
+VARIANT_ENUM_CAST(JoyAxis);
+VARIANT_ENUM_CAST(JoyButton);
+VARIANT_ENUM_CAST(MIDIMessage);
+VARIANT_ENUM_CAST(MouseButton);
VARIANT_ENUM_CAST(Orientation);
VARIANT_ENUM_CAST(HAlign);
VARIANT_ENUM_CAST(VAlign);
@@ -110,6 +118,7 @@ struct PtrToArg<char32_t> {
_FORCE_INLINE_ static char32_t convert(const void *p_ptr) {
return char32_t(*reinterpret_cast<const int *>(p_ptr));
}
+ typedef int64_t EncodeT;
_FORCE_INLINE_ static void encode(char32_t p_val, const void *p_ptr) {
*(int *)p_ptr = p_val;
}
diff --git a/core/variant/callable.cpp b/core/variant/callable.cpp
index 34b3e3ea35..ca6f3d615e 100644
--- a/core/variant/callable.cpp
+++ b/core/variant/callable.cpp
@@ -89,6 +89,10 @@ Callable Callable::unbind(int p_argcount) const {
return Callable(memnew(CallableCustomUnbind(*this, p_argcount)));
}
+bool Callable::is_valid() const {
+ return get_object() && (is_custom() || get_object()->has_method(get_method()));
+}
+
Object *Callable::get_object() const {
if (is_null()) {
return nullptr;
diff --git a/core/variant/callable.h b/core/variant/callable.h
index 20d0804292..52094af3aa 100644
--- a/core/variant/callable.h
+++ b/core/variant/callable.h
@@ -81,6 +81,7 @@ public:
_FORCE_INLINE_ bool is_standard() const {
return method != StringName();
}
+ bool is_valid() const;
Callable bind(const Variant **p_arguments, int p_argcount) const;
Callable unbind(int p_argcount) const;
diff --git a/core/variant/dictionary.cpp b/core/variant/dictionary.cpp
index b2f7c6aa0a..07b3a9a675 100644
--- a/core/variant/dictionary.cpp
+++ b/core/variant/dictionary.cpp
@@ -33,6 +33,11 @@
#include "core/templates/ordered_hash_map.h"
#include "core/templates/safe_refcount.h"
#include "core/variant/variant.h"
+// required in this order by VariantInternal, do not remove this comment.
+#include "core/object/class_db.h"
+#include "core/object/object.h"
+#include "core/variant/type_info.h"
+#include "core/variant/variant_internal.h"
struct DictionaryPrivate {
SafeRefCount refcount;
@@ -74,15 +79,32 @@ Variant Dictionary::get_value_at_index(int p_index) const {
}
Variant &Dictionary::operator[](const Variant &p_key) {
- return _p->variant_map[p_key];
+ if (p_key.get_type() == Variant::STRING_NAME) {
+ const StringName *sn = VariantInternal::get_string_name(&p_key);
+ return _p->variant_map[sn->operator String()];
+ } else {
+ return _p->variant_map[p_key];
+ }
}
const Variant &Dictionary::operator[](const Variant &p_key) const {
- return _p->variant_map[p_key];
+ if (p_key.get_type() == Variant::STRING_NAME) {
+ const StringName *sn = VariantInternal::get_string_name(&p_key);
+ return _p->variant_map[sn->operator String()];
+ } else {
+ return _p->variant_map[p_key];
+ }
}
const Variant *Dictionary::getptr(const Variant &p_key) const {
- OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::ConstElement E = ((const OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator> *)&_p->variant_map)->find(p_key);
+ OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::ConstElement E;
+
+ if (p_key.get_type() == Variant::STRING_NAME) {
+ const StringName *sn = VariantInternal::get_string_name(&p_key);
+ E = ((const OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator> *)&_p->variant_map)->find(sn->operator String());
+ } else {
+ E = ((const OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator> *)&_p->variant_map)->find(p_key);
+ }
if (!E) {
return nullptr;
@@ -91,8 +113,14 @@ const Variant *Dictionary::getptr(const Variant &p_key) const {
}
Variant *Dictionary::getptr(const Variant &p_key) {
- OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E = _p->variant_map.find(p_key);
+ OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E;
+ if (p_key.get_type() == Variant::STRING_NAME) {
+ const StringName *sn = VariantInternal::get_string_name(&p_key);
+ E = ((OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator> *)&_p->variant_map)->find(sn->operator String());
+ } else {
+ E = ((OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator> *)&_p->variant_map)->find(p_key);
+ }
if (!E) {
return nullptr;
}
@@ -100,7 +128,14 @@ Variant *Dictionary::getptr(const Variant &p_key) {
}
Variant Dictionary::get_valid(const Variant &p_key) const {
- OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::ConstElement E = ((const OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator> *)&_p->variant_map)->find(p_key);
+ OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::ConstElement E;
+
+ if (p_key.get_type() == Variant::STRING_NAME) {
+ const StringName *sn = VariantInternal::get_string_name(&p_key);
+ E = ((const OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator> *)&_p->variant_map)->find(sn->operator String());
+ } else {
+ E = ((const OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator> *)&_p->variant_map)->find(p_key);
+ }
if (!E) {
return Variant();
@@ -126,7 +161,12 @@ bool Dictionary::is_empty() const {
}
bool Dictionary::has(const Variant &p_key) const {
- return _p->variant_map.has(p_key);
+ if (p_key.get_type() == Variant::STRING_NAME) {
+ const StringName *sn = VariantInternal::get_string_name(&p_key);
+ return _p->variant_map.has(sn->operator String());
+ } else {
+ return _p->variant_map.has(p_key);
+ }
}
bool Dictionary::has_all(const Array &p_keys) const {
@@ -139,7 +179,12 @@ bool Dictionary::has_all(const Array &p_keys) const {
}
bool Dictionary::erase(const Variant &p_key) {
- return _p->variant_map.erase(p_key);
+ if (p_key.get_type() == Variant::STRING_NAME) {
+ const StringName *sn = VariantInternal::get_string_name(&p_key);
+ return _p->variant_map.erase(sn->operator String());
+ } else {
+ return _p->variant_map.erase(p_key);
+ }
}
bool Dictionary::operator==(const Dictionary &p_dictionary) const {
diff --git a/core/variant/method_ptrcall.h b/core/variant/method_ptrcall.h
index d4ec5e570c..7852187b77 100644
--- a/core/variant/method_ptrcall.h
+++ b/core/variant/method_ptrcall.h
@@ -45,6 +45,7 @@ struct PtrToArg {};
_FORCE_INLINE_ static m_type convert(const void *p_ptr) { \
return *reinterpret_cast<const m_type *>(p_ptr); \
} \
+ typedef m_type EncodeT; \
_FORCE_INLINE_ static void encode(m_type p_val, void *p_ptr) { \
*((m_type *)p_ptr) = p_val; \
} \
@@ -54,6 +55,7 @@ struct PtrToArg {};
_FORCE_INLINE_ static m_type convert(const void *p_ptr) { \
return *reinterpret_cast<const m_type *>(p_ptr); \
} \
+ typedef m_type EncodeT; \
_FORCE_INLINE_ static void encode(m_type p_val, void *p_ptr) { \
*((m_type *)p_ptr) = p_val; \
} \
@@ -65,6 +67,7 @@ struct PtrToArg {};
_FORCE_INLINE_ static m_type convert(const void *p_ptr) { \
return static_cast<m_type>(*reinterpret_cast<const m_conv *>(p_ptr)); \
} \
+ typedef m_conv EncodeT; \
_FORCE_INLINE_ static void encode(m_type p_val, void *p_ptr) { \
*((m_conv *)p_ptr) = static_cast<m_conv>(p_val); \
} \
@@ -74,6 +77,7 @@ struct PtrToArg {};
_FORCE_INLINE_ static m_type convert(const void *p_ptr) { \
return static_cast<m_type>(*reinterpret_cast<const m_conv *>(p_ptr)); \
} \
+ typedef m_conv EncodeT; \
_FORCE_INLINE_ static void encode(m_type p_val, void *p_ptr) { \
*((m_conv *)p_ptr) = static_cast<m_conv>(p_val); \
} \
@@ -85,6 +89,7 @@ struct PtrToArg {};
_FORCE_INLINE_ static m_type convert(const void *p_ptr) { \
return *reinterpret_cast<const m_type *>(p_ptr); \
} \
+ typedef m_type EncodeT; \
_FORCE_INLINE_ static void encode(const m_type &p_val, void *p_ptr) { \
*((m_type *)p_ptr) = p_val; \
} \
@@ -94,12 +99,13 @@ struct PtrToArg {};
_FORCE_INLINE_ static m_type convert(const void *p_ptr) { \
return *reinterpret_cast<const m_type *>(p_ptr); \
} \
+ typedef m_type EncodeT; \
_FORCE_INLINE_ static void encode(const m_type &p_val, void *p_ptr) { \
*((m_type *)p_ptr) = p_val; \
} \
}
-MAKE_PTRARG(bool);
+MAKE_PTRARGCONV(bool, uint32_t);
// Integer types.
MAKE_PTRARGCONV(uint8_t, int64_t);
MAKE_PTRARGCONV(int8_t, int64_t);
@@ -153,7 +159,7 @@ struct PtrToArg<T *> {
_FORCE_INLINE_ static T *convert(const void *p_ptr) {
return const_cast<T *>(reinterpret_cast<const T *>(p_ptr));
}
-
+ typedef Object *EncodeT;
_FORCE_INLINE_ static void encode(T *p_var, void *p_ptr) {
*((T **)p_ptr) = p_var;
}
@@ -164,7 +170,7 @@ struct PtrToArg<const T *> {
_FORCE_INLINE_ static const T *convert(const void *p_ptr) {
return reinterpret_cast<const T *>(p_ptr);
}
-
+ typedef const Object *EncodeT;
_FORCE_INLINE_ static void encode(T *p_var, void *p_ptr) {
*((T **)p_ptr) = p_var;
}
@@ -177,7 +183,7 @@ struct PtrToArg<ObjectID> {
_FORCE_INLINE_ static const ObjectID convert(const void *p_ptr) {
return ObjectID(*reinterpret_cast<const uint64_t *>(p_ptr));
}
-
+ typedef uint64_t EncodeT;
_FORCE_INLINE_ static void encode(const ObjectID &p_val, void *p_ptr) {
*((uint64_t *)p_ptr) = p_val;
}
diff --git a/core/variant/variant.cpp b/core/variant/variant.cpp
index 4e45862fd3..badb5ba103 100644
--- a/core/variant/variant.cpp
+++ b/core/variant/variant.cpp
@@ -32,6 +32,7 @@
#include "core/core_string_names.h"
#include "core/debugger/engine_debugger.h"
+#include "core/io/json.h"
#include "core/io/marshalls.h"
#include "core/io/resource.h"
#include "core/math/math_funcs.h"
@@ -1838,6 +1839,11 @@ String Variant::stringify(List<const void *> &stack) const {
return "";
}
+String Variant::to_json_string() const {
+ JSON json;
+ return json.stringify(*this);
+}
+
Variant::operator Vector2() const {
if (type == VECTOR2) {
return *reinterpret_cast<const Vector2 *>(_data._mem);
diff --git a/core/variant/variant.h b/core/variant/variant.h
index 75316da63f..373fe32921 100644
--- a/core/variant/variant.h
+++ b/core/variant/variant.h
@@ -499,6 +499,7 @@ public:
static bool is_builtin_method_vararg(Variant::Type p_type, const StringName &p_method);
static void get_builtin_method_list(Variant::Type p_type, List<StringName> *p_list);
static int get_builtin_method_count(Variant::Type p_type);
+ static uint32_t get_builtin_method_hash(Variant::Type p_type, const StringName &p_method);
void call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error);
Variant call(const StringName &p_method, const Variant &p_arg1 = Variant(), const Variant &p_arg2 = Variant(), const Variant &p_arg3 = Variant(), const Variant &p_arg4 = Variant(), const Variant &p_arg5 = Variant());
@@ -586,7 +587,7 @@ public:
typedef void (*PTRKeyedSetter)(void *base, const void *key, const void *value);
typedef void (*PTRKeyedGetter)(const void *base, const void *key, void *value);
- typedef bool (*PTRKeyedChecker)(const void *base, const void *key);
+ typedef uint32_t (*PTRKeyedChecker)(const void *base, const void *key);
static PTRKeyedSetter get_member_ptr_keyed_setter(Variant::Type p_type);
static PTRKeyedGetter get_member_ptr_keyed_getter(Variant::Type p_type);
@@ -631,6 +632,7 @@ public:
static bool has_utility_function_return_value(const StringName &p_name);
static Variant::Type get_utility_function_return_type(const StringName &p_name);
static bool is_utility_function_vararg(const StringName &p_name);
+ static uint32_t get_utility_function_hash(const StringName &p_name);
static void get_utility_function_list(List<StringName> *r_functions);
static int get_utility_function_count();
@@ -645,6 +647,7 @@ public:
bool hash_compare(const Variant &p_variant) const;
bool booleanize() const;
String stringify(List<const void *> &stack) const;
+ String to_json_string() const;
void static_assign(const Variant &p_variant);
static void get_constants_for_type(Variant::Type p_type, List<StringName> *p_constants);
diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp
index 9c7cd23d72..733361fe58 100644
--- a/core/variant/variant_call.cpp
+++ b/core/variant/variant_call.cpp
@@ -1126,6 +1126,25 @@ bool Variant::is_builtin_method_vararg(Variant::Type p_type, const StringName &p
return method->is_vararg;
}
+uint32_t Variant::get_builtin_method_hash(Variant::Type p_type, const StringName &p_method) {
+ ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, 0);
+ const VariantBuiltInMethodInfo *method = builtin_method_info[p_type].lookup_ptr(p_method);
+ ERR_FAIL_COND_V(!method, 0);
+ uint32_t hash = hash_djb2_one_32(method->is_const);
+ hash = hash_djb2_one_32(method->is_static, hash);
+ hash = hash_djb2_one_32(method->is_vararg, hash);
+ hash = hash_djb2_one_32(method->has_return_type, hash);
+ if (method->has_return_type) {
+ hash = hash_djb2_one_32(method->return_type, hash);
+ }
+ hash = hash_djb2_one_32(method->argument_count, hash);
+ for (int i = 0; i < method->argument_count; i++) {
+ hash = method->get_argument_type(i);
+ }
+
+ return hash;
+}
+
void Variant::get_method_list(List<MethodInfo> *p_list) const {
if (type == OBJECT) {
Object *obj = get_validated_object();
@@ -1611,6 +1630,7 @@ static void _register_variant_builtin_methods() {
bind_method(Callable, is_null, sarray(), varray());
bind_method(Callable, is_custom, sarray(), varray());
bind_method(Callable, is_standard, sarray(), varray());
+ bind_method(Callable, is_valid, sarray(), varray());
bind_method(Callable, get_object, sarray(), varray());
bind_method(Callable, get_object_id, sarray(), varray());
bind_method(Callable, get_method, sarray(), varray());
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..16c7428781 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);
@@ -1996,8 +661,8 @@ static const char *_op_names[Variant::OP_MAX] = {
"-",
"*",
"/",
- "-",
- "+",
+ "unary-",
+ "unary+",
"%",
"<<",
">>",
diff --git a/core/variant/variant_op.h b/core/variant/variant_op.h
new file mode 100644
index 0000000000..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_parser.cpp b/core/variant/variant_parser.cpp
index 28930a19e2..86d5ae7f38 100644
--- a/core/variant/variant_parser.cpp
+++ b/core/variant/variant_parser.cpp
@@ -738,10 +738,10 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
String type = token.value;
- Object *obj = ClassDB::instance(type);
+ Object *obj = ClassDB::instantiate(type);
if (!obj) {
- r_err_str = "Can't instance Object() of type: " + type;
+ r_err_str = "Can't instantiate Object() of type: " + type;
return ERR_PARSE_ERROR;
}
@@ -1204,16 +1204,32 @@ Error VariantParser::_parse_tag(Token &token, Stream *p_stream, int &line, Strin
r_tag.name = "";
r_tag.fields.clear();
- while (true) {
- char32_t c = p_stream->get_char();
- if (p_stream->is_eof()) {
- r_err_str = "Unexpected EOF while parsing simple tag";
- return ERR_PARSE_ERROR;
+ if (p_stream->is_utf8()) {
+ CharString cs;
+ while (true) {
+ char c = p_stream->get_char();
+ if (p_stream->is_eof()) {
+ r_err_str = "Unexpected EOF while parsing simple tag";
+ return ERR_PARSE_ERROR;
+ }
+ if (c == ']') {
+ break;
+ }
+ cs += c;
}
- if (c == ']') {
- break;
+ r_tag.name.parse_utf8(cs.get_data(), cs.length());
+ } else {
+ while (true) {
+ char32_t c = p_stream->get_char();
+ if (p_stream->is_eof()) {
+ r_err_str = "Unexpected EOF while parsing simple tag";
+ return ERR_PARSE_ERROR;
+ }
+ if (c == ']') {
+ break;
+ }
+ r_tag.name += String::chr(c);
}
- r_tag.name += String::chr(c);
}
r_tag.name = r_tag.name.strip_edges();
diff --git a/core/variant/variant_setget.cpp b/core/variant/variant_setget.cpp
index ae2795f2fd..de1deace63 100644
--- a/core/variant/variant_setget.cpp
+++ b/core/variant/variant_setget.cpp
@@ -28,282 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "variant.h"
-
-#include "core/core_string_names.h"
-#include "core/debugger/engine_debugger.h"
-#include "core/object/class_db.h"
-#include "core/templates/local_vector.h"
-#include "core/variant/variant_internal.h"
-
-/**** NAMED SETTERS AND GETTERS ****/
-
-#define SETGET_STRUCT(m_base_type, m_member_type, m_member) \
- struct VariantSetGet_##m_base_type##_##m_member { \
- static void get(const Variant *base, Variant *member) { \
- VariantTypeAdjust<m_member_type>::adjust(member); \
- *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_member; \
- } \
- static void ptr_get(const void *base, void *member) { \
- PtrToArg<m_member_type>::encode(PtrToArg<m_base_type>::convert(base).m_member, member); \
- } \
- static void set(Variant *base, const Variant *value, bool &valid) { \
- if (value->get_type() == GetTypeInfo<m_member_type>::VARIANT_TYPE) { \
- VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_member = *VariantGetInternalPtr<m_member_type>::get_ptr(value); \
- valid = true; \
- } else { \
- valid = false; \
- } \
- } \
- static void validated_set(Variant *base, const Variant *value) { \
- VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_member = *VariantGetInternalPtr<m_member_type>::get_ptr(value); \
- } \
- static void ptr_set(void *base, const void *member) { \
- m_base_type b = PtrToArg<m_base_type>::convert(base); \
- b.m_member = PtrToArg<m_member_type>::convert(member); \
- PtrToArg<m_base_type>::encode(b, base); \
- } \
- static Variant::Type get_type() { return GetTypeInfo<m_member_type>::VARIANT_TYPE; } \
- };
-
-#define SETGET_NUMBER_STRUCT(m_base_type, m_member_type, m_member) \
- struct VariantSetGet_##m_base_type##_##m_member { \
- static void get(const Variant *base, Variant *member) { \
- VariantTypeAdjust<m_member_type>::adjust(member); \
- *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_member; \
- } \
- static void ptr_get(const void *base, void *member) { \
- PtrToArg<m_member_type>::encode(PtrToArg<m_base_type>::convert(base).m_member, member); \
- } \
- static void set(Variant *base, const Variant *value, bool &valid) { \
- if (value->get_type() == Variant::FLOAT) { \
- VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_member = *VariantGetInternalPtr<double>::get_ptr(value); \
- valid = true; \
- } else if (value->get_type() == Variant::INT) { \
- VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_member = *VariantGetInternalPtr<int64_t>::get_ptr(value); \
- valid = true; \
- } else { \
- valid = false; \
- } \
- } \
- static void validated_set(Variant *base, const Variant *value) { \
- VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_member = *VariantGetInternalPtr<m_member_type>::get_ptr(value); \
- } \
- static void ptr_set(void *base, const void *member) { \
- m_base_type b = PtrToArg<m_base_type>::convert(base); \
- b.m_member = PtrToArg<m_member_type>::convert(member); \
- PtrToArg<m_base_type>::encode(b, base); \
- } \
- static Variant::Type get_type() { return GetTypeInfo<m_member_type>::VARIANT_TYPE; } \
- };
-
-#define SETGET_STRUCT_CUSTOM(m_base_type, m_member_type, m_member, m_custom) \
- struct VariantSetGet_##m_base_type##_##m_member { \
- static void get(const Variant *base, Variant *member) { \
- VariantTypeAdjust<m_member_type>::adjust(member); \
- *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_custom; \
- } \
- static void ptr_get(const void *base, void *member) { \
- PtrToArg<m_member_type>::encode(PtrToArg<m_base_type>::convert(base).m_custom, member); \
- } \
- static void set(Variant *base, const Variant *value, bool &valid) { \
- if (value->get_type() == GetTypeInfo<m_member_type>::VARIANT_TYPE) { \
- VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_custom = *VariantGetInternalPtr<m_member_type>::get_ptr(value); \
- valid = true; \
- } else { \
- valid = false; \
- } \
- } \
- static void validated_set(Variant *base, const Variant *value) { \
- VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_custom = *VariantGetInternalPtr<m_member_type>::get_ptr(value); \
- } \
- static void ptr_set(void *base, const void *member) { \
- m_base_type b = PtrToArg<m_base_type>::convert(base); \
- b.m_custom = PtrToArg<m_member_type>::convert(member); \
- PtrToArg<m_base_type>::encode(b, base); \
- } \
- static Variant::Type get_type() { return GetTypeInfo<m_member_type>::VARIANT_TYPE; } \
- };
-
-#define SETGET_NUMBER_STRUCT_CUSTOM(m_base_type, m_member_type, m_member, m_custom) \
- struct VariantSetGet_##m_base_type##_##m_member { \
- static void get(const Variant *base, Variant *member) { \
- VariantTypeAdjust<m_member_type>::adjust(member); \
- *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_custom; \
- } \
- static void ptr_get(const void *base, void *member) { \
- PtrToArg<m_member_type>::encode(PtrToArg<m_base_type>::convert(base).m_custom, member); \
- } \
- static void set(Variant *base, const Variant *value, bool &valid) { \
- if (value->get_type() == Variant::FLOAT) { \
- VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_custom = *VariantGetInternalPtr<double>::get_ptr(value); \
- valid = true; \
- } else if (value->get_type() == Variant::INT) { \
- VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_custom = *VariantGetInternalPtr<int64_t>::get_ptr(value); \
- valid = true; \
- } else { \
- valid = false; \
- } \
- } \
- static void validated_set(Variant *base, const Variant *value) { \
- VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_custom = *VariantGetInternalPtr<m_member_type>::get_ptr(value); \
- } \
- static void ptr_set(void *base, const void *member) { \
- m_base_type b = PtrToArg<m_base_type>::convert(base); \
- b.m_custom = PtrToArg<m_member_type>::convert(member); \
- PtrToArg<m_base_type>::encode(b, base); \
- } \
- static Variant::Type get_type() { return GetTypeInfo<m_member_type>::VARIANT_TYPE; } \
- };
-
-#define SETGET_STRUCT_FUNC(m_base_type, m_member_type, m_member, m_setter, m_getter) \
- struct VariantSetGet_##m_base_type##_##m_member { \
- static void get(const Variant *base, Variant *member) { \
- VariantTypeAdjust<m_member_type>::adjust(member); \
- *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_getter(); \
- } \
- static void ptr_get(const void *base, void *member) { \
- PtrToArg<m_member_type>::encode(PtrToArg<m_base_type>::convert(base).m_getter(), member); \
- } \
- static void set(Variant *base, const Variant *value, bool &valid) { \
- if (value->get_type() == GetTypeInfo<m_member_type>::VARIANT_TYPE) { \
- VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_setter(*VariantGetInternalPtr<m_member_type>::get_ptr(value)); \
- valid = true; \
- } else { \
- valid = false; \
- } \
- } \
- static void validated_set(Variant *base, const Variant *value) { \
- VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_setter(*VariantGetInternalPtr<m_member_type>::get_ptr(value)); \
- } \
- static void ptr_set(void *base, const void *member) { \
- m_base_type b = PtrToArg<m_base_type>::convert(base); \
- b.m_setter(PtrToArg<m_member_type>::convert(member)); \
- PtrToArg<m_base_type>::encode(b, base); \
- } \
- static Variant::Type get_type() { return GetTypeInfo<m_member_type>::VARIANT_TYPE; } \
- };
-
-#define SETGET_NUMBER_STRUCT_FUNC(m_base_type, m_member_type, m_member, m_setter, m_getter) \
- struct VariantSetGet_##m_base_type##_##m_member { \
- static void get(const Variant *base, Variant *member) { \
- VariantTypeAdjust<m_member_type>::adjust(member); \
- *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_getter(); \
- } \
- static void ptr_get(const void *base, void *member) { \
- PtrToArg<m_member_type>::encode(PtrToArg<m_base_type>::convert(base).m_getter(), member); \
- } \
- static void set(Variant *base, const Variant *value, bool &valid) { \
- if (value->get_type() == Variant::FLOAT) { \
- VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_setter(*VariantGetInternalPtr<double>::get_ptr(value)); \
- valid = true; \
- } else if (value->get_type() == Variant::INT) { \
- VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_setter(*VariantGetInternalPtr<int64_t>::get_ptr(value)); \
- valid = true; \
- } else { \
- valid = false; \
- } \
- } \
- static void validated_set(Variant *base, const Variant *value) { \
- VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_setter(*VariantGetInternalPtr<m_member_type>::get_ptr(value)); \
- } \
- static void ptr_set(void *base, const void *member) { \
- m_base_type b = PtrToArg<m_base_type>::convert(base); \
- b.m_setter(PtrToArg<m_member_type>::convert(member)); \
- PtrToArg<m_base_type>::encode(b, base); \
- } \
- static Variant::Type get_type() { return GetTypeInfo<m_member_type>::VARIANT_TYPE; } \
- };
-
-#define SETGET_STRUCT_FUNC_INDEX(m_base_type, m_member_type, m_member, m_setter, m_getter, m_index) \
- struct VariantSetGet_##m_base_type##_##m_member { \
- static void get(const Variant *base, Variant *member) { \
- VariantTypeAdjust<m_member_type>::adjust(member); \
- *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_getter(m_index); \
- } \
- static void ptr_get(const void *base, void *member) { \
- PtrToArg<m_member_type>::encode(PtrToArg<m_base_type>::convert(base).m_getter(m_index), member); \
- } \
- static void set(Variant *base, const Variant *value, bool &valid) { \
- if (value->get_type() == GetTypeInfo<m_member_type>::VARIANT_TYPE) { \
- VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_setter(m_index, *VariantGetInternalPtr<m_member_type>::get_ptr(value)); \
- valid = true; \
- } else { \
- valid = false; \
- } \
- } \
- static void validated_set(Variant *base, const Variant *value) { \
- VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_setter(m_index, *VariantGetInternalPtr<m_member_type>::get_ptr(value)); \
- } \
- static void ptr_set(void *base, const void *member) { \
- m_base_type b = PtrToArg<m_base_type>::convert(base); \
- b.m_setter(m_index, PtrToArg<m_member_type>::convert(member)); \
- PtrToArg<m_base_type>::encode(b, base); \
- } \
- static Variant::Type get_type() { return GetTypeInfo<m_member_type>::VARIANT_TYPE; } \
- };
-
-SETGET_NUMBER_STRUCT(Vector2, double, x)
-SETGET_NUMBER_STRUCT(Vector2, double, y)
-
-SETGET_NUMBER_STRUCT(Vector2i, int64_t, x)
-SETGET_NUMBER_STRUCT(Vector2i, int64_t, y)
-
-SETGET_NUMBER_STRUCT(Vector3, double, x)
-SETGET_NUMBER_STRUCT(Vector3, double, y)
-SETGET_NUMBER_STRUCT(Vector3, double, z)
-
-SETGET_NUMBER_STRUCT(Vector3i, int64_t, x)
-SETGET_NUMBER_STRUCT(Vector3i, int64_t, y)
-SETGET_NUMBER_STRUCT(Vector3i, int64_t, z)
-
-SETGET_STRUCT(Rect2, Vector2, position)
-SETGET_STRUCT(Rect2, Vector2, size)
-SETGET_STRUCT_FUNC(Rect2, Vector2, end, set_end, get_end)
-
-SETGET_STRUCT(Rect2i, Vector2i, position)
-SETGET_STRUCT(Rect2i, Vector2i, size)
-SETGET_STRUCT_FUNC(Rect2i, Vector2i, end, set_end, get_end)
-
-SETGET_STRUCT(AABB, Vector3, position)
-SETGET_STRUCT(AABB, Vector3, size)
-SETGET_STRUCT_FUNC(AABB, Vector3, end, set_end, get_end)
-
-SETGET_STRUCT_CUSTOM(Transform2D, Vector2, x, elements[0])
-SETGET_STRUCT_CUSTOM(Transform2D, Vector2, y, elements[1])
-SETGET_STRUCT_CUSTOM(Transform2D, Vector2, origin, elements[2])
-
-SETGET_NUMBER_STRUCT_CUSTOM(Plane, double, x, normal.x)
-SETGET_NUMBER_STRUCT_CUSTOM(Plane, double, y, normal.y)
-SETGET_NUMBER_STRUCT_CUSTOM(Plane, double, z, normal.z)
-SETGET_STRUCT(Plane, Vector3, normal)
-SETGET_NUMBER_STRUCT(Plane, double, d)
-
-SETGET_NUMBER_STRUCT(Quaternion, double, x)
-SETGET_NUMBER_STRUCT(Quaternion, double, y)
-SETGET_NUMBER_STRUCT(Quaternion, double, z)
-SETGET_NUMBER_STRUCT(Quaternion, double, w)
-
-SETGET_STRUCT_FUNC_INDEX(Basis, Vector3, x, set_axis, get_axis, 0)
-SETGET_STRUCT_FUNC_INDEX(Basis, Vector3, y, set_axis, get_axis, 1)
-SETGET_STRUCT_FUNC_INDEX(Basis, Vector3, z, set_axis, get_axis, 2)
-
-SETGET_STRUCT(Transform3D, Basis, basis)
-SETGET_STRUCT(Transform3D, Vector3, origin)
-
-SETGET_NUMBER_STRUCT(Color, double, r)
-SETGET_NUMBER_STRUCT(Color, double, g)
-SETGET_NUMBER_STRUCT(Color, double, b)
-SETGET_NUMBER_STRUCT(Color, double, a)
-
-SETGET_NUMBER_STRUCT_FUNC(Color, int64_t, r8, set_r8, get_r8)
-SETGET_NUMBER_STRUCT_FUNC(Color, int64_t, g8, set_g8, get_g8)
-SETGET_NUMBER_STRUCT_FUNC(Color, int64_t, b8, set_b8, get_b8)
-SETGET_NUMBER_STRUCT_FUNC(Color, int64_t, a8, set_a8, get_a8)
-
-SETGET_NUMBER_STRUCT_FUNC(Color, double, h, set_h, get_h)
-SETGET_NUMBER_STRUCT_FUNC(Color, double, s, set_s, get_s)
-SETGET_NUMBER_STRUCT_FUNC(Color, double, v, set_v, get_v)
+#include "variant_setget.h"
struct VariantSetterGetterInfo {
void (*setter)(Variant *base, const Variant *value, bool &valid);
@@ -326,7 +51,7 @@ static void register_member(Variant::Type p_type, const StringName &p_member) {
sgi.ptr_setter = T::ptr_set;
sgi.getter = T::get;
- sgi.validated_getter = T::get;
+ sgi.validated_getter = T::validated_get;
sgi.ptr_getter = T::ptr_get;
sgi.member_type = T::get_type();
@@ -1146,7 +871,7 @@ struct VariantKeyedSetGetDictionary {
*r_valid = true;
return VariantGetInternalPtr<Dictionary>::get_ptr(base)->has(*key);
}
- static bool ptr_has(const void *base, const void *key) {
+ static uint32_t ptr_has(const void *base, const void *key) {
/* avoid ptrconvert for performance*/
const Dictionary &v = *reinterpret_cast<const Dictionary *>(base);
return v.has(PtrToArg<Variant>::convert(key));
@@ -1196,7 +921,7 @@ struct VariantKeyedSetGetObject {
obj->getvar(*key, &exists);
return exists;
}
- static bool ptr_has(const void *base, const void *key) {
+ static uint32_t ptr_has(const void *base, const void *key) {
const Object *obj = PtrToArg<Object *>::convert(base);
ERR_FAIL_COND_V(!obj, false);
bool valid;
diff --git a/core/variant/variant_setget.h b/core/variant/variant_setget.h
new file mode 100644
index 0000000000..dbf24ab3e3
--- /dev/null
+++ b/core/variant/variant_setget.h
@@ -0,0 +1,332 @@
+/*************************************************************************/
+/* variant_setget.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef VARIANT_SETGET_H
+#define VARIANT_SETGET_H
+
+#include "variant.h"
+
+#include "core/core_string_names.h"
+#include "core/debugger/engine_debugger.h"
+#include "core/object/class_db.h"
+#include "core/templates/local_vector.h"
+#include "core/variant/variant_internal.h"
+
+/**** NAMED SETTERS AND GETTERS ****/
+
+#define SETGET_STRUCT(m_base_type, m_member_type, m_member) \
+ struct VariantSetGet_##m_base_type##_##m_member { \
+ static void get(const Variant *base, Variant *member) { \
+ VariantTypeAdjust<m_member_type>::adjust(member); \
+ *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_member; \
+ } \
+ static inline void validated_get(const Variant *base, Variant *member) { \
+ *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_member; \
+ } \
+ static void ptr_get(const void *base, void *member) { \
+ PtrToArg<m_member_type>::encode(PtrToArg<m_base_type>::convert(base).m_member, member); \
+ } \
+ static void set(Variant *base, const Variant *value, bool &valid) { \
+ if (value->get_type() == GetTypeInfo<m_member_type>::VARIANT_TYPE) { \
+ VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_member = *VariantGetInternalPtr<m_member_type>::get_ptr(value); \
+ valid = true; \
+ } else { \
+ valid = false; \
+ } \
+ } \
+ static inline void validated_set(Variant *base, const Variant *value) { \
+ VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_member = *VariantGetInternalPtr<m_member_type>::get_ptr(value); \
+ } \
+ static void ptr_set(void *base, const void *member) { \
+ m_base_type b = PtrToArg<m_base_type>::convert(base); \
+ b.m_member = PtrToArg<m_member_type>::convert(member); \
+ PtrToArg<m_base_type>::encode(b, base); \
+ } \
+ static Variant::Type get_type() { return GetTypeInfo<m_member_type>::VARIANT_TYPE; } \
+ };
+
+#define SETGET_NUMBER_STRUCT(m_base_type, m_member_type, m_member) \
+ struct VariantSetGet_##m_base_type##_##m_member { \
+ static void get(const Variant *base, Variant *member) { \
+ VariantTypeAdjust<m_member_type>::adjust(member); \
+ *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_member; \
+ } \
+ static inline void validated_get(const Variant *base, Variant *member) { \
+ *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_member; \
+ } \
+ static void ptr_get(const void *base, void *member) { \
+ PtrToArg<m_member_type>::encode(PtrToArg<m_base_type>::convert(base).m_member, member); \
+ } \
+ static void set(Variant *base, const Variant *value, bool &valid) { \
+ if (value->get_type() == Variant::FLOAT) { \
+ VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_member = *VariantGetInternalPtr<double>::get_ptr(value); \
+ valid = true; \
+ } else if (value->get_type() == Variant::INT) { \
+ VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_member = *VariantGetInternalPtr<int64_t>::get_ptr(value); \
+ valid = true; \
+ } else { \
+ valid = false; \
+ } \
+ } \
+ static inline void validated_set(Variant *base, const Variant *value) { \
+ VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_member = *VariantGetInternalPtr<m_member_type>::get_ptr(value); \
+ } \
+ static void ptr_set(void *base, const void *member) { \
+ m_base_type b = PtrToArg<m_base_type>::convert(base); \
+ b.m_member = PtrToArg<m_member_type>::convert(member); \
+ PtrToArg<m_base_type>::encode(b, base); \
+ } \
+ static Variant::Type get_type() { return GetTypeInfo<m_member_type>::VARIANT_TYPE; } \
+ };
+
+#define SETGET_STRUCT_CUSTOM(m_base_type, m_member_type, m_member, m_custom) \
+ struct VariantSetGet_##m_base_type##_##m_member { \
+ static void get(const Variant *base, Variant *member) { \
+ VariantTypeAdjust<m_member_type>::adjust(member); \
+ *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_custom; \
+ } \
+ static inline void validated_get(const Variant *base, Variant *member) { \
+ *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_custom; \
+ } \
+ static void ptr_get(const void *base, void *member) { \
+ PtrToArg<m_member_type>::encode(PtrToArg<m_base_type>::convert(base).m_custom, member); \
+ } \
+ static void set(Variant *base, const Variant *value, bool &valid) { \
+ if (value->get_type() == GetTypeInfo<m_member_type>::VARIANT_TYPE) { \
+ VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_custom = *VariantGetInternalPtr<m_member_type>::get_ptr(value); \
+ valid = true; \
+ } else { \
+ valid = false; \
+ } \
+ } \
+ static inline void validated_set(Variant *base, const Variant *value) { \
+ VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_custom = *VariantGetInternalPtr<m_member_type>::get_ptr(value); \
+ } \
+ static void ptr_set(void *base, const void *member) { \
+ m_base_type b = PtrToArg<m_base_type>::convert(base); \
+ b.m_custom = PtrToArg<m_member_type>::convert(member); \
+ PtrToArg<m_base_type>::encode(b, base); \
+ } \
+ static Variant::Type get_type() { return GetTypeInfo<m_member_type>::VARIANT_TYPE; } \
+ };
+
+#define SETGET_NUMBER_STRUCT_CUSTOM(m_base_type, m_member_type, m_member, m_custom) \
+ struct VariantSetGet_##m_base_type##_##m_member { \
+ static void get(const Variant *base, Variant *member) { \
+ VariantTypeAdjust<m_member_type>::adjust(member); \
+ *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_custom; \
+ } \
+ static inline void validated_get(const Variant *base, Variant *member) { \
+ *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_custom; \
+ } \
+ static void ptr_get(const void *base, void *member) { \
+ PtrToArg<m_member_type>::encode(PtrToArg<m_base_type>::convert(base).m_custom, member); \
+ } \
+ static void set(Variant *base, const Variant *value, bool &valid) { \
+ if (value->get_type() == Variant::FLOAT) { \
+ VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_custom = *VariantGetInternalPtr<double>::get_ptr(value); \
+ valid = true; \
+ } else if (value->get_type() == Variant::INT) { \
+ VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_custom = *VariantGetInternalPtr<int64_t>::get_ptr(value); \
+ valid = true; \
+ } else { \
+ valid = false; \
+ } \
+ } \
+ static inline void validated_set(Variant *base, const Variant *value) { \
+ VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_custom = *VariantGetInternalPtr<m_member_type>::get_ptr(value); \
+ } \
+ static void ptr_set(void *base, const void *member) { \
+ m_base_type b = PtrToArg<m_base_type>::convert(base); \
+ b.m_custom = PtrToArg<m_member_type>::convert(member); \
+ PtrToArg<m_base_type>::encode(b, base); \
+ } \
+ static Variant::Type get_type() { return GetTypeInfo<m_member_type>::VARIANT_TYPE; } \
+ };
+
+#define SETGET_STRUCT_FUNC(m_base_type, m_member_type, m_member, m_setter, m_getter) \
+ struct VariantSetGet_##m_base_type##_##m_member { \
+ static void get(const Variant *base, Variant *member) { \
+ VariantTypeAdjust<m_member_type>::adjust(member); \
+ *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_getter(); \
+ } \
+ static inline void validated_get(const Variant *base, Variant *member) { \
+ *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_getter(); \
+ } \
+ static void ptr_get(const void *base, void *member) { \
+ PtrToArg<m_member_type>::encode(PtrToArg<m_base_type>::convert(base).m_getter(), member); \
+ } \
+ static void set(Variant *base, const Variant *value, bool &valid) { \
+ if (value->get_type() == GetTypeInfo<m_member_type>::VARIANT_TYPE) { \
+ VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_setter(*VariantGetInternalPtr<m_member_type>::get_ptr(value)); \
+ valid = true; \
+ } else { \
+ valid = false; \
+ } \
+ } \
+ static inline void validated_set(Variant *base, const Variant *value) { \
+ VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_setter(*VariantGetInternalPtr<m_member_type>::get_ptr(value)); \
+ } \
+ static void ptr_set(void *base, const void *member) { \
+ m_base_type b = PtrToArg<m_base_type>::convert(base); \
+ b.m_setter(PtrToArg<m_member_type>::convert(member)); \
+ PtrToArg<m_base_type>::encode(b, base); \
+ } \
+ static Variant::Type get_type() { return GetTypeInfo<m_member_type>::VARIANT_TYPE; } \
+ };
+
+#define SETGET_NUMBER_STRUCT_FUNC(m_base_type, m_member_type, m_member, m_setter, m_getter) \
+ struct VariantSetGet_##m_base_type##_##m_member { \
+ static void get(const Variant *base, Variant *member) { \
+ VariantTypeAdjust<m_member_type>::adjust(member); \
+ *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_getter(); \
+ } \
+ static inline void validated_get(const Variant *base, Variant *member) { \
+ *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_getter(); \
+ } \
+ static void ptr_get(const void *base, void *member) { \
+ PtrToArg<m_member_type>::encode(PtrToArg<m_base_type>::convert(base).m_getter(), member); \
+ } \
+ static void set(Variant *base, const Variant *value, bool &valid) { \
+ if (value->get_type() == Variant::FLOAT) { \
+ VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_setter(*VariantGetInternalPtr<double>::get_ptr(value)); \
+ valid = true; \
+ } else if (value->get_type() == Variant::INT) { \
+ VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_setter(*VariantGetInternalPtr<int64_t>::get_ptr(value)); \
+ valid = true; \
+ } else { \
+ valid = false; \
+ } \
+ } \
+ static inline void validated_set(Variant *base, const Variant *value) { \
+ VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_setter(*VariantGetInternalPtr<m_member_type>::get_ptr(value)); \
+ } \
+ static void ptr_set(void *base, const void *member) { \
+ m_base_type b = PtrToArg<m_base_type>::convert(base); \
+ b.m_setter(PtrToArg<m_member_type>::convert(member)); \
+ PtrToArg<m_base_type>::encode(b, base); \
+ } \
+ static Variant::Type get_type() { return GetTypeInfo<m_member_type>::VARIANT_TYPE; } \
+ };
+
+#define SETGET_STRUCT_FUNC_INDEX(m_base_type, m_member_type, m_member, m_setter, m_getter, m_index) \
+ struct VariantSetGet_##m_base_type##_##m_member { \
+ static void get(const Variant *base, Variant *member) { \
+ VariantTypeAdjust<m_member_type>::adjust(member); \
+ *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_getter(m_index); \
+ } \
+ static inline void validated_get(const Variant *base, Variant *member) { \
+ *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_getter(m_index); \
+ } \
+ static void ptr_get(const void *base, void *member) { \
+ PtrToArg<m_member_type>::encode(PtrToArg<m_base_type>::convert(base).m_getter(m_index), member); \
+ } \
+ static void set(Variant *base, const Variant *value, bool &valid) { \
+ if (value->get_type() == GetTypeInfo<m_member_type>::VARIANT_TYPE) { \
+ VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_setter(m_index, *VariantGetInternalPtr<m_member_type>::get_ptr(value)); \
+ valid = true; \
+ } else { \
+ valid = false; \
+ } \
+ } \
+ static inline void validated_set(Variant *base, const Variant *value) { \
+ VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_setter(m_index, *VariantGetInternalPtr<m_member_type>::get_ptr(value)); \
+ } \
+ static void ptr_set(void *base, const void *member) { \
+ m_base_type b = PtrToArg<m_base_type>::convert(base); \
+ b.m_setter(m_index, PtrToArg<m_member_type>::convert(member)); \
+ PtrToArg<m_base_type>::encode(b, base); \
+ } \
+ static Variant::Type get_type() { return GetTypeInfo<m_member_type>::VARIANT_TYPE; } \
+ };
+
+SETGET_NUMBER_STRUCT(Vector2, double, x)
+SETGET_NUMBER_STRUCT(Vector2, double, y)
+
+SETGET_NUMBER_STRUCT(Vector2i, int64_t, x)
+SETGET_NUMBER_STRUCT(Vector2i, int64_t, y)
+
+SETGET_NUMBER_STRUCT(Vector3, double, x)
+SETGET_NUMBER_STRUCT(Vector3, double, y)
+SETGET_NUMBER_STRUCT(Vector3, double, z)
+
+SETGET_NUMBER_STRUCT(Vector3i, int64_t, x)
+SETGET_NUMBER_STRUCT(Vector3i, int64_t, y)
+SETGET_NUMBER_STRUCT(Vector3i, int64_t, z)
+
+SETGET_STRUCT(Rect2, Vector2, position)
+SETGET_STRUCT(Rect2, Vector2, size)
+SETGET_STRUCT_FUNC(Rect2, Vector2, end, set_end, get_end)
+
+SETGET_STRUCT(Rect2i, Vector2i, position)
+SETGET_STRUCT(Rect2i, Vector2i, size)
+SETGET_STRUCT_FUNC(Rect2i, Vector2i, end, set_end, get_end)
+
+SETGET_STRUCT(AABB, Vector3, position)
+SETGET_STRUCT(AABB, Vector3, size)
+SETGET_STRUCT_FUNC(AABB, Vector3, end, set_end, get_end)
+
+SETGET_STRUCT_CUSTOM(Transform2D, Vector2, x, elements[0])
+SETGET_STRUCT_CUSTOM(Transform2D, Vector2, y, elements[1])
+SETGET_STRUCT_CUSTOM(Transform2D, Vector2, origin, elements[2])
+
+SETGET_NUMBER_STRUCT_CUSTOM(Plane, double, x, normal.x)
+SETGET_NUMBER_STRUCT_CUSTOM(Plane, double, y, normal.y)
+SETGET_NUMBER_STRUCT_CUSTOM(Plane, double, z, normal.z)
+SETGET_STRUCT(Plane, Vector3, normal)
+SETGET_NUMBER_STRUCT(Plane, double, d)
+
+SETGET_NUMBER_STRUCT(Quaternion, double, x)
+SETGET_NUMBER_STRUCT(Quaternion, double, y)
+SETGET_NUMBER_STRUCT(Quaternion, double, z)
+SETGET_NUMBER_STRUCT(Quaternion, double, w)
+
+SETGET_STRUCT_FUNC_INDEX(Basis, Vector3, x, set_axis, get_axis, 0)
+SETGET_STRUCT_FUNC_INDEX(Basis, Vector3, y, set_axis, get_axis, 1)
+SETGET_STRUCT_FUNC_INDEX(Basis, Vector3, z, set_axis, get_axis, 2)
+
+SETGET_STRUCT(Transform3D, Basis, basis)
+SETGET_STRUCT(Transform3D, Vector3, origin)
+
+SETGET_NUMBER_STRUCT(Color, double, r)
+SETGET_NUMBER_STRUCT(Color, double, g)
+SETGET_NUMBER_STRUCT(Color, double, b)
+SETGET_NUMBER_STRUCT(Color, double, a)
+
+SETGET_NUMBER_STRUCT_FUNC(Color, int64_t, r8, set_r8, get_r8)
+SETGET_NUMBER_STRUCT_FUNC(Color, int64_t, g8, set_g8, get_g8)
+SETGET_NUMBER_STRUCT_FUNC(Color, int64_t, b8, set_b8, get_b8)
+SETGET_NUMBER_STRUCT_FUNC(Color, int64_t, a8, set_a8, get_a8)
+
+SETGET_NUMBER_STRUCT_FUNC(Color, double, h, set_h, get_h)
+SETGET_NUMBER_STRUCT_FUNC(Color, double, s, set_s, get_s)
+SETGET_NUMBER_STRUCT_FUNC(Color, double, v, set_v, get_v)
+
+#endif // VARIANT_SETGET_H
diff --git a/core/variant/variant_utility.cpp b/core/variant/variant_utility.cpp
index 5d1efb4166..1f69e81d99 100644
--- a/core/variant/variant_utility.cpp
+++ b/core/variant/variant_utility.cpp
@@ -1348,8 +1348,8 @@ String Variant::get_utility_function_argument_name(const StringName &p_name, int
if (!bfi) {
return String();
}
- ERR_FAIL_COND_V(bfi->is_vararg, String());
ERR_FAIL_INDEX_V(p_arg, bfi->argnames.size(), String());
+ ERR_FAIL_COND_V(bfi->is_vararg, String());
return bfi->argnames[p_arg];
}
@@ -1379,6 +1379,23 @@ bool Variant::is_utility_function_vararg(const StringName &p_name) {
return bfi->is_vararg;
}
+uint32_t Variant::get_utility_function_hash(const StringName &p_name) {
+ const VariantUtilityFunctionInfo *bfi = utility_function_table.lookup_ptr(p_name);
+ ERR_FAIL_COND_V(!bfi, 0);
+
+ uint32_t hash = hash_djb2_one_32(bfi->is_vararg);
+ hash = hash_djb2_one_32(bfi->returns_value, hash);
+ if (bfi->returns_value) {
+ hash = hash_djb2_one_32(bfi->return_type, hash);
+ }
+ hash = hash_djb2_one_32(bfi->argcount, hash);
+ for (int i = 0; i < bfi->argcount; i++) {
+ hash = hash_djb2_one_32(bfi->get_arg_type(i), hash);
+ }
+
+ return hash;
+}
+
void Variant::get_utility_function_list(List<StringName> *r_functions) {
for (List<StringName>::Element *E = utility_function_name_table.front(); E; E = E->next()) {
r_functions->push_back(E->get());