summaryrefslogtreecommitdiff
path: root/core/variant
diff options
context:
space:
mode:
Diffstat (limited to 'core/variant')
-rw-r--r--core/variant/array.cpp6
-rw-r--r--core/variant/binder_common.h19
-rw-r--r--core/variant/callable.cpp19
-rw-r--r--core/variant/callable.h8
-rw-r--r--core/variant/dictionary.cpp59
-rw-r--r--core/variant/method_ptrcall.h18
-rw-r--r--core/variant/type_info.h33
-rw-r--r--core/variant/typed_array.h8
-rw-r--r--core/variant/variant.cpp256
-rw-r--r--core/variant/variant.h46
-rw-r--r--core/variant/variant_call.cpp162
-rw-r--r--core/variant/variant_construct.cpp568
-rw-r--r--core/variant/variant_construct.h572
-rw-r--r--core/variant/variant_destruct.cpp78
-rw-r--r--core/variant/variant_destruct.h76
-rw-r--r--core/variant/variant_internal.h103
-rw-r--r--core/variant/variant_op.cpp1413
-rw-r--r--core/variant/variant_op.h1320
-rw-r--r--core/variant/variant_parser.cpp154
-rw-r--r--core/variant/variant_parser.h8
-rw-r--r--core/variant/variant_setget.cpp335
-rw-r--r--core/variant/variant_setget.h332
-rw-r--r--core/variant/variant_utility.cpp39
23 files changed, 3052 insertions, 2580 deletions
diff --git a/core/variant/array.cpp b/core/variant/array.cpp
index 3c7e2a0719..09cf785390 100644
--- a/core/variant/array.cpp
+++ b/core/variant/array.cpp
@@ -366,8 +366,8 @@ Array Array::filter(const Callable &p_callable) const {
new_arr.resize(size());
int accepted_count = 0;
+ const Variant *argptrs[1];
for (int i = 0; i < size(); i++) {
- const Variant **argptrs = (const Variant **)alloca(sizeof(Variant *));
argptrs[0] = &get(i);
Variant result;
@@ -392,8 +392,8 @@ Array Array::map(const Callable &p_callable) const {
Array new_arr;
new_arr.resize(size());
+ const Variant *argptrs[1];
for (int i = 0; i < size(); i++) {
- const Variant **argptrs = (const Variant **)alloca(sizeof(Variant *));
argptrs[0] = &get(i);
Variant result;
@@ -417,8 +417,8 @@ Variant Array::reduce(const Callable &p_callable, const Variant &p_accum) const
start = 1;
}
+ const Variant *argptrs[2];
for (int i = start; i < size(); i++) {
- const Variant **argptrs = (const Variant **)alloca(sizeof(Variant *) * 2);
argptrs[0] = &ret;
argptrs[1] = &get(i);
diff --git a/core/variant/binder_common.h b/core/variant/binder_common.h
index 830e0a5cbd..3b2c837096 100644
--- a/core/variant/binder_common.h
+++ b/core/variant/binder_common.h
@@ -31,7 +31,9 @@
#ifndef BINDER_COMMON_H
#define BINDER_COMMON_H
+#include "core/input/input_enums.h"
#include "core/object/object.h"
+#include "core/os/keyboard.h"
#include "core/templates/list.h"
#include "core/templates/simple_type.h"
#include "core/typedefs.h"
@@ -68,16 +70,17 @@ struct VariantCaster<const T &> {
template <> \
struct VariantCaster<m_enum> { \
static _FORCE_INLINE_ m_enum cast(const Variant &p_variant) { \
- return (m_enum)p_variant.operator int(); \
+ return (m_enum)p_variant.operator int64_t(); \
} \
}; \
template <> \
struct PtrToArg<m_enum> { \
_FORCE_INLINE_ static m_enum convert(const void *p_ptr) { \
- return m_enum(*reinterpret_cast<const int *>(p_ptr)); \
+ return m_enum(*reinterpret_cast<const int64_t *>(p_ptr)); \
} \
+ typedef int64_t EncodeT; \
_FORCE_INLINE_ static void encode(m_enum p_val, const void *p_ptr) { \
- *(int *)p_ptr = p_val; \
+ *(int64_t *)p_ptr = p_val; \
} \
};
@@ -90,9 +93,18 @@ VARIANT_ENUM_CAST(Error);
VARIANT_ENUM_CAST(Side);
VARIANT_ENUM_CAST(ClockDirection);
VARIANT_ENUM_CAST(Corner);
+VARIANT_ENUM_CAST(HatDir);
+VARIANT_ENUM_CAST(HatMask);
+VARIANT_ENUM_CAST(JoyAxis);
+VARIANT_ENUM_CAST(JoyButton);
+VARIANT_ENUM_CAST(Key);
+VARIANT_ENUM_CAST(KeyModifierMask);
+VARIANT_ENUM_CAST(MIDIMessage);
+VARIANT_ENUM_CAST(MouseButton);
VARIANT_ENUM_CAST(Orientation);
VARIANT_ENUM_CAST(HAlign);
VARIANT_ENUM_CAST(VAlign);
+VARIANT_ENUM_CAST(InlineAlign);
VARIANT_ENUM_CAST(PropertyHint);
VARIANT_ENUM_CAST(PropertyUsageFlags);
VARIANT_ENUM_CAST(Variant::Type);
@@ -110,6 +122,7 @@ struct PtrToArg<char32_t> {
_FORCE_INLINE_ static char32_t convert(const void *p_ptr) {
return char32_t(*reinterpret_cast<const int *>(p_ptr));
}
+ typedef int64_t EncodeT;
_FORCE_INLINE_ static void encode(char32_t p_val, const void *p_ptr) {
*(int *)p_ptr = p_val;
}
diff --git a/core/variant/callable.cpp b/core/variant/callable.cpp
index e06b3e07ef..f487e718f4 100644
--- a/core/variant/callable.cpp
+++ b/core/variant/callable.cpp
@@ -33,7 +33,7 @@
#include "callable_bind.h"
#include "core/object/message_queue.h"
#include "core/object/object.h"
-#include "core/object/reference.h"
+#include "core/object/ref_counted.h"
#include "core/object/script_language.h"
void Callable::call_deferred(const Variant **p_arguments, int p_argcount) const {
@@ -50,6 +50,15 @@ void Callable::call(const Variant **p_arguments, int p_argcount, Variant &r_retu
custom->call(p_arguments, p_argcount, r_return_value, r_call_error);
} else {
Object *obj = ObjectDB::get_instance(ObjectID(object));
+#ifdef DEBUG_ENABLED
+ if (!obj) {
+ r_call_error.error = CallError::CALL_ERROR_INSTANCE_IS_NULL;
+ r_call_error.argument = 0;
+ r_call_error.expected = 0;
+ r_return_value = Variant();
+ return;
+ }
+#endif
r_return_value = obj->call(method, p_arguments, p_argcount, r_call_error);
}
}
@@ -80,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;
@@ -394,8 +407,8 @@ Array Signal::get_connections() const {
object->get_signal_connection_list(name, &connections);
Array arr;
- for (List<Object::Connection>::Element *E = connections.front(); E; E = E->next()) {
- arr.push_back(E->get());
+ for (const Object::Connection &E : connections) {
+ arr.push_back(E);
}
return arr;
}
diff --git a/core/variant/callable.h b/core/variant/callable.h
index d91bebfa5f..52094af3aa 100644
--- a/core/variant/callable.h
+++ b/core/variant/callable.h
@@ -44,9 +44,9 @@ class CallableCustom;
// is required. It is designed for the standard case (object and method)
// but can be optimized or customized.
+// Enforce 16 bytes with `alignas` to avoid arch-specific alignment issues on x86 vs armv7.
class Callable {
- //needs to be max 16 bytes in 64 bits
- StringName method;
+ alignas(8) StringName method;
union {
uint64_t object = 0;
CallableCustom *custom;
@@ -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;
@@ -138,8 +139,9 @@ public:
// be put inside a Variant, but it is not
// used by the engine itself.
+// Enforce 16 bytes with `alignas` to avoid arch-specific alignment issues on x86 vs armv7.
class Signal {
- StringName name;
+ alignas(8) StringName name;
ObjectID object;
public:
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 e91029f330..8836e257a9 100644
--- a/core/variant/method_ptrcall.h
+++ b/core/variant/method_ptrcall.h
@@ -45,6 +45,7 @@ struct PtrToArg {};
_FORCE_INLINE_ static m_type convert(const void *p_ptr) { \
return *reinterpret_cast<const m_type *>(p_ptr); \
} \
+ typedef m_type EncodeT; \
_FORCE_INLINE_ static void encode(m_type p_val, void *p_ptr) { \
*((m_type *)p_ptr) = p_val; \
} \
@@ -54,6 +55,7 @@ struct PtrToArg {};
_FORCE_INLINE_ static m_type convert(const void *p_ptr) { \
return *reinterpret_cast<const m_type *>(p_ptr); \
} \
+ typedef m_type EncodeT; \
_FORCE_INLINE_ static void encode(m_type p_val, void *p_ptr) { \
*((m_type *)p_ptr) = p_val; \
} \
@@ -65,6 +67,7 @@ struct PtrToArg {};
_FORCE_INLINE_ static m_type convert(const void *p_ptr) { \
return static_cast<m_type>(*reinterpret_cast<const m_conv *>(p_ptr)); \
} \
+ typedef m_conv EncodeT; \
_FORCE_INLINE_ static void encode(m_type p_val, void *p_ptr) { \
*((m_conv *)p_ptr) = static_cast<m_conv>(p_val); \
} \
@@ -74,6 +77,7 @@ struct PtrToArg {};
_FORCE_INLINE_ static m_type convert(const void *p_ptr) { \
return static_cast<m_type>(*reinterpret_cast<const m_conv *>(p_ptr)); \
} \
+ typedef m_conv EncodeT; \
_FORCE_INLINE_ static void encode(m_type p_val, void *p_ptr) { \
*((m_conv *)p_ptr) = static_cast<m_conv>(p_val); \
} \
@@ -85,6 +89,7 @@ struct PtrToArg {};
_FORCE_INLINE_ static m_type convert(const void *p_ptr) { \
return *reinterpret_cast<const m_type *>(p_ptr); \
} \
+ typedef m_type EncodeT; \
_FORCE_INLINE_ static void encode(const m_type &p_val, void *p_ptr) { \
*((m_type *)p_ptr) = p_val; \
} \
@@ -94,12 +99,13 @@ struct PtrToArg {};
_FORCE_INLINE_ static m_type convert(const void *p_ptr) { \
return *reinterpret_cast<const m_type *>(p_ptr); \
} \
+ typedef m_type EncodeT; \
_FORCE_INLINE_ static void encode(const m_type &p_val, void *p_ptr) { \
*((m_type *)p_ptr) = p_val; \
} \
}
-MAKE_PTRARG(bool);
+MAKE_PTRARGCONV(bool, uint8_t);
// Integer types.
MAKE_PTRARGCONV(uint8_t, int64_t);
MAKE_PTRARGCONV(int8_t, int64_t);
@@ -122,10 +128,10 @@ MAKE_PTRARG_BY_REFERENCE(Vector3);
MAKE_PTRARG_BY_REFERENCE(Vector3i);
MAKE_PTRARG(Transform2D);
MAKE_PTRARG_BY_REFERENCE(Plane);
-MAKE_PTRARG(Quat);
+MAKE_PTRARG(Quaternion);
MAKE_PTRARG_BY_REFERENCE(AABB);
MAKE_PTRARG_BY_REFERENCE(Basis);
-MAKE_PTRARG_BY_REFERENCE(Transform);
+MAKE_PTRARG_BY_REFERENCE(Transform3D);
MAKE_PTRARG_BY_REFERENCE(Color);
MAKE_PTRARG(StringName);
MAKE_PTRARG(NodePath);
@@ -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/type_info.h b/core/variant/type_info.h
index d5b6d85dfb..b70d29bbac 100644
--- a/core/variant/type_info.h
+++ b/core/variant/type_info.h
@@ -146,10 +146,10 @@ MAKE_TYPE_INFO(Rect2i, Variant::RECT2I)
MAKE_TYPE_INFO(Vector3i, Variant::VECTOR3I)
MAKE_TYPE_INFO(Transform2D, Variant::TRANSFORM2D)
MAKE_TYPE_INFO(Plane, Variant::PLANE)
-MAKE_TYPE_INFO(Quat, Variant::QUAT)
+MAKE_TYPE_INFO(Quaternion, Variant::QUATERNION)
MAKE_TYPE_INFO(AABB, Variant::AABB)
MAKE_TYPE_INFO(Basis, Variant::BASIS)
-MAKE_TYPE_INFO(Transform, Variant::TRANSFORM)
+MAKE_TYPE_INFO(Transform3D, Variant::TRANSFORM3D)
MAKE_TYPE_INFO(Color, Variant::COLOR)
MAKE_TYPE_INFO(StringName, Variant::STRING_NAME)
MAKE_TYPE_INFO(NodePath, Variant::NODE_PATH)
@@ -241,14 +241,27 @@ struct GetTypeInfo<const T *, typename EnableIf<TypeInherits<Object, T>::value>:
}
};
-#define TEMPL_MAKE_ENUM_TYPE_INFO(m_enum, m_impl) \
- template <> \
- struct GetTypeInfo<m_impl> { \
- static const Variant::Type VARIANT_TYPE = Variant::INT; \
- static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE; \
- static inline PropertyInfo get_class_info() { \
- return PropertyInfo(Variant::INT, String(), PROPERTY_HINT_NONE, String(), PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_CLASS_IS_ENUM, String(#m_enum).replace("::", ".")); \
- } \
+namespace godot {
+namespace details {
+inline String enum_qualified_name_to_class_info_name(const String &p_qualified_name) {
+ Vector<String> parts = p_qualified_name.split("::", false);
+ if (parts.size() <= 2)
+ return String(".").join(parts);
+ // Contains namespace. We only want the class and enum names.
+ return parts[parts.size() - 2] + "." + parts[parts.size() - 1];
+}
+} // namespace details
+} // namespace godot
+
+#define TEMPL_MAKE_ENUM_TYPE_INFO(m_enum, m_impl) \
+ template <> \
+ struct GetTypeInfo<m_impl> { \
+ static const Variant::Type VARIANT_TYPE = Variant::INT; \
+ static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE; \
+ static inline PropertyInfo get_class_info() { \
+ return PropertyInfo(Variant::INT, String(), PROPERTY_HINT_NONE, String(), PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_CLASS_IS_ENUM, \
+ godot::details::enum_qualified_name_to_class_info_name(String(#m_enum))); \
+ } \
};
#define MAKE_ENUM_TYPE_INFO(m_enum) \
diff --git a/core/variant/typed_array.h b/core/variant/typed_array.h
index e0309aa3fe..900dcf7689 100644
--- a/core/variant/typed_array.h
+++ b/core/variant/typed_array.h
@@ -98,10 +98,10 @@ MAKE_TYPED_ARRAY(Vector3, Variant::VECTOR3)
MAKE_TYPED_ARRAY(Vector3i, Variant::VECTOR3I)
MAKE_TYPED_ARRAY(Transform2D, Variant::TRANSFORM2D)
MAKE_TYPED_ARRAY(Plane, Variant::PLANE)
-MAKE_TYPED_ARRAY(Quat, Variant::QUAT)
+MAKE_TYPED_ARRAY(Quaternion, Variant::QUATERNION)
MAKE_TYPED_ARRAY(AABB, Variant::AABB)
MAKE_TYPED_ARRAY(Basis, Variant::BASIS)
-MAKE_TYPED_ARRAY(Transform, Variant::TRANSFORM)
+MAKE_TYPED_ARRAY(Transform3D, Variant::TRANSFORM3D)
MAKE_TYPED_ARRAY(Color, Variant::COLOR)
MAKE_TYPED_ARRAY(StringName, Variant::STRING_NAME)
MAKE_TYPED_ARRAY(NodePath, Variant::NODE_PATH)
@@ -196,10 +196,10 @@ MAKE_TYPED_ARRAY_INFO(Vector3, Variant::VECTOR3)
MAKE_TYPED_ARRAY_INFO(Vector3i, Variant::VECTOR3I)
MAKE_TYPED_ARRAY_INFO(Transform2D, Variant::TRANSFORM2D)
MAKE_TYPED_ARRAY_INFO(Plane, Variant::PLANE)
-MAKE_TYPED_ARRAY_INFO(Quat, Variant::QUAT)
+MAKE_TYPED_ARRAY_INFO(Quaternion, Variant::QUATERNION)
MAKE_TYPED_ARRAY_INFO(AABB, Variant::AABB)
MAKE_TYPED_ARRAY_INFO(Basis, Variant::BASIS)
-MAKE_TYPED_ARRAY_INFO(Transform, Variant::TRANSFORM)
+MAKE_TYPED_ARRAY_INFO(Transform3D, Variant::TRANSFORM3D)
MAKE_TYPED_ARRAY_INFO(Color, Variant::COLOR)
MAKE_TYPED_ARRAY_INFO(StringName, Variant::STRING_NAME)
MAKE_TYPED_ARRAY_INFO(NodePath, Variant::NODE_PATH)
diff --git a/core/variant/variant.cpp b/core/variant/variant.cpp
index 333dd8e8d1..d538b9faff 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"
@@ -91,16 +92,16 @@ String Variant::get_type_name(Variant::Type p_type) {
case AABB: {
return "AABB";
} break;
- case QUAT: {
- return "Quat";
+ case QUATERNION: {
+ return "Quaternion";
} break;
case BASIS: {
return "Basis";
} break;
- case TRANSFORM: {
- return "Transform";
+ case TRANSFORM3D: {
+ return "Transform3D";
} break;
@@ -275,7 +276,7 @@ bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) {
} break;
case TRANSFORM2D: {
static const Type valid[] = {
- TRANSFORM,
+ TRANSFORM3D,
NIL
};
@@ -300,7 +301,7 @@ bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) {
} break;
- case QUAT: {
+ case QUATERNION: {
static const Type valid[] = {
BASIS,
NIL
@@ -311,7 +312,7 @@ bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) {
} break;
case BASIS: {
static const Type valid[] = {
- QUAT,
+ QUATERNION,
VECTOR3,
NIL
};
@@ -319,10 +320,10 @@ bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) {
valid_types = valid;
} break;
- case TRANSFORM: {
+ case TRANSFORM3D: {
static const Type valid[] = {
TRANSFORM2D,
- QUAT,
+ QUATERNION,
BASIS,
NIL
};
@@ -582,7 +583,7 @@ bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type
} break;
case TRANSFORM2D: {
static const Type valid[] = {
- TRANSFORM,
+ TRANSFORM3D,
NIL
};
@@ -607,7 +608,7 @@ bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type
} break;
- case QUAT: {
+ case QUATERNION: {
static const Type valid[] = {
BASIS,
NIL
@@ -618,7 +619,7 @@ bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type
} break;
case BASIS: {
static const Type valid[] = {
- QUAT,
+ QUATERNION,
VECTOR3,
NIL
};
@@ -626,10 +627,10 @@ bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type
valid_types = valid;
} break;
- case TRANSFORM: {
+ case TRANSFORM3D: {
static const Type valid[] = {
TRANSFORM2D,
- QUAT,
+ QUATERNION,
BASIS,
NIL
};
@@ -873,16 +874,16 @@ bool Variant::is_zero() const {
case AABB: {
return *_data._aabb == ::AABB();
} break;
- case QUAT: {
- return *reinterpret_cast<const Quat *>(_data._mem) == Quat();
+ case QUATERNION: {
+ return *reinterpret_cast<const Quaternion *>(_data._mem) == Quaternion();
} break;
case BASIS: {
return *_data._basis == Basis();
} break;
- case TRANSFORM: {
- return *_data._transform == Transform();
+ case TRANSFORM3D: {
+ return *_data._transform3d == Transform3D();
} break;
@@ -1092,16 +1093,16 @@ void Variant::reference(const Variant &p_variant) {
case AABB: {
_data._aabb = memnew(::AABB(*p_variant._data._aabb));
} break;
- case QUAT: {
- memnew_placement(_data._mem, Quat(*reinterpret_cast<const Quat *>(p_variant._data._mem)));
+ case QUATERNION: {
+ memnew_placement(_data._mem, Quaternion(*reinterpret_cast<const Quaternion *>(p_variant._data._mem)));
} break;
case BASIS: {
_data._basis = memnew(Basis(*p_variant._data._basis));
} break;
- case TRANSFORM: {
- _data._transform = memnew(Transform(*p_variant._data._transform));
+ case TRANSFORM3D: {
+ _data._transform3d = memnew(Transform3D(*p_variant._data._transform3d));
} break;
// misc types
@@ -1115,9 +1116,9 @@ void Variant::reference(const Variant &p_variant) {
case OBJECT: {
memnew_placement(_data._mem, ObjData);
- if (p_variant._get_obj().obj && p_variant._get_obj().id.is_reference()) {
- Reference *reference = static_cast<Reference *>(p_variant._get_obj().obj);
- if (!reference->reference()) {
+ if (p_variant._get_obj().obj && p_variant._get_obj().id.is_ref_counted()) {
+ RefCounted *ref_counted = static_cast<RefCounted *>(p_variant._get_obj().obj);
+ if (!ref_counted->reference()) {
_get_obj().obj = nullptr;
_get_obj().id = ObjectID();
break;
@@ -1254,8 +1255,8 @@ void Variant::zero() {
case PLANE:
*reinterpret_cast<Plane *>(this->_data._mem) = Plane();
break;
- case QUAT:
- *reinterpret_cast<Quat *>(this->_data._mem) = Quat();
+ case QUATERNION:
+ *reinterpret_cast<Quaternion *>(this->_data._mem) = Quaternion();
break;
case COLOR:
*reinterpret_cast<Color *>(this->_data._mem) = Color();
@@ -1275,7 +1276,7 @@ void Variant::_clear_internal() {
// no point, they don't allocate memory
VECTOR3,
PLANE,
- QUAT,
+ QUATERNION,
COLOR,
VECTOR2,
RECT2
@@ -1289,8 +1290,8 @@ void Variant::_clear_internal() {
case BASIS: {
memdelete(_data._basis);
} break;
- case TRANSFORM: {
- memdelete(_data._transform);
+ case TRANSFORM3D: {
+ memdelete(_data._transform3d);
} break;
// misc types
@@ -1301,11 +1302,11 @@ void Variant::_clear_internal() {
reinterpret_cast<NodePath *>(_data._mem)->~NodePath();
} break;
case OBJECT: {
- if (_get_obj().id.is_reference()) {
+ if (_get_obj().id.is_ref_counted()) {
//we are safe that there is a reference here
- Reference *reference = static_cast<Reference *>(_get_obj().obj);
- if (reference->unreference()) {
- memdelete(reference);
+ RefCounted *ref_counted = static_cast<RefCounted *>(_get_obj().obj);
+ if (ref_counted->unreference()) {
+ memdelete(ref_counted);
}
}
_get_obj().obj = nullptr;
@@ -1636,60 +1637,35 @@ String Variant::stringify(List<const void *> &stack) const {
case STRING:
return *reinterpret_cast<const String *>(_data._mem);
case VECTOR2:
- return "(" + operator Vector2() + ")";
+ return operator Vector2();
case VECTOR2I:
- return "(" + operator Vector2i() + ")";
+ return operator Vector2i();
case RECT2:
- return "(" + operator Rect2() + ")";
+ return operator Rect2();
case RECT2I:
- return "(" + operator Rect2i() + ")";
- case TRANSFORM2D: {
- Transform2D mat32 = operator Transform2D();
- return "(" + Variant(mat32.elements[0]).operator String() + ", " + Variant(mat32.elements[1]).operator String() + ", " + Variant(mat32.elements[2]).operator String() + ")";
- } break;
+ return operator Rect2i();
+ case TRANSFORM2D:
+ return operator Transform2D();
case VECTOR3:
- return "(" + operator Vector3() + ")";
+ return operator Vector3();
case VECTOR3I:
- return "(" + operator Vector3i() + ")";
+ return operator Vector3i();
case PLANE:
return operator Plane();
- //case QUAT:
case AABB:
return operator ::AABB();
- case QUAT:
- return "(" + operator Quat() + ")";
- case BASIS: {
- Basis mat3 = operator Basis();
-
- String mtx("(");
- for (int i = 0; i < 3; i++) {
- if (i != 0) {
- mtx += ", ";
- }
-
- mtx += "(";
-
- for (int j = 0; j < 3; j++) {
- if (j != 0) {
- mtx += ", ";
- }
-
- mtx += Variant(mat3.elements[i][j]).operator String();
- }
-
- mtx += ")";
- }
-
- return mtx + ")";
- } break;
- case TRANSFORM:
- return operator Transform();
+ case QUATERNION:
+ return operator Quaternion();
+ case BASIS:
+ return operator Basis();
+ case TRANSFORM3D:
+ return operator Transform3D();
case STRING_NAME:
return operator StringName();
case NODE_PATH:
return operator NodePath();
case COLOR:
- return String::num(operator Color().r) + "," + String::num(operator Color().g) + "," + String::num(operator Color().b) + "," + String::num(operator Color().a);
+ return operator Color();
case DICTIONARY: {
const Dictionary &d = *reinterpret_cast<const Dictionary *>(_data._mem);
if (stack.find(d.id())) {
@@ -1705,10 +1681,10 @@ String Variant::stringify(List<const void *> &stack) const {
Vector<_VariantStrPair> pairs;
- for (List<Variant>::Element *E = keys.front(); E; E = E->next()) {
+ for (const Variant &E : keys) {
_VariantStrPair sp;
- sp.key = E->get().stringify(stack);
- sp.value = d[E->get()].stringify(stack);
+ sp.key = E.stringify(stack);
+ sp.value = d[E].stringify(stack);
pairs.push_back(sp);
}
@@ -1723,6 +1699,7 @@ String Variant::stringify(List<const void *> &stack) const {
}
str += "}";
+ stack.erase(d.id());
return str;
} break;
case PACKED_VECTOR2_ARRAY: {
@@ -1826,12 +1803,13 @@ String Variant::stringify(List<const void *> &stack) const {
}
str += "]";
+ stack.erase(arr.id());
return str;
} break;
case OBJECT: {
if (_get_obj().obj) {
- if (!_get_obj().id.is_reference() && ObjectDB::get_instance(_get_obj().id) == nullptr) {
+ if (!_get_obj().id.is_ref_counted() && ObjectDB::get_instance(_get_obj().id) == nullptr) {
return "[Freed Object]";
}
@@ -1861,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);
@@ -1956,39 +1939,39 @@ Variant::operator ::AABB() const {
Variant::operator Basis() const {
if (type == BASIS) {
return *_data._basis;
- } else if (type == QUAT) {
- return *reinterpret_cast<const Quat *>(_data._mem);
+ } else if (type == QUATERNION) {
+ return *reinterpret_cast<const Quaternion *>(_data._mem);
} else if (type == VECTOR3) {
return Basis(*reinterpret_cast<const Vector3 *>(_data._mem));
- } else if (type == TRANSFORM) { // unexposed in Variant::can_convert?
- return _data._transform->basis;
+ } else if (type == TRANSFORM3D) { // unexposed in Variant::can_convert?
+ return _data._transform3d->basis;
} else {
return Basis();
}
}
-Variant::operator Quat() const {
- if (type == QUAT) {
- return *reinterpret_cast<const Quat *>(_data._mem);
+Variant::operator Quaternion() const {
+ if (type == QUATERNION) {
+ return *reinterpret_cast<const Quaternion *>(_data._mem);
} else if (type == BASIS) {
return *_data._basis;
- } else if (type == TRANSFORM) {
- return _data._transform->basis;
+ } else if (type == TRANSFORM3D) {
+ return _data._transform3d->basis;
} else {
- return Quat();
+ return Quaternion();
}
}
-Variant::operator Transform() const {
- if (type == TRANSFORM) {
- return *_data._transform;
+Variant::operator Transform3D() const {
+ if (type == TRANSFORM3D) {
+ return *_data._transform3d;
} else if (type == BASIS) {
- return Transform(*_data._basis, Vector3());
- } else if (type == QUAT) {
- return Transform(Basis(*reinterpret_cast<const Quat *>(_data._mem)), Vector3());
+ return Transform3D(*_data._basis, Vector3());
+ } else if (type == QUATERNION) {
+ return Transform3D(Basis(*reinterpret_cast<const Quaternion *>(_data._mem)), Vector3());
} else if (type == TRANSFORM2D) {
const Transform2D &t = *_data._transform2d;
- Transform m;
+ Transform3D m;
m.basis.elements[0][0] = t.elements[0][0];
m.basis.elements[1][0] = t.elements[0][1];
m.basis.elements[0][1] = t.elements[1][0];
@@ -1997,15 +1980,15 @@ Variant::operator Transform() const {
m.origin[1] = t.elements[2][1];
return m;
} else {
- return Transform();
+ return Transform3D();
}
}
Variant::operator Transform2D() const {
if (type == TRANSFORM2D) {
return *_data._transform2d;
- } else if (type == TRANSFORM) {
- const Transform &t = *_data._transform;
+ } else if (type == TRANSFORM3D) {
+ const Transform3D &t = *_data._transform3d;
Transform2D m;
m.elements[0][0] = t.basis.elements[0][0];
m.elements[0][1] = t.basis.elements[1][0];
@@ -2495,14 +2478,14 @@ Variant::Variant(const Basis &p_matrix) {
_data._basis = memnew(Basis(p_matrix));
}
-Variant::Variant(const Quat &p_quat) {
- type = QUAT;
- memnew_placement(_data._mem, Quat(p_quat));
+Variant::Variant(const Quaternion &p_quaternion) {
+ type = QUATERNION;
+ memnew_placement(_data._mem, Quaternion(p_quaternion));
}
-Variant::Variant(const Transform &p_transform) {
- type = TRANSFORM;
- _data._transform = memnew(Transform(p_transform));
+Variant::Variant(const Transform3D &p_transform) {
+ type = TRANSFORM3D;
+ _data._transform3d = memnew(Transform3D(p_transform));
}
Variant::Variant(const Transform2D &p_transform) {
@@ -2531,9 +2514,9 @@ Variant::Variant(const Object *p_object) {
memnew_placement(_data._mem, ObjData);
if (p_object) {
- if (p_object->is_reference()) {
- Reference *reference = const_cast<Reference *>(static_cast<const Reference *>(p_object));
- if (!reference->init_ref()) {
+ if (p_object->is_ref_counted()) {
+ RefCounted *ref_counted = const_cast<RefCounted *>(static_cast<const RefCounted *>(p_object));
+ if (!ref_counted->init_ref()) {
_get_obj().obj = nullptr;
_get_obj().id = ObjectID();
return;
@@ -2739,14 +2722,14 @@ void Variant::operator=(const Variant &p_variant) {
case AABB: {
*_data._aabb = *(p_variant._data._aabb);
} break;
- case QUAT: {
- *reinterpret_cast<Quat *>(_data._mem) = *reinterpret_cast<const Quat *>(p_variant._data._mem);
+ case QUATERNION: {
+ *reinterpret_cast<Quaternion *>(_data._mem) = *reinterpret_cast<const Quaternion *>(p_variant._data._mem);
} break;
case BASIS: {
*_data._basis = *(p_variant._data._basis);
} break;
- case TRANSFORM: {
- *_data._transform = *(p_variant._data._transform);
+ case TRANSFORM3D: {
+ *_data._transform3d = *(p_variant._data._transform3d);
} break;
// misc types
@@ -2757,17 +2740,17 @@ void Variant::operator=(const Variant &p_variant) {
*reinterpret_cast<::RID *>(_data._mem) = *reinterpret_cast<const ::RID *>(p_variant._data._mem);
} break;
case OBJECT: {
- if (_get_obj().id.is_reference()) {
+ if (_get_obj().id.is_ref_counted()) {
//we are safe that there is a reference here
- Reference *reference = static_cast<Reference *>(_get_obj().obj);
- if (reference->unreference()) {
- memdelete(reference);
+ RefCounted *ref_counted = static_cast<RefCounted *>(_get_obj().obj);
+ if (ref_counted->unreference()) {
+ memdelete(ref_counted);
}
}
- if (p_variant._get_obj().obj && p_variant._get_obj().id.is_reference()) {
- Reference *reference = static_cast<Reference *>(p_variant._get_obj().obj);
- if (!reference->reference()) {
+ if (p_variant._get_obj().obj && p_variant._get_obj().id.is_ref_counted()) {
+ RefCounted *ref_counted = static_cast<RefCounted *>(p_variant._get_obj().obj);
+ if (!ref_counted->reference()) {
_get_obj().obj = nullptr;
_get_obj().id = ObjectID();
break;
@@ -2916,11 +2899,11 @@ uint32_t Variant::hash() const {
return hash;
} break;
- case QUAT: {
- uint32_t hash = hash_djb2_one_float(reinterpret_cast<const Quat *>(_data._mem)->x);
- hash = hash_djb2_one_float(reinterpret_cast<const Quat *>(_data._mem)->y, hash);
- hash = hash_djb2_one_float(reinterpret_cast<const Quat *>(_data._mem)->z, hash);
- return hash_djb2_one_float(reinterpret_cast<const Quat *>(_data._mem)->w, hash);
+ case QUATERNION: {
+ uint32_t hash = hash_djb2_one_float(reinterpret_cast<const Quaternion *>(_data._mem)->x);
+ hash = hash_djb2_one_float(reinterpret_cast<const Quaternion *>(_data._mem)->y, hash);
+ hash = hash_djb2_one_float(reinterpret_cast<const Quaternion *>(_data._mem)->z, hash);
+ return hash_djb2_one_float(reinterpret_cast<const Quaternion *>(_data._mem)->w, hash);
} break;
case BASIS: {
@@ -2934,13 +2917,13 @@ uint32_t Variant::hash() const {
return hash;
} break;
- case TRANSFORM: {
+ case TRANSFORM3D: {
uint32_t hash = 5831;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
- hash = hash_djb2_one_float(_data._transform->basis.elements[i][j], hash);
+ hash = hash_djb2_one_float(_data._transform3d->basis.elements[i][j], hash);
}
- hash = hash_djb2_one_float(_data._transform->origin[i], hash);
+ hash = hash_djb2_one_float(_data._transform3d->origin[i], hash);
}
return hash;
@@ -3127,7 +3110,7 @@ uint32_t Variant::hash() const {
(hash_compare_scalar((p_lhs).y, (p_rhs).y)) && \
(hash_compare_scalar((p_lhs).z, (p_rhs).z))
-#define hash_compare_quat(p_lhs, p_rhs) \
+#define hash_compare_quaternion(p_lhs, p_rhs) \
(hash_compare_scalar((p_lhs).x, (p_rhs).x)) && \
(hash_compare_scalar((p_lhs).y, (p_rhs).y)) && \
(hash_compare_scalar((p_lhs).z, (p_rhs).z)) && \
@@ -3235,11 +3218,11 @@ bool Variant::hash_compare(const Variant &p_variant) const {
} break;
- case QUAT: {
- const Quat *l = reinterpret_cast<const Quat *>(_data._mem);
- const Quat *r = reinterpret_cast<const Quat *>(p_variant._data._mem);
+ case QUATERNION: {
+ const Quaternion *l = reinterpret_cast<const Quaternion *>(_data._mem);
+ const Quaternion *r = reinterpret_cast<const Quaternion *>(p_variant._data._mem);
- return hash_compare_quat(*l, *r);
+ return hash_compare_quaternion(*l, *r);
} break;
case BASIS: {
@@ -3255,9 +3238,9 @@ bool Variant::hash_compare(const Variant &p_variant) const {
return true;
} break;
- case TRANSFORM: {
- const Transform *l = _data._transform;
- const Transform *r = p_variant._data._transform;
+ case TRANSFORM3D: {
+ const Transform3D *l = _data._transform3d;
+ const Transform3D *r = p_variant._data._transform3d;
for (int i = 0; i < 3; i++) {
if (!(hash_compare_vector3(l->basis.elements[i], r->basis.elements[i]))) {
@@ -3324,7 +3307,7 @@ bool Variant::hash_compare(const Variant &p_variant) const {
}
bool Variant::is_ref() const {
- return type == OBJECT && _get_obj().id.is_reference();
+ return type == OBJECT && _get_obj().id.is_ref_counted();
}
Vector<Variant> varray() {
@@ -3550,12 +3533,13 @@ void Variant::register_types() {
_register_variant_methods();
_register_variant_setters_getters();
_register_variant_constructors();
+ _register_variant_destructors();
_register_variant_utility_functions();
}
void Variant::unregister_types() {
_unregister_variant_operators();
_unregister_variant_methods();
_unregister_variant_setters_getters();
- _unregister_variant_constructors();
+ _unregister_variant_destructors();
_unregister_variant_utility_functions();
}
diff --git a/core/variant/variant.h b/core/variant/variant.h
index 7f3c3477fc..9ec131a1b8 100644
--- a/core/variant/variant.h
+++ b/core/variant/variant.h
@@ -37,9 +37,9 @@
#include "core/math/color.h"
#include "core/math/face3.h"
#include "core/math/plane.h"
-#include "core/math/quat.h"
-#include "core/math/transform.h"
+#include "core/math/quaternion.h"
#include "core/math/transform_2d.h"
+#include "core/math/transform_3d.h"
#include "core/math/vector3.h"
#include "core/math/vector3i.h"
#include "core/object/object_id.h"
@@ -88,10 +88,10 @@ public:
VECTOR3I,
TRANSFORM2D,
PLANE,
- QUAT,
+ QUATERNION,
AABB,
BASIS,
- TRANSFORM,
+ TRANSFORM3D,
// misc types
COLOR,
@@ -118,6 +118,11 @@ public:
VARIANT_MAX
};
+ enum {
+ // Maximum recursion depth allowed when serializing variants.
+ MAX_RECURSION_DEPTH = 1024,
+ };
+
private:
friend struct _VariantCall;
friend class VariantInternal;
@@ -200,10 +205,10 @@ private:
Transform2D *_transform2d;
::AABB *_aabb;
Basis *_basis;
- Transform *_transform;
+ Transform3D *_transform3d;
PackedArrayRefBase *packed_array;
void *_ptr; //generic pointer
- uint8_t _mem[sizeof(ObjData) > (sizeof(real_t) * 4) ? sizeof(ObjData) : (sizeof(real_t) * 4)];
+ uint8_t _mem[sizeof(ObjData) > (sizeof(real_t) * 4) ? sizeof(ObjData) : (sizeof(real_t) * 4)]{ 0 };
} _data alignas(8);
void reference(const Variant &p_variant);
@@ -225,7 +230,7 @@ private:
false, //VECTOR3I,
true, //TRANSFORM2D,
false, //PLANE,
- false, //QUAT,
+ false, //QUATERNION,
true, //AABB,
true, //BASIS,
true, //TRANSFORM,
@@ -253,7 +258,7 @@ private:
true, //PACKED_COLOR_ARRAY,
};
- if (unlikely(needs_deinit[type])) { //make it fast for types that dont need deinit
+ if (unlikely(needs_deinit[type])) { // Make it fast for types that don't need deinit.
_clear_internal();
}
type = NIL;
@@ -266,6 +271,8 @@ private:
static void _register_variant_setters_getters();
static void _unregister_variant_setters_getters();
static void _register_variant_constructors();
+ static void _unregister_variant_destructors();
+ static void _register_variant_destructors();
static void _unregister_variant_constructors();
static void _register_variant_utility_functions();
static void _unregister_variant_utility_functions();
@@ -320,10 +327,10 @@ public:
operator Vector3i() const;
operator Plane() const;
operator ::AABB() const;
- operator Quat() const;
+ operator Quaternion() const;
operator Basis() const;
- operator Transform() const;
operator Transform2D() const;
+ operator Transform3D() const;
operator Color() const;
operator NodePath() const;
@@ -392,10 +399,10 @@ public:
Variant(const Vector3i &p_vector3i);
Variant(const Plane &p_plane);
Variant(const ::AABB &p_aabb);
- Variant(const Quat &p_quat);
+ Variant(const Quaternion &p_quat);
Variant(const Basis &p_matrix);
Variant(const Transform2D &p_transform);
- Variant(const Transform &p_transform);
+ Variant(const Transform3D &p_transform);
Variant(const Color &p_color);
Variant(const NodePath &p_node_path);
Variant(const ::RID &p_rid);
@@ -499,9 +506,10 @@ public:
static bool is_builtin_method_vararg(Variant::Type p_type, const StringName &p_method);
static void get_builtin_method_list(Variant::Type p_type, List<StringName> *p_list);
static int get_builtin_method_count(Variant::Type p_type);
+ static uint32_t get_builtin_method_hash(Variant::Type p_type, const StringName &p_method);
void call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error);
- Variant call(const StringName &p_method, const Variant &p_arg1 = Variant(), const Variant &p_arg2 = Variant(), const Variant &p_arg3 = Variant(), const Variant &p_arg4 = Variant(), const Variant &p_arg5 = Variant());
+ Variant call(const StringName &p_method, const Variant &p_arg1 = Variant(), const Variant &p_arg2 = Variant(), const Variant &p_arg3 = Variant(), const Variant &p_arg4 = Variant(), const Variant &p_arg5 = Variant(), const Variant &p_arg6 = Variant(), const Variant &p_arg7 = Variant(), const Variant &p_arg8 = Variant());
static void call_static(Variant::Type p_type, const StringName &p_method, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error);
@@ -528,6 +536,14 @@ public:
static void get_constructor_list(Type p_type, List<MethodInfo> *r_list); //convenience
+ /* Destructors */
+
+ // Only ptrcall is available.
+ typedef void (*PTRDestructor)(void *base);
+
+ static PTRDestructor get_ptr_destructor(Variant::Type p_type);
+ static bool has_destructor(Variant::Type p_type);
+
/* Properties */
void set_named(const StringName &p_member, const Variant &p_value, bool &r_valid);
@@ -586,7 +602,7 @@ public:
typedef void (*PTRKeyedSetter)(void *base, const void *key, const void *value);
typedef void (*PTRKeyedGetter)(const void *base, const void *key, void *value);
- typedef bool (*PTRKeyedChecker)(const void *base, const void *key);
+ typedef uint32_t (*PTRKeyedChecker)(const void *base, const void *key);
static PTRKeyedSetter get_member_ptr_keyed_setter(Variant::Type p_type);
static PTRKeyedGetter get_member_ptr_keyed_getter(Variant::Type p_type);
@@ -631,6 +647,7 @@ public:
static bool has_utility_function_return_value(const StringName &p_name);
static Variant::Type get_utility_function_return_type(const StringName &p_name);
static bool is_utility_function_vararg(const StringName &p_name);
+ static uint32_t get_utility_function_hash(const StringName &p_name);
static void get_utility_function_list(List<StringName> *r_functions);
static int get_utility_function_count();
@@ -645,6 +662,7 @@ public:
bool hash_compare(const Variant &p_variant) const;
bool booleanize() const;
String stringify(List<const void *> &stack) const;
+ String to_json_string() const;
void static_assign(const Variant &p_variant);
static void get_constants_for_type(Variant::Type p_type, List<StringName> *p_constants);
diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp
index efaaa8cd19..c3481d4896 100644
--- a/core/variant/variant_call.cpp
+++ b/core/variant/variant_call.cpp
@@ -611,6 +611,9 @@ struct _VariantCall {
if (buffer_size <= 0) {
ERR_FAIL_V_MSG(decompressed, "Decompression buffer size must be greater than zero.");
}
+ if (p_instance->size() == 0) {
+ ERR_FAIL_V_MSG(decompressed, "Compressed buffer size must be greater than zero.");
+ }
decompressed.resize(buffer_size);
int result = Compression::decompress(decompressed.ptrw(), buffer_size, p_instance->ptr(), p_instance->size(), mode);
@@ -747,6 +750,42 @@ struct _VariantCall {
return 0;
}
+ static PackedInt32Array func_PackedByteArray_decode_s32_array(PackedByteArray *p_instance) {
+ uint64_t size = p_instance->size();
+ const uint8_t *r = p_instance->ptr();
+ PackedInt32Array dest;
+ dest.resize(size / sizeof(int32_t));
+ memcpy(dest.ptrw(), r, size);
+ return dest;
+ }
+
+ static PackedInt64Array func_PackedByteArray_decode_s64_array(PackedByteArray *p_instance) {
+ uint64_t size = p_instance->size();
+ const uint8_t *r = p_instance->ptr();
+ PackedInt64Array dest;
+ dest.resize(size / sizeof(int64_t));
+ memcpy(dest.ptrw(), r, size);
+ return dest;
+ }
+
+ static PackedFloat32Array func_PackedByteArray_decode_float_array(PackedByteArray *p_instance) {
+ uint64_t size = p_instance->size();
+ const uint8_t *r = p_instance->ptr();
+ PackedFloat32Array dest;
+ dest.resize(size / sizeof(float));
+ memcpy(dest.ptrw(), r, size);
+ return dest;
+ }
+
+ static PackedFloat64Array func_PackedByteArray_decode_double_array(PackedByteArray *p_instance) {
+ uint64_t size = p_instance->size();
+ const uint8_t *r = p_instance->ptr();
+ PackedFloat64Array dest;
+ dest.resize(size / sizeof(double));
+ memcpy(dest.ptrw(), r, size);
+ return dest;
+ }
+
static void func_PackedByteArray_encode_u8(PackedByteArray *p_instance, int64_t p_offset, int64_t p_value) {
uint64_t size = p_instance->size();
ERR_FAIL_COND(p_offset < 0 || p_offset > int64_t(size) - 1);
@@ -969,7 +1008,7 @@ void Variant::call(const StringName &p_method, const Variant **p_args, int p_arg
return;
}
#ifdef DEBUG_ENABLED
- if (EngineDebugger::is_active() && !_get_obj().id.is_reference() && ObjectDB::get_instance(_get_obj().id) == nullptr) {
+ if (EngineDebugger::is_active() && !_get_obj().id.is_ref_counted() && ObjectDB::get_instance(_get_obj().id) == nullptr) {
r_error.error = Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL;
return;
}
@@ -1085,8 +1124,8 @@ bool Variant::has_builtin_method_return_value(Variant::Type p_type, const String
void Variant::get_builtin_method_list(Variant::Type p_type, List<StringName> *p_list) {
ERR_FAIL_INDEX(p_type, Variant::VARIANT_MAX);
- for (List<StringName>::Element *E = builtin_method_names[p_type].front(); E; E = E->next()) {
- p_list->push_back(E->get());
+ for (const StringName &E : builtin_method_names[p_type]) {
+ p_list->push_back(E);
}
}
@@ -1123,6 +1162,25 @@ bool Variant::is_builtin_method_vararg(Variant::Type p_type, const StringName &p
return method->is_vararg;
}
+uint32_t Variant::get_builtin_method_hash(Variant::Type p_type, const StringName &p_method) {
+ ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, 0);
+ const VariantBuiltInMethodInfo *method = builtin_method_info[p_type].lookup_ptr(p_method);
+ ERR_FAIL_COND_V(!method, 0);
+ uint32_t hash = hash_djb2_one_32(method->is_const);
+ hash = hash_djb2_one_32(method->is_static, hash);
+ hash = hash_djb2_one_32(method->is_vararg, hash);
+ hash = hash_djb2_one_32(method->has_return_type, hash);
+ if (method->has_return_type) {
+ hash = hash_djb2_one_32(method->return_type, hash);
+ }
+ hash = hash_djb2_one_32(method->argument_count, hash);
+ for (int i = 0; i < method->argument_count; i++) {
+ hash = method->get_argument_type(i);
+ }
+
+ return hash;
+}
+
void Variant::get_method_list(List<MethodInfo> *p_list) const {
if (type == OBJECT) {
Object *obj = get_validated_object();
@@ -1130,12 +1188,12 @@ void Variant::get_method_list(List<MethodInfo> *p_list) const {
obj->get_method_list(p_list);
}
} else {
- for (List<StringName>::Element *E = builtin_method_names[type].front(); E; E = E->next()) {
- const VariantBuiltInMethodInfo *method = builtin_method_info[type].lookup_ptr(E->get());
+ for (const StringName &E : builtin_method_names[type]) {
+ const VariantBuiltInMethodInfo *method = builtin_method_info[type].lookup_ptr(E);
ERR_CONTINUE(!method);
MethodInfo mi;
- mi.name = E->get();
+ mi.name = E;
//return type
if (method->has_return_type) {
@@ -1362,7 +1420,7 @@ static void _register_variant_builtin_methods() {
// FIXME: Static function, not sure how to bind
//bind_method(String, humanize_size, sarray("size"), varray());
- bind_method(String, is_abs_path, sarray(), varray());
+ bind_method(String, is_absolute_path, sarray(), varray());
bind_method(String, is_rel_path, sarray(), varray());
bind_method(String, get_base_dir, sarray(), varray());
bind_method(String, get_file, sarray(), varray());
@@ -1377,7 +1435,7 @@ static void _register_variant_builtin_methods() {
bind_method(String, validate_node_name, sarray(), varray());
bind_method(String, is_valid_identifier, sarray(), varray());
- bind_method(String, is_valid_integer, sarray(), varray());
+ bind_method(String, is_valid_int, sarray(), varray());
bind_method(String, is_valid_float, sarray(), varray());
bind_method(String, is_valid_hex_number, sarray("with_prefix"), varray(false));
bind_method(String, is_valid_html_color, sarray(), varray());
@@ -1416,6 +1474,7 @@ static void _register_variant_builtin_methods() {
bind_method(Vector2, distance_squared_to, sarray("to"), varray());
bind_method(Vector2, length, sarray(), varray());
bind_method(Vector2, length_squared, sarray(), varray());
+ bind_method(Vector2, limit_length, sarray("length"), varray(1.0));
bind_method(Vector2, normalized, sarray(), varray());
bind_method(Vector2, is_normalized, sarray(), varray());
bind_method(Vector2, is_equal_approx, sarray("to"), varray());
@@ -1439,14 +1498,15 @@ static void _register_variant_builtin_methods() {
bind_method(Vector2, cross, sarray("with"), varray());
bind_method(Vector2, abs, sarray(), varray());
bind_method(Vector2, sign, sarray(), varray());
+ bind_method(Vector2, clamp, sarray("min", "max"), varray());
bind_method(Vector2, snapped, sarray("step"), varray());
- bind_method(Vector2, clamped, sarray("length"), varray());
/* Vector2i */
bind_method(Vector2i, aspect, sarray(), varray());
bind_method(Vector2i, sign, sarray(), varray());
bind_method(Vector2i, abs, sarray(), varray());
+ bind_method(Vector2i, clamp, sarray("min", "max"), varray());
/* Rect2 */
@@ -1490,10 +1550,12 @@ static void _register_variant_builtin_methods() {
bind_method(Vector3, distance_squared_to, sarray("b"), varray());
bind_method(Vector3, length, sarray(), varray());
bind_method(Vector3, length_squared, sarray(), varray());
+ bind_method(Vector3, limit_length, sarray("length"), varray(1.0));
bind_method(Vector3, normalized, sarray(), varray());
bind_method(Vector3, is_normalized, sarray(), varray());
bind_method(Vector3, is_equal_approx, sarray("to"), varray());
bind_method(Vector3, inverse, sarray(), varray());
+ bind_method(Vector3, clamp, sarray("min", "max"), varray());
bind_method(Vector3, snapped, sarray("step"), varray());
bind_method(Vector3, rotated, sarray("by_axis", "phi"), varray());
bind_method(Vector3, lerp, sarray("to", "weight"), varray());
@@ -1522,6 +1584,7 @@ static void _register_variant_builtin_methods() {
bind_method(Vector3i, max_axis, sarray(), varray());
bind_method(Vector3i, sign, sarray(), varray());
bind_method(Vector3i, abs, sarray(), varray());
+ bind_method(Vector3i, clamp, sarray("min", "max"), varray());
/* Plane */
@@ -1536,19 +1599,20 @@ static void _register_variant_builtin_methods() {
bind_methodv(Plane, intersects_ray, &Plane::intersects_ray_bind, sarray("from", "dir"), varray());
bind_methodv(Plane, intersects_segment, &Plane::intersects_segment_bind, sarray("from", "to"), varray());
- /* Quat */
-
- bind_method(Quat, length, sarray(), varray());
- bind_method(Quat, length_squared, sarray(), varray());
- bind_method(Quat, normalized, sarray(), varray());
- bind_method(Quat, is_normalized, sarray(), varray());
- bind_method(Quat, is_equal_approx, sarray("to"), varray());
- bind_method(Quat, inverse, sarray(), varray());
- bind_method(Quat, dot, sarray("with"), varray());
- bind_method(Quat, slerp, sarray("to", "weight"), varray());
- bind_method(Quat, slerpni, sarray("to", "weight"), varray());
- bind_method(Quat, cubic_slerp, sarray("b", "pre_a", "post_b", "weight"), varray());
- bind_method(Quat, get_euler, sarray(), varray());
+ /* Quaternion */
+
+ bind_method(Quaternion, length, sarray(), varray());
+ bind_method(Quaternion, length_squared, sarray(), varray());
+ bind_method(Quaternion, normalized, sarray(), varray());
+ bind_method(Quaternion, is_normalized, sarray(), varray());
+ bind_method(Quaternion, is_equal_approx, sarray("to"), varray());
+ bind_method(Quaternion, inverse, sarray(), varray());
+ bind_method(Quaternion, angle_to, sarray("to"), varray());
+ bind_method(Quaternion, dot, sarray("with"), varray());
+ bind_method(Quaternion, slerp, sarray("to", "weight"), varray());
+ bind_method(Quaternion, slerpni, sarray("to", "weight"), varray());
+ bind_method(Quaternion, cubic_slerp, sarray("b", "pre_a", "post_b", "weight"), varray());
+ bind_method(Quaternion, get_euler, sarray(), varray());
/* Color */
@@ -1559,6 +1623,7 @@ static void _register_variant_builtin_methods() {
bind_method(Color, to_abgr64, sarray(), varray());
bind_method(Color, to_rgba64, sarray(), varray());
+ bind_method(Color, clamp, sarray("min", "max"), varray(Color(0, 0, 0, 0), Color(1, 1, 1, 1)));
bind_method(Color, inverted, sarray(), varray());
bind_method(Color, lerp, sarray("to", "weight"), varray());
bind_method(Color, lightened, sarray("amount"), varray());
@@ -1601,6 +1666,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());
@@ -1642,6 +1708,8 @@ static void _register_variant_builtin_methods() {
bind_method(Transform2D, basis_xform_inv, sarray("v"), varray());
bind_method(Transform2D, interpolate_with, sarray("xform", "weight"), varray());
bind_method(Transform2D, is_equal_approx, sarray("xform"), varray());
+ bind_method(Transform2D, set_rotation, sarray("rotation"), varray());
+ bind_method(Transform2D, looking_at, sarray("target"), varray(Vector2()));
/* Basis */
@@ -1659,7 +1727,8 @@ static void _register_variant_builtin_methods() {
bind_method(Basis, get_orthogonal_index, sarray(), varray());
bind_method(Basis, slerp, sarray("to", "weight"), varray());
bind_method(Basis, is_equal_approx, sarray("b"), varray());
- bind_method(Basis, get_rotation_quat, sarray(), varray());
+ bind_method(Basis, get_rotation_quaternion, sarray(), varray());
+ bind_static_method(Basis, looking_at, sarray("target", "up"), varray(Vector3(0, 1, 0)));
/* AABB */
@@ -1687,17 +1756,17 @@ static void _register_variant_builtin_methods() {
bind_methodv(AABB, intersects_segment, &AABB::intersects_segment_bind, sarray("from", "to"), varray());
bind_methodv(AABB, intersects_ray, &AABB::intersects_ray_bind, sarray("from", "dir"), varray());
- /* Transform */
+ /* Transform3D */
- bind_method(Transform, inverse, sarray(), varray());
- bind_method(Transform, affine_inverse, sarray(), varray());
- bind_method(Transform, orthonormalized, sarray(), varray());
- bind_method(Transform, rotated, sarray("axis", "phi"), varray());
- bind_method(Transform, scaled, sarray("scale"), varray());
- bind_method(Transform, translated, sarray("offset"), varray());
- bind_method(Transform, looking_at, sarray("target", "up"), varray(Vector3(0, 1, 0)));
- bind_method(Transform, interpolate_with, sarray("xform", "weight"), varray());
- bind_method(Transform, is_equal_approx, sarray("xform"), varray());
+ bind_method(Transform3D, inverse, sarray(), varray());
+ bind_method(Transform3D, affine_inverse, sarray(), varray());
+ bind_method(Transform3D, orthonormalized, sarray(), varray());
+ bind_method(Transform3D, rotated, sarray("axis", "phi"), varray());
+ bind_method(Transform3D, scaled, sarray("scale"), varray());
+ bind_method(Transform3D, translated, sarray("offset"), varray());
+ bind_method(Transform3D, looking_at, sarray("target", "up"), varray(Vector3(0, 1, 0)));
+ bind_method(Transform3D, interpolate_with, sarray("xform", "weight"), varray());
+ bind_method(Transform3D, is_equal_approx, sarray("xform"), varray());
/* Dictionary */
@@ -1792,6 +1861,11 @@ static void _register_variant_builtin_methods() {
bind_function(PackedByteArray, decode_var, _VariantCall::func_PackedByteArray_decode_var, sarray("byte_offset", "allow_objects"), varray(false));
bind_function(PackedByteArray, decode_var_size, _VariantCall::func_PackedByteArray_decode_var_size, sarray("byte_offset", "allow_objects"), varray(false));
+ bind_function(PackedByteArray, to_int32_array, _VariantCall::func_PackedByteArray_decode_s32_array, sarray(), varray());
+ bind_function(PackedByteArray, to_int64_array, _VariantCall::func_PackedByteArray_decode_s64_array, sarray(), varray());
+ bind_function(PackedByteArray, to_float32_array, _VariantCall::func_PackedByteArray_decode_float_array, sarray(), varray());
+ bind_function(PackedByteArray, to_float64_array, _VariantCall::func_PackedByteArray_decode_double_array, sarray(), varray());
+
bind_functionnc(PackedByteArray, encode_u8, _VariantCall::func_PackedByteArray_encode_u8, sarray("byte_offset", "value"), varray());
bind_functionnc(PackedByteArray, encode_s8, _VariantCall::func_PackedByteArray_encode_s8, sarray("byte_offset", "value"), varray());
bind_functionnc(PackedByteArray, encode_u16, _VariantCall::func_PackedByteArray_encode_u16, sarray("byte_offset", "value"), varray());
@@ -1970,7 +2044,7 @@ static void _register_variant_builtin_methods() {
_VariantCall::add_variant_constant(Variant::VECTOR3, "ZERO", Vector3(0, 0, 0));
_VariantCall::add_variant_constant(Variant::VECTOR3, "ONE", Vector3(1, 1, 1));
- _VariantCall::add_variant_constant(Variant::VECTOR3, "INF", Vector3(Math_INF, Math_INF, Math_INF));
+ _VariantCall::add_variant_constant(Variant::VECTOR3, "INF", Vector3(INFINITY, INFINITY, INFINITY));
_VariantCall::add_variant_constant(Variant::VECTOR3, "LEFT", Vector3(-1, 0, 0));
_VariantCall::add_variant_constant(Variant::VECTOR3, "RIGHT", Vector3(1, 0, 0));
_VariantCall::add_variant_constant(Variant::VECTOR3, "UP", Vector3(0, 1, 0));
@@ -1999,7 +2073,7 @@ static void _register_variant_builtin_methods() {
_VariantCall::add_variant_constant(Variant::VECTOR2, "ZERO", Vector2(0, 0));
_VariantCall::add_variant_constant(Variant::VECTOR2, "ONE", Vector2(1, 1));
- _VariantCall::add_variant_constant(Variant::VECTOR2, "INF", Vector2(Math_INF, Math_INF));
+ _VariantCall::add_variant_constant(Variant::VECTOR2, "INF", Vector2(INFINITY, INFINITY));
_VariantCall::add_variant_constant(Variant::VECTOR2, "LEFT", Vector2(-1, 0));
_VariantCall::add_variant_constant(Variant::VECTOR2, "RIGHT", Vector2(1, 0));
_VariantCall::add_variant_constant(Variant::VECTOR2, "UP", Vector2(0, -1));
@@ -2016,14 +2090,14 @@ static void _register_variant_builtin_methods() {
_VariantCall::add_variant_constant(Variant::TRANSFORM2D, "FLIP_X", Transform2D(-1, 0, 0, 1, 0, 0));
_VariantCall::add_variant_constant(Variant::TRANSFORM2D, "FLIP_Y", Transform2D(1, 0, 0, -1, 0, 0));
- Transform identity_transform = Transform();
- Transform flip_x_transform = Transform(-1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0);
- Transform flip_y_transform = Transform(1, 0, 0, 0, -1, 0, 0, 0, 1, 0, 0, 0);
- Transform flip_z_transform = Transform(1, 0, 0, 0, 1, 0, 0, 0, -1, 0, 0, 0);
- _VariantCall::add_variant_constant(Variant::TRANSFORM, "IDENTITY", identity_transform);
- _VariantCall::add_variant_constant(Variant::TRANSFORM, "FLIP_X", flip_x_transform);
- _VariantCall::add_variant_constant(Variant::TRANSFORM, "FLIP_Y", flip_y_transform);
- _VariantCall::add_variant_constant(Variant::TRANSFORM, "FLIP_Z", flip_z_transform);
+ Transform3D identity_transform = Transform3D();
+ Transform3D flip_x_transform = Transform3D(-1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0);
+ Transform3D flip_y_transform = Transform3D(1, 0, 0, 0, -1, 0, 0, 0, 1, 0, 0, 0);
+ Transform3D flip_z_transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, -1, 0, 0, 0);
+ _VariantCall::add_variant_constant(Variant::TRANSFORM3D, "IDENTITY", identity_transform);
+ _VariantCall::add_variant_constant(Variant::TRANSFORM3D, "FLIP_X", flip_x_transform);
+ _VariantCall::add_variant_constant(Variant::TRANSFORM3D, "FLIP_Y", flip_y_transform);
+ _VariantCall::add_variant_constant(Variant::TRANSFORM3D, "FLIP_Z", flip_z_transform);
Basis identity_basis = Basis();
Basis flip_x_basis = Basis(-1, 0, 0, 0, 1, 0, 0, 0, 1);
@@ -2038,7 +2112,7 @@ static void _register_variant_builtin_methods() {
_VariantCall::add_variant_constant(Variant::PLANE, "PLANE_XZ", Plane(Vector3(0, 1, 0), 0));
_VariantCall::add_variant_constant(Variant::PLANE, "PLANE_XY", Plane(Vector3(0, 0, 1), 0));
- _VariantCall::add_variant_constant(Variant::QUAT, "IDENTITY", Quat(0, 0, 0, 1));
+ _VariantCall::add_variant_constant(Variant::QUATERNION, "IDENTITY", Quaternion(0, 0, 0, 1));
}
void Variant::_register_variant_methods() {
diff --git a/core/variant/variant_construct.cpp b/core/variant/variant_construct.cpp
index f0c9e52b46..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(Quat);
-MAKE_PTRCONSTRUCT(AABB);
-MAKE_PTRCONSTRUCT(Basis);
-MAKE_PTRCONSTRUCT(Transform);
-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);
@@ -659,13 +123,13 @@ void Variant::_register_variant_constructors() {
add_constructor<VariantConstructor<Plane, Vector3, Vector3, Vector3>>(sarray("point1", "point2", "point3"));
add_constructor<VariantConstructor<Plane, double, double, double, double>>(sarray("a", "b", "c", "d"));
- add_constructor<VariantConstructNoArgs<Quat>>(sarray());
- add_constructor<VariantConstructor<Quat, Quat>>(sarray("from"));
- add_constructor<VariantConstructor<Quat, Basis>>(sarray("from"));
- add_constructor<VariantConstructor<Quat, Vector3>>(sarray("euler"));
- add_constructor<VariantConstructor<Quat, Vector3, double>>(sarray("axis", "angle"));
- add_constructor<VariantConstructor<Quat, Vector3, Vector3>>(sarray("arc_from", "arc_to"));
- add_constructor<VariantConstructor<Quat, double, double, double, double>>(sarray("x", "y", "z", "w"));
+ add_constructor<VariantConstructNoArgs<Quaternion>>(sarray());
+ add_constructor<VariantConstructor<Quaternion, Quaternion>>(sarray("from"));
+ add_constructor<VariantConstructor<Quaternion, Basis>>(sarray("from"));
+ add_constructor<VariantConstructor<Quaternion, Vector3>>(sarray("euler"));
+ add_constructor<VariantConstructor<Quaternion, Vector3, double>>(sarray("axis", "angle"));
+ add_constructor<VariantConstructor<Quaternion, Vector3, Vector3>>(sarray("arc_from", "arc_to"));
+ add_constructor<VariantConstructor<Quaternion, double, double, double, double>>(sarray("x", "y", "z", "w"));
add_constructor<VariantConstructNoArgs<::AABB>>(sarray());
add_constructor<VariantConstructor<::AABB, ::AABB>>(sarray("from"));
@@ -673,15 +137,15 @@ void Variant::_register_variant_constructors() {
add_constructor<VariantConstructNoArgs<Basis>>(sarray());
add_constructor<VariantConstructor<Basis, Basis>>(sarray("from"));
- add_constructor<VariantConstructor<Basis, Quat>>(sarray("from"));
+ add_constructor<VariantConstructor<Basis, Quaternion>>(sarray("from"));
add_constructor<VariantConstructor<Basis, Vector3>>(sarray("euler"));
add_constructor<VariantConstructor<Basis, Vector3, double>>(sarray("axis", "phi"));
add_constructor<VariantConstructor<Basis, Vector3, Vector3, Vector3>>(sarray("x_axis", "y_axis", "z_axis"));
- add_constructor<VariantConstructNoArgs<Transform>>(sarray());
- add_constructor<VariantConstructor<Transform, Transform>>(sarray("from"));
- add_constructor<VariantConstructor<Transform, Basis, Vector3>>(sarray("basis", "origin"));
- add_constructor<VariantConstructor<Transform, Vector3, Vector3, Vector3, Vector3>>(sarray("x_axis", "y_axis", "z_axis", "origin"));
+ add_constructor<VariantConstructNoArgs<Transform3D>>(sarray());
+ add_constructor<VariantConstructor<Transform3D, Transform3D>>(sarray("from"));
+ add_constructor<VariantConstructor<Transform3D, Basis, Vector3>>(sarray("basis", "origin"));
+ add_constructor<VariantConstructor<Transform3D, Vector3, Vector3, Vector3, Vector3>>(sarray("x_axis", "y_axis", "z_axis", "origin"));
add_constructor<VariantConstructNoArgs<Color>>(sarray());
add_constructor<VariantConstructor<Color, Color>>(sarray("from"));
@@ -836,9 +300,9 @@ String Variant::get_constructor_argument_name(Variant::Type p_type, int p_constr
void VariantInternal::object_assign(Variant *v, const Object *o) {
if (o) {
- if (o->is_reference()) {
- Reference *reference = const_cast<Reference *>(static_cast<const Reference *>(o));
- if (!reference->init_ref()) {
+ if (o->is_ref_counted()) {
+ RefCounted *ref_counted = const_cast<RefCounted *>(static_cast<const RefCounted *>(o));
+ if (!ref_counted->init_ref()) {
v->_get_obj().obj = nullptr;
v->_get_obj().id = ObjectID();
return;
diff --git a/core/variant/variant_construct.h b/core/variant/variant_construct.h
new file mode 100644
index 0000000000..b03f4a8d3b
--- /dev/null
+++ b/core/variant/variant_construct.h
@@ -0,0 +1,572 @@
+/*************************************************************************/
+/* variant_construct.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef VARIANT_CONSTRUCT_H
+#define VARIANT_CONSTRUCT_H
+
+#include "variant.h"
+
+#include "core/core_string_names.h"
+#include "core/crypto/crypto_core.h"
+#include "core/debugger/engine_debugger.h"
+#include "core/io/compression.h"
+#include "core/object/class_db.h"
+#include "core/os/os.h"
+#include "core/templates/local_vector.h"
+#include "core/templates/oa_hash_map.h"
+
+template <class T>
+struct PtrConstruct {};
+
+#define MAKE_PTRCONSTRUCT(m_type) \
+ template <> \
+ struct PtrConstruct<m_type> { \
+ _FORCE_INLINE_ static void construct(const m_type &p_value, void *p_ptr) { \
+ memnew_placement(p_ptr, m_type(p_value)); \
+ } \
+ };
+
+MAKE_PTRCONSTRUCT(bool);
+MAKE_PTRCONSTRUCT(int64_t);
+MAKE_PTRCONSTRUCT(double);
+MAKE_PTRCONSTRUCT(String);
+MAKE_PTRCONSTRUCT(Vector2);
+MAKE_PTRCONSTRUCT(Vector2i);
+MAKE_PTRCONSTRUCT(Rect2);
+MAKE_PTRCONSTRUCT(Rect2i);
+MAKE_PTRCONSTRUCT(Vector3);
+MAKE_PTRCONSTRUCT(Vector3i);
+MAKE_PTRCONSTRUCT(Transform2D);
+MAKE_PTRCONSTRUCT(Plane);
+MAKE_PTRCONSTRUCT(Quaternion);
+MAKE_PTRCONSTRUCT(AABB);
+MAKE_PTRCONSTRUCT(Basis);
+MAKE_PTRCONSTRUCT(Transform3D);
+MAKE_PTRCONSTRUCT(Color);
+MAKE_PTRCONSTRUCT(StringName);
+MAKE_PTRCONSTRUCT(NodePath);
+MAKE_PTRCONSTRUCT(RID);
+
+template <>
+struct PtrConstruct<Object *> {
+ _FORCE_INLINE_ static void construct(Object *p_value, void *p_ptr) {
+ *((Object **)p_ptr) = p_value;
+ }
+};
+
+MAKE_PTRCONSTRUCT(Callable);
+MAKE_PTRCONSTRUCT(Signal);
+MAKE_PTRCONSTRUCT(Dictionary);
+MAKE_PTRCONSTRUCT(Array);
+MAKE_PTRCONSTRUCT(PackedByteArray);
+MAKE_PTRCONSTRUCT(PackedInt32Array);
+MAKE_PTRCONSTRUCT(PackedInt64Array);
+MAKE_PTRCONSTRUCT(PackedFloat32Array);
+MAKE_PTRCONSTRUCT(PackedFloat64Array);
+MAKE_PTRCONSTRUCT(PackedStringArray);
+MAKE_PTRCONSTRUCT(PackedVector2Array);
+MAKE_PTRCONSTRUCT(PackedVector3Array);
+MAKE_PTRCONSTRUCT(PackedColorArray);
+MAKE_PTRCONSTRUCT(Variant);
+
+template <class T, class... P>
+class VariantConstructor {
+ template <size_t... Is>
+ static _FORCE_INLINE_ void construct_helper(T &base, const Variant **p_args, Callable::CallError &r_error, IndexSequence<Is...>) {
+ r_error.error = Callable::CallError::CALL_OK;
+
+#ifdef DEBUG_METHODS_ENABLED
+ base = T(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...);
+#else
+ base = T(VariantCaster<P>::cast(*p_args[Is])...);
+#endif
+ }
+
+ template <size_t... Is>
+ static _FORCE_INLINE_ void validated_construct_helper(T &base, const Variant **p_args, IndexSequence<Is...>) {
+ base = T((*VariantGetInternalPtr<P>::get_ptr(p_args[Is]))...);
+ }
+
+ template <size_t... Is>
+ static _FORCE_INLINE_ void ptr_construct_helper(void *base, const void **p_args, IndexSequence<Is...>) {
+ PtrConstruct<T>::construct(T(PtrToArg<P>::convert(p_args[Is])...), base);
+ }
+
+public:
+ static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) {
+ r_error.error = Callable::CallError::CALL_OK;
+ VariantTypeChanger<T>::change(&r_ret);
+ construct_helper(*VariantGetInternalPtr<T>::get_ptr(&r_ret), p_args, r_error, BuildIndexSequence<sizeof...(P)>{});
+ }
+
+ static inline void validated_construct(Variant *r_ret, const Variant **p_args) {
+ VariantTypeChanger<T>::change(r_ret);
+ validated_construct_helper(*VariantGetInternalPtr<T>::get_ptr(r_ret), p_args, BuildIndexSequence<sizeof...(P)>{});
+ }
+ static void ptr_construct(void *base, const void **p_args) {
+ ptr_construct_helper(base, p_args, BuildIndexSequence<sizeof...(P)>{});
+ }
+
+ static int get_argument_count() {
+ return sizeof...(P);
+ }
+
+ static Variant::Type get_argument_type(int p_arg) {
+ return call_get_argument_type<P...>(p_arg);
+ }
+
+ static Variant::Type get_base_type() {
+ return GetTypeInfo<T>::VARIANT_TYPE;
+ }
+};
+
+class VariantConstructorObject {
+public:
+ static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) {
+ VariantInternal::clear(&r_ret);
+ if (p_args[0]->get_type() == Variant::NIL) {
+ VariantInternal::object_assign_null(&r_ret);
+ r_error.error = Callable::CallError::CALL_OK;
+ } else if (p_args[0]->get_type() == Variant::OBJECT) {
+ VariantInternal::object_assign(&r_ret, p_args[0]);
+ r_error.error = Callable::CallError::CALL_OK;
+ } else {
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.argument = 0;
+ r_error.expected = Variant::OBJECT;
+ }
+ }
+
+ static inline void validated_construct(Variant *r_ret, const Variant **p_args) {
+ VariantInternal::clear(r_ret);
+ VariantInternal::object_assign(r_ret, p_args[0]);
+ }
+ static void ptr_construct(void *base, const void **p_args) {
+ PtrConstruct<Object *>::construct(PtrToArg<Object *>::convert(p_args[0]), base);
+ }
+
+ static int get_argument_count() {
+ return 1;
+ }
+
+ static Variant::Type get_argument_type(int p_arg) {
+ return Variant::OBJECT;
+ }
+
+ static Variant::Type get_base_type() {
+ return Variant::OBJECT;
+ }
+};
+
+class VariantConstructorNilObject {
+public:
+ static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) {
+ if (p_args[0]->get_type() != Variant::NIL) {
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.argument = 0;
+ r_error.expected = Variant::NIL;
+ }
+
+ VariantInternal::clear(&r_ret);
+ VariantInternal::object_assign_null(&r_ret);
+ }
+
+ static inline void validated_construct(Variant *r_ret, const Variant **p_args) {
+ VariantInternal::clear(r_ret);
+ VariantInternal::object_assign_null(r_ret);
+ }
+ static void ptr_construct(void *base, const void **p_args) {
+ PtrConstruct<Object *>::construct(nullptr, base);
+ }
+
+ static int get_argument_count() {
+ return 1;
+ }
+
+ static Variant::Type get_argument_type(int p_arg) {
+ return Variant::NIL;
+ }
+
+ static Variant::Type get_base_type() {
+ return Variant::OBJECT;
+ }
+};
+
+class VariantConstructorCallableArgs {
+public:
+ static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) {
+ ObjectID object_id;
+ StringName method;
+
+ if (p_args[0]->get_type() == Variant::NIL) {
+ // leave as is
+ } else if (p_args[0]->get_type() == Variant::OBJECT) {
+ object_id = VariantInternal::get_object_id(p_args[0]);
+ } else {
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.argument = 0;
+ r_error.expected = Variant::OBJECT;
+ return;
+ }
+
+ if (p_args[1]->get_type() == Variant::STRING_NAME) {
+ method = *VariantGetInternalPtr<StringName>::get_ptr(p_args[1]);
+ } else if (p_args[1]->get_type() == Variant::STRING) {
+ method = *VariantGetInternalPtr<String>::get_ptr(p_args[1]);
+ } else {
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.argument = 1;
+ r_error.expected = Variant::STRING_NAME;
+ return;
+ }
+
+ VariantTypeChanger<Callable>::change(&r_ret);
+ *VariantGetInternalPtr<Callable>::get_ptr(&r_ret) = Callable(object_id, method);
+ }
+
+ static inline void validated_construct(Variant *r_ret, const Variant **p_args) {
+ VariantTypeChanger<Callable>::change(r_ret);
+ *VariantGetInternalPtr<Callable>::get_ptr(r_ret) = Callable(VariantInternal::get_object_id(p_args[0]), *VariantGetInternalPtr<StringName>::get_ptr(p_args[1]));
+ }
+ static void ptr_construct(void *base, const void **p_args) {
+ PtrConstruct<Callable>::construct(Callable(PtrToArg<Object *>::convert(p_args[0]), PtrToArg<StringName>::convert(p_args[1])), base);
+ }
+
+ static int get_argument_count() {
+ return 2;
+ }
+
+ static Variant::Type get_argument_type(int p_arg) {
+ if (p_arg == 0) {
+ return Variant::OBJECT;
+ } else {
+ return Variant::STRING_NAME;
+ }
+ }
+
+ static Variant::Type get_base_type() {
+ return Variant::CALLABLE;
+ }
+};
+
+class VariantConstructorSignalArgs {
+public:
+ static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) {
+ ObjectID object_id;
+ StringName method;
+
+ if (p_args[0]->get_type() == Variant::NIL) {
+ // leave as is
+ } else if (p_args[0]->get_type() == Variant::OBJECT) {
+ object_id = VariantInternal::get_object_id(p_args[0]);
+ } else {
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.argument = 0;
+ r_error.expected = Variant::OBJECT;
+ return;
+ }
+
+ if (p_args[1]->get_type() == Variant::STRING_NAME) {
+ method = *VariantGetInternalPtr<StringName>::get_ptr(p_args[1]);
+ } else if (p_args[1]->get_type() == Variant::STRING) {
+ method = *VariantGetInternalPtr<String>::get_ptr(p_args[1]);
+ } else {
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.argument = 1;
+ r_error.expected = Variant::STRING_NAME;
+ return;
+ }
+
+ VariantTypeChanger<Signal>::change(&r_ret);
+ *VariantGetInternalPtr<Signal>::get_ptr(&r_ret) = Signal(object_id, method);
+ }
+
+ static inline void validated_construct(Variant *r_ret, const Variant **p_args) {
+ VariantTypeChanger<Signal>::change(r_ret);
+ *VariantGetInternalPtr<Signal>::get_ptr(r_ret) = Signal(VariantInternal::get_object_id(p_args[0]), *VariantGetInternalPtr<StringName>::get_ptr(p_args[1]));
+ }
+ static void ptr_construct(void *base, const void **p_args) {
+ PtrConstruct<Signal>::construct(Signal(PtrToArg<Object *>::convert(p_args[0]), PtrToArg<StringName>::convert(p_args[1])), base);
+ }
+
+ static int get_argument_count() {
+ return 2;
+ }
+
+ static Variant::Type get_argument_type(int p_arg) {
+ if (p_arg == 0) {
+ return Variant::OBJECT;
+ } else {
+ return Variant::STRING_NAME;
+ }
+ }
+
+ static Variant::Type get_base_type() {
+ return Variant::SIGNAL;
+ }
+};
+
+template <class T>
+class VariantConstructorToArray {
+public:
+ static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) {
+ if (p_args[0]->get_type() != GetTypeInfo<T>::VARIANT_TYPE) {
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.argument = 0;
+ r_error.expected = GetTypeInfo<T>::VARIANT_TYPE;
+ return;
+ }
+
+ VariantTypeChanger<Array>::change(&r_ret);
+ Array &dst_arr = *VariantGetInternalPtr<Array>::get_ptr(&r_ret);
+ const T &src_arr = *VariantGetInternalPtr<T>::get_ptr(p_args[0]);
+
+ int size = src_arr.size();
+ dst_arr.resize(size);
+ for (int i = 0; i < size; i++) {
+ dst_arr[i] = src_arr[i];
+ }
+ }
+
+ static inline void validated_construct(Variant *r_ret, const Variant **p_args) {
+ VariantTypeChanger<Array>::change(r_ret);
+ Array &dst_arr = *VariantGetInternalPtr<Array>::get_ptr(r_ret);
+ const T &src_arr = *VariantGetInternalPtr<T>::get_ptr(p_args[0]);
+
+ int size = src_arr.size();
+ dst_arr.resize(size);
+ for (int i = 0; i < size; i++) {
+ dst_arr[i] = src_arr[i];
+ }
+ }
+ static void ptr_construct(void *base, const void **p_args) {
+ Array dst_arr;
+ T src_arr = PtrToArg<T>::convert(p_args[0]);
+
+ int size = src_arr.size();
+ dst_arr.resize(size);
+ for (int i = 0; i < size; i++) {
+ dst_arr[i] = src_arr[i];
+ }
+
+ PtrConstruct<Array>::construct(dst_arr, base);
+ }
+
+ static int get_argument_count() {
+ return 1;
+ }
+
+ static Variant::Type get_argument_type(int p_arg) {
+ return GetTypeInfo<T>::VARIANT_TYPE;
+ }
+
+ static Variant::Type get_base_type() {
+ return Variant::ARRAY;
+ }
+};
+
+template <class T>
+class VariantConstructorFromArray {
+public:
+ static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) {
+ if (p_args[0]->get_type() != Variant::ARRAY) {
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.argument = 0;
+ r_error.expected = Variant::ARRAY;
+ return;
+ }
+
+ VariantTypeChanger<T>::change(&r_ret);
+ const Array &src_arr = *VariantGetInternalPtr<Array>::get_ptr(p_args[0]);
+ T &dst_arr = *VariantGetInternalPtr<T>::get_ptr(&r_ret);
+
+ int size = src_arr.size();
+ dst_arr.resize(size);
+ for (int i = 0; i < size; i++) {
+ dst_arr.write[i] = src_arr[i];
+ }
+ }
+
+ static inline void validated_construct(Variant *r_ret, const Variant **p_args) {
+ VariantTypeChanger<T>::change(r_ret);
+ const Array &src_arr = *VariantGetInternalPtr<Array>::get_ptr(p_args[0]);
+ T &dst_arr = *VariantGetInternalPtr<T>::get_ptr(r_ret);
+
+ int size = src_arr.size();
+ dst_arr.resize(size);
+ for (int i = 0; i < size; i++) {
+ dst_arr.write[i] = src_arr[i];
+ }
+ }
+ static void ptr_construct(void *base, const void **p_args) {
+ Array src_arr = PtrToArg<Array>::convert(p_args[0]);
+ T dst_arr;
+
+ int size = src_arr.size();
+ dst_arr.resize(size);
+ for (int i = 0; i < size; i++) {
+ dst_arr.write[i] = src_arr[i];
+ }
+
+ PtrConstruct<T>::construct(dst_arr, base);
+ }
+
+ static int get_argument_count() {
+ return 1;
+ }
+
+ static Variant::Type get_argument_type(int p_arg) {
+ return Variant::ARRAY;
+ }
+
+ static Variant::Type get_base_type() {
+ return GetTypeInfo<T>::VARIANT_TYPE;
+ }
+};
+
+class VariantConstructorNil {
+public:
+ static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) {
+ if (p_args[0]->get_type() != Variant::NIL) {
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.argument = 0;
+ r_error.expected = Variant::NIL;
+ return;
+ }
+
+ r_error.error = Callable::CallError::CALL_OK;
+ VariantInternal::clear(&r_ret);
+ }
+
+ static inline void validated_construct(Variant *r_ret, const Variant **p_args) {
+ VariantInternal::clear(r_ret);
+ }
+ static void ptr_construct(void *base, const void **p_args) {
+ PtrConstruct<Variant>::construct(Variant(), base);
+ }
+
+ static int get_argument_count() {
+ return 1;
+ }
+
+ static Variant::Type get_argument_type(int p_arg) {
+ return Variant::NIL;
+ }
+
+ static Variant::Type get_base_type() {
+ return Variant::NIL;
+ }
+};
+
+template <class T>
+class VariantConstructNoArgs {
+public:
+ static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) {
+ VariantTypeChanger<T>::change_and_reset(&r_ret);
+ r_error.error = Callable::CallError::CALL_OK;
+ }
+
+ static inline void validated_construct(Variant *r_ret, const Variant **p_args) {
+ VariantTypeChanger<T>::change_and_reset(r_ret);
+ }
+ static void ptr_construct(void *base, const void **p_args) {
+ PtrConstruct<T>::construct(T(), base);
+ }
+
+ static int get_argument_count() {
+ return 0;
+ }
+
+ static Variant::Type get_argument_type(int p_arg) {
+ return Variant::NIL;
+ }
+
+ static Variant::Type get_base_type() {
+ return GetTypeInfo<T>::VARIANT_TYPE;
+ }
+};
+
+class VariantConstructNoArgsNil {
+public:
+ static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) {
+ VariantInternal::clear(&r_ret);
+ r_error.error = Callable::CallError::CALL_OK;
+ }
+
+ static inline void validated_construct(Variant *r_ret, const Variant **p_args) {
+ VariantInternal::clear(r_ret);
+ }
+ static void ptr_construct(void *base, const void **p_args) {
+ ERR_FAIL_MSG("can't ptrcall nil constructor");
+ }
+
+ static int get_argument_count() {
+ return 0;
+ }
+
+ static Variant::Type get_argument_type(int p_arg) {
+ return Variant::NIL;
+ }
+
+ static Variant::Type get_base_type() {
+ return Variant::NIL;
+ }
+};
+
+class VariantConstructNoArgsObject {
+public:
+ static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) {
+ VariantInternal::clear(&r_ret);
+ VariantInternal::object_assign_null(&r_ret);
+ r_error.error = Callable::CallError::CALL_OK;
+ }
+
+ static inline void validated_construct(Variant *r_ret, const Variant **p_args) {
+ VariantInternal::clear(r_ret);
+ VariantInternal::object_assign_null(r_ret);
+ }
+ static void ptr_construct(void *base, const void **p_args) {
+ PtrConstruct<Object *>::construct(nullptr, base);
+ }
+
+ static int get_argument_count() {
+ return 0;
+ }
+
+ static Variant::Type get_argument_type(int p_arg) {
+ return Variant::NIL;
+ }
+
+ static Variant::Type get_base_type() {
+ return Variant::OBJECT;
+ }
+};
+
+#endif // VARIANT_CONSTRUCT_H
diff --git a/core/variant/variant_destruct.cpp b/core/variant/variant_destruct.cpp
new file mode 100644
index 0000000000..366b71df3a
--- /dev/null
+++ b/core/variant/variant_destruct.cpp
@@ -0,0 +1,78 @@
+/*************************************************************************/
+/* variant_destruct.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "variant_destruct.h"
+
+#include "core/templates/local_vector.h"
+
+static Variant::PTRDestructor destruct_pointers[Variant::VARIANT_MAX] = { nullptr };
+
+template <class T>
+static void add_destructor() {
+ destruct_pointers[T::get_base_type()] = T::ptr_destruct;
+}
+
+void Variant::_register_variant_destructors() {
+ add_destructor<VariantDestruct<String>>();
+ add_destructor<VariantDestruct<Transform2D>>();
+ add_destructor<VariantDestruct<::AABB>>();
+ add_destructor<VariantDestruct<Basis>>();
+ add_destructor<VariantDestruct<Transform3D>>();
+ add_destructor<VariantDestruct<StringName>>();
+ add_destructor<VariantDestruct<NodePath>>();
+ add_destructor<VariantDestruct<::RID>>();
+ add_destructor<VariantDestruct<Callable>>();
+ add_destructor<VariantDestruct<Signal>>();
+ add_destructor<VariantDestruct<Dictionary>>();
+ add_destructor<VariantDestruct<Array>>();
+ add_destructor<VariantDestruct<PackedByteArray>>();
+ add_destructor<VariantDestruct<PackedInt32Array>>();
+ add_destructor<VariantDestruct<PackedInt64Array>>();
+ add_destructor<VariantDestruct<PackedFloat32Array>>();
+ add_destructor<VariantDestruct<PackedFloat64Array>>();
+ add_destructor<VariantDestruct<PackedStringArray>>();
+ add_destructor<VariantDestruct<PackedVector2Array>>();
+ add_destructor<VariantDestruct<PackedVector3Array>>();
+ add_destructor<VariantDestruct<PackedColorArray>>();
+}
+
+void Variant::_unregister_variant_destructors() {
+ // Nothing to be done.
+}
+
+Variant::PTRDestructor Variant::get_ptr_destructor(Variant::Type p_type) {
+ ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, nullptr);
+ return destruct_pointers[p_type];
+}
+
+bool Variant::has_destructor(Variant::Type p_type) {
+ ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, false);
+ return destruct_pointers[p_type] != nullptr;
+}
diff --git a/core/variant/variant_destruct.h b/core/variant/variant_destruct.h
new file mode 100644
index 0000000000..7356e42201
--- /dev/null
+++ b/core/variant/variant_destruct.h
@@ -0,0 +1,76 @@
+/*************************************************************************/
+/* variant_destruct.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef VARIANT_DESTRUCT_H
+#define VARIANT_DESTRUCT_H
+
+#include "core/variant/variant.h"
+
+#include "core/object/class_db.h"
+
+template <class T>
+struct VariantDestruct {};
+
+#define MAKE_PTRDESTRUCT(m_type) \
+ template <> \
+ struct VariantDestruct<m_type> { \
+ _FORCE_INLINE_ static void ptr_destruct(void *p_ptr) { \
+ reinterpret_cast<m_type *>(p_ptr)->~m_type(); \
+ } \
+ _FORCE_INLINE_ static Variant::Type get_base_type() { \
+ return GetTypeInfo<m_type>::VARIANT_TYPE; \
+ } \
+ }
+
+MAKE_PTRDESTRUCT(String);
+MAKE_PTRDESTRUCT(Transform2D);
+MAKE_PTRDESTRUCT(AABB);
+MAKE_PTRDESTRUCT(Basis);
+MAKE_PTRDESTRUCT(Transform3D);
+MAKE_PTRDESTRUCT(StringName);
+MAKE_PTRDESTRUCT(NodePath);
+MAKE_PTRDESTRUCT(RID);
+MAKE_PTRDESTRUCT(Callable);
+MAKE_PTRDESTRUCT(Signal);
+MAKE_PTRDESTRUCT(Dictionary);
+MAKE_PTRDESTRUCT(Array);
+MAKE_PTRDESTRUCT(PackedByteArray);
+MAKE_PTRDESTRUCT(PackedInt32Array);
+MAKE_PTRDESTRUCT(PackedInt64Array);
+MAKE_PTRDESTRUCT(PackedFloat32Array);
+MAKE_PTRDESTRUCT(PackedFloat64Array);
+MAKE_PTRDESTRUCT(PackedStringArray);
+MAKE_PTRDESTRUCT(PackedVector2Array);
+MAKE_PTRDESTRUCT(PackedVector3Array);
+MAKE_PTRDESTRUCT(PackedColorArray);
+
+#undef MAKE_PTRDESTRUCT
+
+#endif // VARIANT_DESTRUCT_H
diff --git a/core/variant/variant_internal.h b/core/variant/variant_internal.h
index 7d33d85cd6..566b14736e 100644
--- a/core/variant/variant_internal.h
+++ b/core/variant/variant_internal.h
@@ -43,17 +43,20 @@ public:
v->type = p_type;
switch (p_type) {
- case Variant::AABB:
- init_aabb(v);
+ case Variant::STRING:
+ init_string(v);
break;
case Variant::TRANSFORM2D:
init_transform2d(v);
break;
- case Variant::TRANSFORM:
- init_transform(v);
+ case Variant::AABB:
+ init_aabb(v);
break;
- case Variant::STRING:
- init_string(v);
+ case Variant::BASIS:
+ init_basis(v);
+ break;
+ case Variant::TRANSFORM3D:
+ init_transform(v);
break;
case Variant::STRING_NAME:
init_string_name(v);
@@ -135,14 +138,14 @@ public:
_FORCE_INLINE_ static const Transform2D *get_transform2d(const Variant *v) { return v->_data._transform2d; }
_FORCE_INLINE_ static Plane *get_plane(Variant *v) { return reinterpret_cast<Plane *>(v->_data._mem); }
_FORCE_INLINE_ static const Plane *get_plane(const Variant *v) { return reinterpret_cast<const Plane *>(v->_data._mem); }
- _FORCE_INLINE_ static Quat *get_quat(Variant *v) { return reinterpret_cast<Quat *>(v->_data._mem); }
- _FORCE_INLINE_ static const Quat *get_quat(const Variant *v) { return reinterpret_cast<const Quat *>(v->_data._mem); }
+ _FORCE_INLINE_ static Quaternion *get_quaternion(Variant *v) { return reinterpret_cast<Quaternion *>(v->_data._mem); }
+ _FORCE_INLINE_ static const Quaternion *get_quaternion(const Variant *v) { return reinterpret_cast<const Quaternion *>(v->_data._mem); }
_FORCE_INLINE_ static ::AABB *get_aabb(Variant *v) { return v->_data._aabb; }
_FORCE_INLINE_ static const ::AABB *get_aabb(const Variant *v) { return v->_data._aabb; }
_FORCE_INLINE_ static Basis *get_basis(Variant *v) { return v->_data._basis; }
_FORCE_INLINE_ static const Basis *get_basis(const Variant *v) { return v->_data._basis; }
- _FORCE_INLINE_ static Transform *get_transform(Variant *v) { return v->_data._transform; }
- _FORCE_INLINE_ static const Transform *get_transform(const Variant *v) { return v->_data._transform; }
+ _FORCE_INLINE_ static Transform3D *get_transform(Variant *v) { return v->_data._transform3d; }
+ _FORCE_INLINE_ static const Transform3D *get_transform(const Variant *v) { return v->_data._transform3d; }
// Misc types.
_FORCE_INLINE_ static Color *get_color(Variant *v) { return reinterpret_cast<Color *>(v->_data._mem); }
@@ -192,6 +195,10 @@ public:
v->type = GetTypeInfo<T>::VARIANT_TYPE;
}
+ // Should be in the same order as Variant::Type for consistency.
+ // Those primitive and vector types don't need an `init_` method:
+ // Nil, bool, float, Vector2/i, Rect2/i, Vector3/i, Plane, Quat, Color, RID.
+ // Object is a special case, handled via `object_assign_null`.
_FORCE_INLINE_ static void init_string(Variant *v) {
memnew_placement(v->_data._mem, String);
v->type = Variant::STRING;
@@ -210,8 +217,8 @@ public:
v->type = Variant::BASIS;
}
_FORCE_INLINE_ static void init_transform(Variant *v) {
- v->_data._transform = memnew(Transform);
- v->type = Variant::TRANSFORM;
+ v->_data._transform3d = memnew(Transform3D);
+ v->type = Variant::TRANSFORM3D;
}
_FORCE_INLINE_ static void init_string_name(Variant *v) {
memnew_placement(v->_data._mem, StringName);
@@ -278,7 +285,7 @@ public:
v->clear();
}
- static void object_assign(Variant *v, const Object *o); // Needs Reference, so it's implemented elsewhere.
+ static void object_assign(Variant *v, const Object *o); // Needs RefCounted, so it's implemented elsewhere.
_FORCE_INLINE_ static void object_assign(Variant *v, const Variant *o) {
object_assign(v, o->_get_obj().obj);
@@ -313,12 +320,12 @@ public:
return get_rect2(v);
case Variant::RECT2I:
return get_rect2i(v);
- case Variant::TRANSFORM:
+ case Variant::TRANSFORM3D:
return get_transform(v);
case Variant::TRANSFORM2D:
return get_transform2d(v);
- case Variant::QUAT:
- return get_quat(v);
+ case Variant::QUATERNION:
+ return get_quaternion(v);
case Variant::PLANE:
return get_plane(v);
case Variant::BASIS:
@@ -391,12 +398,12 @@ public:
return get_rect2(v);
case Variant::RECT2I:
return get_rect2i(v);
- case Variant::TRANSFORM:
+ case Variant::TRANSFORM3D:
return get_transform(v);
case Variant::TRANSFORM2D:
return get_transform2d(v);
- case Variant::QUAT:
- return get_quat(v);
+ case Variant::QUATERNION:
+ return get_quaternion(v);
case Variant::PLANE:
return get_plane(v);
case Variant::BASIS:
@@ -583,9 +590,9 @@ struct VariantGetInternalPtr<Transform2D> {
};
template <>
-struct VariantGetInternalPtr<Transform> {
- static Transform *get_ptr(Variant *v) { return VariantInternal::get_transform(v); }
- static const Transform *get_ptr(const Variant *v) { return VariantInternal::get_transform(v); }
+struct VariantGetInternalPtr<Transform3D> {
+ static Transform3D *get_ptr(Variant *v) { return VariantInternal::get_transform(v); }
+ static const Transform3D *get_ptr(const Variant *v) { return VariantInternal::get_transform(v); }
};
template <>
@@ -595,9 +602,9 @@ struct VariantGetInternalPtr<Plane> {
};
template <>
-struct VariantGetInternalPtr<Quat> {
- static Quat *get_ptr(Variant *v) { return VariantInternal::get_quat(v); }
- static const Quat *get_ptr(const Variant *v) { return VariantInternal::get_quat(v); }
+struct VariantGetInternalPtr<Quaternion> {
+ static Quaternion *get_ptr(Variant *v) { return VariantInternal::get_quaternion(v); }
+ static const Quaternion *get_ptr(const Variant *v) { return VariantInternal::get_quaternion(v); }
};
template <>
@@ -812,9 +819,9 @@ struct VariantInternalAccessor<Transform2D> {
};
template <>
-struct VariantInternalAccessor<Transform> {
- static _FORCE_INLINE_ const Transform &get(const Variant *v) { return *VariantInternal::get_transform(v); }
- static _FORCE_INLINE_ void set(Variant *v, const Transform &p_value) { *VariantInternal::get_transform(v) = p_value; }
+struct VariantInternalAccessor<Transform3D> {
+ static _FORCE_INLINE_ const Transform3D &get(const Variant *v) { return *VariantInternal::get_transform(v); }
+ static _FORCE_INLINE_ void set(Variant *v, const Transform3D &p_value) { *VariantInternal::get_transform(v) = p_value; }
};
template <>
@@ -824,9 +831,9 @@ struct VariantInternalAccessor<Plane> {
};
template <>
-struct VariantInternalAccessor<Quat> {
- static _FORCE_INLINE_ const Quat &get(const Variant *v) { return *VariantInternal::get_quat(v); }
- static _FORCE_INLINE_ void set(Variant *v, const Quat &p_value) { *VariantInternal::get_quat(v) = p_value; }
+struct VariantInternalAccessor<Quaternion> {
+ static _FORCE_INLINE_ const Quaternion &get(const Variant *v) { return *VariantInternal::get_quaternion(v); }
+ static _FORCE_INLINE_ void set(Variant *v, const Quaternion &p_value) { *VariantInternal::get_quaternion(v) = p_value; }
};
template <>
@@ -1060,8 +1067,8 @@ struct VariantInitializer<Plane> {
};
template <>
-struct VariantInitializer<Quat> {
- static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic<Quat>(v); }
+struct VariantInitializer<Quaternion> {
+ static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic<Quaternion>(v); }
};
template <>
@@ -1075,7 +1082,7 @@ struct VariantInitializer<Basis> {
};
template <>
-struct VariantInitializer<Transform> {
+struct VariantInitializer<Transform3D> {
static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_transform(v); }
};
@@ -1164,6 +1171,11 @@ struct VariantInitializer<PackedColorArray> {
static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_color_array(v); }
};
+template <>
+struct VariantInitializer<Object *> {
+ static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::object_assign_null(v); }
+};
+
template <class T>
struct VariantZeroAssigner {
};
@@ -1234,8 +1246,8 @@ struct VariantZeroAssigner<Plane> {
};
template <>
-struct VariantZeroAssigner<Quat> {
- static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_quat(v) = Quat(); }
+struct VariantZeroAssigner<Quaternion> {
+ static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_quaternion(v) = Quaternion(); }
};
template <>
@@ -1249,8 +1261,8 @@ struct VariantZeroAssigner<Basis> {
};
template <>
-struct VariantZeroAssigner<Transform> {
- static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_transform(v) = Transform(); }
+struct VariantZeroAssigner<Transform3D> {
+ static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_transform(v) = Transform3D(); }
};
template <>
@@ -1378,4 +1390,19 @@ struct VariantTypeAdjust<Object *> {
}
};
+// GDNative extension helpers.
+
+template <class T>
+struct VariantTypeConstructor {
+ _FORCE_INLINE_ static void variant_from_type(void *p_variant, void *p_value) {
+ Variant *variant = reinterpret_cast<Variant *>(p_variant);
+ VariantInitializer<T>::init(variant);
+ VariantInternalAccessor<T>::set(variant, *((T *)p_value));
+ }
+
+ _FORCE_INLINE_ static void type_from_variant(void *p_value, void *p_variant) {
+ *((T *)p_value) = VariantInternalAccessor<T>::get(reinterpret_cast<Variant *>(p_variant));
+ }
+};
+
#endif // VARIANT_INTERNAL_H
diff --git a/core/variant/variant_op.cpp b/core/variant/variant_op.cpp
index 8cfa793c0e..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);
@@ -1395,7 +60,7 @@ void Variant::_register_variant_operators() {
register_op<OperatorEvaluatorAdd<Vector2i, Vector2i, Vector2i>>(Variant::OP_ADD, Variant::VECTOR2I, Variant::VECTOR2I);
register_op<OperatorEvaluatorAdd<Vector3, Vector3, Vector3>>(Variant::OP_ADD, Variant::VECTOR3, Variant::VECTOR3);
register_op<OperatorEvaluatorAdd<Vector3i, Vector3i, Vector3i>>(Variant::OP_ADD, Variant::VECTOR3I, Variant::VECTOR3I);
- register_op<OperatorEvaluatorAdd<Quat, Quat, Quat>>(Variant::OP_ADD, Variant::QUAT, Variant::QUAT);
+ register_op<OperatorEvaluatorAdd<Quaternion, Quaternion, Quaternion>>(Variant::OP_ADD, Variant::QUATERNION, Variant::QUATERNION);
register_op<OperatorEvaluatorAdd<Color, Color, Color>>(Variant::OP_ADD, Variant::COLOR, Variant::COLOR);
register_op<OperatorEvaluatorAddArray>(Variant::OP_ADD, Variant::ARRAY, Variant::ARRAY);
register_op<OperatorEvaluatorAppendArray<uint8_t>>(Variant::OP_ADD, Variant::PACKED_BYTE_ARRAY, Variant::PACKED_BYTE_ARRAY);
@@ -1416,7 +81,7 @@ void Variant::_register_variant_operators() {
register_op<OperatorEvaluatorSub<Vector2i, Vector2i, Vector2i>>(Variant::OP_SUBTRACT, Variant::VECTOR2I, Variant::VECTOR2I);
register_op<OperatorEvaluatorSub<Vector3, Vector3, Vector3>>(Variant::OP_SUBTRACT, Variant::VECTOR3, Variant::VECTOR3);
register_op<OperatorEvaluatorSub<Vector3i, Vector3i, Vector3i>>(Variant::OP_SUBTRACT, Variant::VECTOR3I, Variant::VECTOR3I);
- register_op<OperatorEvaluatorSub<Quat, Quat, Quat>>(Variant::OP_SUBTRACT, Variant::QUAT, Variant::QUAT);
+ register_op<OperatorEvaluatorSub<Quaternion, Quaternion, Quaternion>>(Variant::OP_SUBTRACT, Variant::QUATERNION, Variant::QUATERNION);
register_op<OperatorEvaluatorSub<Color, Color, Color>>(Variant::OP_SUBTRACT, Variant::COLOR, Variant::COLOR);
register_op<OperatorEvaluatorMul<int64_t, int64_t, int64_t>>(Variant::OP_MULTIPLY, Variant::INT, Variant::INT);
@@ -1449,15 +114,17 @@ void Variant::_register_variant_operators() {
register_op<OperatorEvaluatorMul<Vector3i, Vector3i, int64_t>>(Variant::OP_MULTIPLY, Variant::VECTOR3I, Variant::INT);
register_op<OperatorEvaluatorMul<Vector3i, Vector3i, double>>(Variant::OP_MULTIPLY, Variant::VECTOR3I, Variant::FLOAT);
- register_op<OperatorEvaluatorMul<Quat, Quat, Quat>>(Variant::OP_MULTIPLY, Variant::QUAT, Variant::QUAT);
- register_op<OperatorEvaluatorMul<Quat, Quat, int64_t>>(Variant::OP_MULTIPLY, Variant::QUAT, Variant::INT);
- register_op<OperatorEvaluatorMul<Quat, Quat, double>>(Variant::OP_MULTIPLY, Variant::QUAT, Variant::FLOAT);
+ register_op<OperatorEvaluatorMul<Quaternion, Quaternion, Quaternion>>(Variant::OP_MULTIPLY, Variant::QUATERNION, Variant::QUATERNION);
+ register_op<OperatorEvaluatorMul<Quaternion, Quaternion, int64_t>>(Variant::OP_MULTIPLY, Variant::QUATERNION, Variant::INT);
+ register_op<OperatorEvaluatorMul<Quaternion, Quaternion, double>>(Variant::OP_MULTIPLY, Variant::QUATERNION, Variant::FLOAT);
register_op<OperatorEvaluatorMul<Color, Color, Color>>(Variant::OP_MULTIPLY, Variant::COLOR, Variant::COLOR);
register_op<OperatorEvaluatorMul<Color, Color, int64_t>>(Variant::OP_MULTIPLY, Variant::COLOR, Variant::INT);
register_op<OperatorEvaluatorMul<Color, Color, double>>(Variant::OP_MULTIPLY, Variant::COLOR, Variant::FLOAT);
register_op<OperatorEvaluatorMul<Transform2D, Transform2D, Transform2D>>(Variant::OP_MULTIPLY, Variant::TRANSFORM2D, Variant::TRANSFORM2D);
+ register_op<OperatorEvaluatorMul<Transform2D, Transform2D, int64_t>>(Variant::OP_MULTIPLY, Variant::TRANSFORM2D, Variant::INT);
+ register_op<OperatorEvaluatorMul<Transform2D, Transform2D, double>>(Variant::OP_MULTIPLY, Variant::TRANSFORM2D, Variant::FLOAT);
register_op<OperatorEvaluatorXForm<Vector2, Transform2D, Vector2>>(Variant::OP_MULTIPLY, Variant::TRANSFORM2D, Variant::VECTOR2);
register_op<OperatorEvaluatorXFormInv<Vector2, Vector2, Transform2D>>(Variant::OP_MULTIPLY, Variant::VECTOR2, Variant::TRANSFORM2D);
register_op<OperatorEvaluatorXForm<Rect2, Transform2D, Rect2>>(Variant::OP_MULTIPLY, Variant::TRANSFORM2D, Variant::RECT2);
@@ -1465,25 +132,29 @@ void Variant::_register_variant_operators() {
register_op<OperatorEvaluatorXForm<Vector<Vector2>, Transform2D, Vector<Vector2>>>(Variant::OP_MULTIPLY, Variant::TRANSFORM2D, Variant::PACKED_VECTOR2_ARRAY);
register_op<OperatorEvaluatorXFormInv<Vector<Vector2>, Vector<Vector2>, Transform2D>>(Variant::OP_MULTIPLY, Variant::PACKED_VECTOR2_ARRAY, Variant::TRANSFORM2D);
- register_op<OperatorEvaluatorMul<Transform, Transform, Transform>>(Variant::OP_MULTIPLY, Variant::TRANSFORM, Variant::TRANSFORM);
- register_op<OperatorEvaluatorXForm<Vector3, Transform, Vector3>>(Variant::OP_MULTIPLY, Variant::TRANSFORM, Variant::VECTOR3);
- register_op<OperatorEvaluatorXFormInv<Vector3, Vector3, Transform>>(Variant::OP_MULTIPLY, Variant::VECTOR3, Variant::TRANSFORM);
- register_op<OperatorEvaluatorXForm<::AABB, Transform, ::AABB>>(Variant::OP_MULTIPLY, Variant::TRANSFORM, Variant::AABB);
- register_op<OperatorEvaluatorXFormInv<::AABB, ::AABB, Transform>>(Variant::OP_MULTIPLY, Variant::AABB, Variant::TRANSFORM);
- register_op<OperatorEvaluatorXForm<Vector<Vector3>, Transform, Vector<Vector3>>>(Variant::OP_MULTIPLY, Variant::TRANSFORM, Variant::PACKED_VECTOR3_ARRAY);
- register_op<OperatorEvaluatorXFormInv<Vector<Vector3>, Vector<Vector3>, Transform>>(Variant::OP_MULTIPLY, Variant::PACKED_VECTOR3_ARRAY, Variant::TRANSFORM);
+ register_op<OperatorEvaluatorMul<Transform3D, Transform3D, Transform3D>>(Variant::OP_MULTIPLY, Variant::TRANSFORM3D, Variant::TRANSFORM3D);
+ register_op<OperatorEvaluatorMul<Transform3D, Transform3D, int64_t>>(Variant::OP_MULTIPLY, Variant::TRANSFORM3D, Variant::INT);
+ register_op<OperatorEvaluatorMul<Transform3D, Transform3D, double>>(Variant::OP_MULTIPLY, Variant::TRANSFORM3D, Variant::FLOAT);
+ register_op<OperatorEvaluatorXForm<Vector3, Transform3D, Vector3>>(Variant::OP_MULTIPLY, Variant::TRANSFORM3D, Variant::VECTOR3);
+ register_op<OperatorEvaluatorXFormInv<Vector3, Vector3, Transform3D>>(Variant::OP_MULTIPLY, Variant::VECTOR3, Variant::TRANSFORM3D);
+ register_op<OperatorEvaluatorXForm<::AABB, Transform3D, ::AABB>>(Variant::OP_MULTIPLY, Variant::TRANSFORM3D, Variant::AABB);
+ register_op<OperatorEvaluatorXFormInv<::AABB, ::AABB, Transform3D>>(Variant::OP_MULTIPLY, Variant::AABB, Variant::TRANSFORM3D);
+ register_op<OperatorEvaluatorXForm<Vector<Vector3>, Transform3D, Vector<Vector3>>>(Variant::OP_MULTIPLY, Variant::TRANSFORM3D, Variant::PACKED_VECTOR3_ARRAY);
+ register_op<OperatorEvaluatorXFormInv<Vector<Vector3>, Vector<Vector3>, Transform3D>>(Variant::OP_MULTIPLY, Variant::PACKED_VECTOR3_ARRAY, Variant::TRANSFORM3D);
register_op<OperatorEvaluatorMul<Basis, Basis, Basis>>(Variant::OP_MULTIPLY, Variant::BASIS, Variant::BASIS);
+ register_op<OperatorEvaluatorMul<Basis, Basis, int64_t>>(Variant::OP_MULTIPLY, Variant::BASIS, Variant::INT);
+ register_op<OperatorEvaluatorMul<Basis, Basis, double>>(Variant::OP_MULTIPLY, Variant::BASIS, Variant::FLOAT);
register_op<OperatorEvaluatorXForm<Vector3, Basis, Vector3>>(Variant::OP_MULTIPLY, Variant::BASIS, Variant::VECTOR3);
register_op<OperatorEvaluatorXFormInv<Vector3, Vector3, Basis>>(Variant::OP_MULTIPLY, Variant::VECTOR3, Variant::BASIS);
- register_op<OperatorEvaluatorMul<Quat, Quat, Quat>>(Variant::OP_MULTIPLY, Variant::QUAT, Variant::QUAT);
- register_op<OperatorEvaluatorMul<Quat, Quat, int64_t>>(Variant::OP_MULTIPLY, Variant::QUAT, Variant::INT);
- register_op<OperatorEvaluatorMul<Quat, int64_t, Quat>>(Variant::OP_MULTIPLY, Variant::INT, Variant::QUAT);
- register_op<OperatorEvaluatorMul<Quat, Quat, double>>(Variant::OP_MULTIPLY, Variant::QUAT, Variant::FLOAT);
- register_op<OperatorEvaluatorMul<Quat, double, Quat>>(Variant::OP_MULTIPLY, Variant::FLOAT, Variant::QUAT);
- register_op<OperatorEvaluatorXForm<Vector3, Quat, Vector3>>(Variant::OP_MULTIPLY, Variant::QUAT, Variant::VECTOR3);
- register_op<OperatorEvaluatorXFormInv<Vector3, Vector3, Quat>>(Variant::OP_MULTIPLY, Variant::VECTOR3, Variant::QUAT);
+ register_op<OperatorEvaluatorMul<Quaternion, Quaternion, Quaternion>>(Variant::OP_MULTIPLY, Variant::QUATERNION, Variant::QUATERNION);
+ register_op<OperatorEvaluatorMul<Quaternion, Quaternion, int64_t>>(Variant::OP_MULTIPLY, Variant::QUATERNION, Variant::INT);
+ register_op<OperatorEvaluatorMul<Quaternion, int64_t, Quaternion>>(Variant::OP_MULTIPLY, Variant::INT, Variant::QUATERNION);
+ register_op<OperatorEvaluatorMul<Quaternion, Quaternion, double>>(Variant::OP_MULTIPLY, Variant::QUATERNION, Variant::FLOAT);
+ register_op<OperatorEvaluatorMul<Quaternion, double, Quaternion>>(Variant::OP_MULTIPLY, Variant::FLOAT, Variant::QUATERNION);
+ register_op<OperatorEvaluatorXForm<Vector3, Quaternion, Vector3>>(Variant::OP_MULTIPLY, Variant::QUATERNION, Variant::VECTOR3);
+ register_op<OperatorEvaluatorXFormInv<Vector3, Vector3, Quaternion>>(Variant::OP_MULTIPLY, Variant::VECTOR3, Variant::QUATERNION);
register_op<OperatorEvaluatorMul<Color, Color, Color>>(Variant::OP_MULTIPLY, Variant::COLOR, Variant::COLOR);
register_op<OperatorEvaluatorMul<Color, Color, int64_t>>(Variant::OP_MULTIPLY, Variant::COLOR, Variant::INT);
@@ -1516,8 +187,8 @@ void Variant::_register_variant_operators() {
register_op<OperatorEvaluatorDivNZ<Vector3i, Vector3i, double>>(Variant::OP_DIVIDE, Variant::VECTOR3I, Variant::FLOAT);
register_op<OperatorEvaluatorDivNZ<Vector3i, Vector3i, int64_t>>(Variant::OP_DIVIDE, Variant::VECTOR3I, Variant::INT);
- register_op<OperatorEvaluatorDiv<Quat, Quat, double>>(Variant::OP_DIVIDE, Variant::QUAT, Variant::FLOAT);
- register_op<OperatorEvaluatorDiv<Quat, Quat, int64_t>>(Variant::OP_DIVIDE, Variant::QUAT, Variant::INT);
+ register_op<OperatorEvaluatorDiv<Quaternion, Quaternion, double>>(Variant::OP_DIVIDE, Variant::QUATERNION, Variant::FLOAT);
+ register_op<OperatorEvaluatorDiv<Quaternion, Quaternion, int64_t>>(Variant::OP_DIVIDE, Variant::QUATERNION, Variant::INT);
register_op<OperatorEvaluatorDiv<Color, Color, Color>>(Variant::OP_DIVIDE, Variant::COLOR, Variant::COLOR);
register_op<OperatorEvaluatorDiv<Color, Color, double>>(Variant::OP_DIVIDE, Variant::COLOR, Variant::FLOAT);
@@ -1544,10 +215,10 @@ void Variant::_register_variant_operators() {
register_op<OperatorEvaluatorStringModT<Vector3i>>(Variant::OP_MODULE, Variant::STRING, Variant::VECTOR3I);
register_op<OperatorEvaluatorStringModT<Transform2D>>(Variant::OP_MODULE, Variant::STRING, Variant::TRANSFORM2D);
register_op<OperatorEvaluatorStringModT<Plane>>(Variant::OP_MODULE, Variant::STRING, Variant::PLANE);
- register_op<OperatorEvaluatorStringModT<Quat>>(Variant::OP_MODULE, Variant::STRING, Variant::QUAT);
+ register_op<OperatorEvaluatorStringModT<Quaternion>>(Variant::OP_MODULE, Variant::STRING, Variant::QUATERNION);
register_op<OperatorEvaluatorStringModT<::AABB>>(Variant::OP_MODULE, Variant::STRING, Variant::AABB);
register_op<OperatorEvaluatorStringModT<Basis>>(Variant::OP_MODULE, Variant::STRING, Variant::BASIS);
- register_op<OperatorEvaluatorStringModT<Transform>>(Variant::OP_MODULE, Variant::STRING, Variant::TRANSFORM);
+ register_op<OperatorEvaluatorStringModT<Transform3D>>(Variant::OP_MODULE, Variant::STRING, Variant::TRANSFORM3D);
register_op<OperatorEvaluatorStringModT<Color>>(Variant::OP_MODULE, Variant::STRING, Variant::COLOR);
register_op<OperatorEvaluatorStringModT<StringName>>(Variant::OP_MODULE, Variant::STRING, Variant::STRING_NAME);
@@ -1574,7 +245,7 @@ void Variant::_register_variant_operators() {
register_op<OperatorEvaluatorNeg<Vector2i, Vector2i>>(Variant::OP_NEGATE, Variant::VECTOR2I, Variant::NIL);
register_op<OperatorEvaluatorNeg<Vector3, Vector3>>(Variant::OP_NEGATE, Variant::VECTOR3, Variant::NIL);
register_op<OperatorEvaluatorNeg<Vector3i, Vector3i>>(Variant::OP_NEGATE, Variant::VECTOR3I, Variant::NIL);
- register_op<OperatorEvaluatorNeg<Quat, Quat>>(Variant::OP_NEGATE, Variant::QUAT, Variant::NIL);
+ register_op<OperatorEvaluatorNeg<Quaternion, Quaternion>>(Variant::OP_NEGATE, Variant::QUATERNION, Variant::NIL);
register_op<OperatorEvaluatorNeg<Plane, Plane>>(Variant::OP_NEGATE, Variant::PLANE, Variant::NIL);
register_op<OperatorEvaluatorNeg<Color, Color>>(Variant::OP_NEGATE, Variant::COLOR, Variant::NIL);
@@ -1584,7 +255,7 @@ void Variant::_register_variant_operators() {
register_op<OperatorEvaluatorPos<Vector2i, Vector2i>>(Variant::OP_POSITIVE, Variant::VECTOR2I, Variant::NIL);
register_op<OperatorEvaluatorPos<Vector3, Vector3>>(Variant::OP_POSITIVE, Variant::VECTOR3, Variant::NIL);
register_op<OperatorEvaluatorPos<Vector3i, Vector3i>>(Variant::OP_POSITIVE, Variant::VECTOR3I, Variant::NIL);
- register_op<OperatorEvaluatorPos<Quat, Quat>>(Variant::OP_POSITIVE, Variant::QUAT, Variant::NIL);
+ register_op<OperatorEvaluatorPos<Quaternion, Quaternion>>(Variant::OP_POSITIVE, Variant::QUATERNION, Variant::NIL);
register_op<OperatorEvaluatorPos<Plane, Plane>>(Variant::OP_POSITIVE, Variant::PLANE, Variant::NIL);
register_op<OperatorEvaluatorPos<Color, Color>>(Variant::OP_POSITIVE, Variant::COLOR, Variant::NIL);
@@ -1612,10 +283,10 @@ void Variant::_register_variant_operators() {
register_op<OperatorEvaluatorEqual<Vector3i, Vector3i>>(Variant::OP_EQUAL, Variant::VECTOR3I, Variant::VECTOR3I);
register_op<OperatorEvaluatorEqual<Transform2D, Transform2D>>(Variant::OP_EQUAL, Variant::TRANSFORM2D, Variant::TRANSFORM2D);
register_op<OperatorEvaluatorEqual<Plane, Plane>>(Variant::OP_EQUAL, Variant::PLANE, Variant::PLANE);
- register_op<OperatorEvaluatorEqual<Quat, Quat>>(Variant::OP_EQUAL, Variant::QUAT, Variant::QUAT);
+ register_op<OperatorEvaluatorEqual<Quaternion, Quaternion>>(Variant::OP_EQUAL, Variant::QUATERNION, Variant::QUATERNION);
register_op<OperatorEvaluatorEqual<::AABB, ::AABB>>(Variant::OP_EQUAL, Variant::AABB, Variant::AABB);
register_op<OperatorEvaluatorEqual<Basis, Basis>>(Variant::OP_EQUAL, Variant::BASIS, Variant::BASIS);
- register_op<OperatorEvaluatorEqual<Transform, Transform>>(Variant::OP_EQUAL, Variant::TRANSFORM, Variant::TRANSFORM);
+ register_op<OperatorEvaluatorEqual<Transform3D, Transform3D>>(Variant::OP_EQUAL, Variant::TRANSFORM3D, Variant::TRANSFORM3D);
register_op<OperatorEvaluatorEqual<Color, Color>>(Variant::OP_EQUAL, Variant::COLOR, Variant::COLOR);
register_op<OperatorEvaluatorEqual<StringName, String>>(Variant::OP_EQUAL, Variant::STRING_NAME, Variant::STRING);
@@ -1658,10 +329,10 @@ void Variant::_register_variant_operators() {
register_op<OperatorEvaluatorNotEqual<Vector3i, Vector3i>>(Variant::OP_NOT_EQUAL, Variant::VECTOR3I, Variant::VECTOR3I);
register_op<OperatorEvaluatorNotEqual<Transform2D, Transform2D>>(Variant::OP_NOT_EQUAL, Variant::TRANSFORM2D, Variant::TRANSFORM2D);
register_op<OperatorEvaluatorNotEqual<Plane, Plane>>(Variant::OP_NOT_EQUAL, Variant::PLANE, Variant::PLANE);
- register_op<OperatorEvaluatorNotEqual<Quat, Quat>>(Variant::OP_NOT_EQUAL, Variant::QUAT, Variant::QUAT);
+ register_op<OperatorEvaluatorNotEqual<Quaternion, Quaternion>>(Variant::OP_NOT_EQUAL, Variant::QUATERNION, Variant::QUATERNION);
register_op<OperatorEvaluatorNotEqual<::AABB, ::AABB>>(Variant::OP_NOT_EQUAL, Variant::AABB, Variant::AABB);
register_op<OperatorEvaluatorNotEqual<Basis, Basis>>(Variant::OP_NOT_EQUAL, Variant::BASIS, Variant::BASIS);
- register_op<OperatorEvaluatorNotEqual<Transform, Transform>>(Variant::OP_NOT_EQUAL, Variant::TRANSFORM, Variant::TRANSFORM);
+ register_op<OperatorEvaluatorNotEqual<Transform3D, Transform3D>>(Variant::OP_NOT_EQUAL, Variant::TRANSFORM3D, Variant::TRANSFORM3D);
register_op<OperatorEvaluatorNotEqual<Color, Color>>(Variant::OP_NOT_EQUAL, Variant::COLOR, Variant::COLOR);
register_op<OperatorEvaluatorNotEqual<StringName, String>>(Variant::OP_NOT_EQUAL, Variant::STRING_NAME, Variant::STRING);
@@ -1849,10 +520,10 @@ void Variant::_register_variant_operators() {
register_op<OperatorEvaluatorInDictionaryHas<Vector3i>>(Variant::OP_IN, Variant::VECTOR3I, Variant::DICTIONARY);
register_op<OperatorEvaluatorInDictionaryHas<Transform2D>>(Variant::OP_IN, Variant::TRANSFORM2D, Variant::DICTIONARY);
register_op<OperatorEvaluatorInDictionaryHas<Plane>>(Variant::OP_IN, Variant::PLANE, Variant::DICTIONARY);
- register_op<OperatorEvaluatorInDictionaryHas<Quat>>(Variant::OP_IN, Variant::QUAT, Variant::DICTIONARY);
+ register_op<OperatorEvaluatorInDictionaryHas<Quaternion>>(Variant::OP_IN, Variant::QUATERNION, Variant::DICTIONARY);
register_op<OperatorEvaluatorInDictionaryHas<::AABB>>(Variant::OP_IN, Variant::AABB, Variant::DICTIONARY);
register_op<OperatorEvaluatorInDictionaryHas<Basis>>(Variant::OP_IN, Variant::BASIS, Variant::DICTIONARY);
- register_op<OperatorEvaluatorInDictionaryHas<Transform>>(Variant::OP_IN, Variant::TRANSFORM, Variant::DICTIONARY);
+ register_op<OperatorEvaluatorInDictionaryHas<Transform3D>>(Variant::OP_IN, Variant::TRANSFORM3D, Variant::DICTIONARY);
register_op<OperatorEvaluatorInDictionaryHas<Color>>(Variant::OP_IN, Variant::COLOR, Variant::DICTIONARY);
register_op<OperatorEvaluatorInDictionaryHas<StringName>>(Variant::OP_IN, Variant::STRING_NAME, Variant::DICTIONARY);
@@ -1886,10 +557,10 @@ void Variant::_register_variant_operators() {
register_op<OperatorEvaluatorInArrayFind<Vector3i, Array>>(Variant::OP_IN, Variant::VECTOR3I, Variant::ARRAY);
register_op<OperatorEvaluatorInArrayFind<Transform2D, Array>>(Variant::OP_IN, Variant::TRANSFORM2D, Variant::ARRAY);
register_op<OperatorEvaluatorInArrayFind<Plane, Array>>(Variant::OP_IN, Variant::PLANE, Variant::ARRAY);
- register_op<OperatorEvaluatorInArrayFind<Quat, Array>>(Variant::OP_IN, Variant::QUAT, Variant::ARRAY);
+ register_op<OperatorEvaluatorInArrayFind<Quaternion, Array>>(Variant::OP_IN, Variant::QUATERNION, Variant::ARRAY);
register_op<OperatorEvaluatorInArrayFind<::AABB, Array>>(Variant::OP_IN, Variant::AABB, Variant::ARRAY);
register_op<OperatorEvaluatorInArrayFind<Basis, Array>>(Variant::OP_IN, Variant::BASIS, Variant::ARRAY);
- register_op<OperatorEvaluatorInArrayFind<Transform, Array>>(Variant::OP_IN, Variant::TRANSFORM, Variant::ARRAY);
+ register_op<OperatorEvaluatorInArrayFind<Transform3D, Array>>(Variant::OP_IN, Variant::TRANSFORM3D, Variant::ARRAY);
register_op<OperatorEvaluatorInArrayFind<Color, Array>>(Variant::OP_IN, Variant::COLOR, Variant::ARRAY);
register_op<OperatorEvaluatorInArrayFind<StringName, Array>>(Variant::OP_IN, Variant::STRING_NAME, Variant::ARRAY);
@@ -1990,8 +661,8 @@ static const char *_op_names[Variant::OP_MAX] = {
"-",
"*",
"/",
- "-",
- "+",
+ "unary-",
+ "unary+",
"%",
"<<",
">>",
diff --git a/core/variant/variant_op.h b/core/variant/variant_op.h
new file mode 100644
index 0000000000..cbdd60f404
--- /dev/null
+++ b/core/variant/variant_op.h
@@ -0,0 +1,1320 @@
+/*************************************************************************/
+/* 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);
+
+ bool exist;
+ b->get(a, &exist);
+ *r_ret = exist;
+ r_valid = true;
+ }
+ static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
+ Object *l = right->get_validated_object();
+ ERR_FAIL_COND(l == nullptr);
+ const String &a = *VariantGetInternalPtr<String>::get_ptr(left);
+
+ bool valid;
+ l->get(a, &valid);
+ *VariantGetInternalPtr<bool>::get_ptr(r_ret) = valid;
+ }
+ static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
+ bool valid;
+ PtrToArg<Object *>::convert(right)->get(PtrToArg<String>::convert(left), &valid);
+ PtrToArg<bool>::encode(valid, r_ret);
+ }
+ static Variant::Type get_return_type() { return Variant::BOOL; }
+};
+
+class OperatorEvaluatorObjectHasPropertyStringName {
+public:
+ static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
+ Object *b = p_right.get_validated_object();
+ if (!b) {
+ *r_ret = "Invalid base object for 'in'";
+ r_valid = false;
+ return;
+ }
+
+ const StringName &a = *VariantGetInternalPtr<StringName>::get_ptr(&p_left);
+
+ bool exist;
+ b->get(a, &exist);
+ *r_ret = exist;
+ r_valid = true;
+ }
+ static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
+ Object *l = right->get_validated_object();
+ ERR_FAIL_COND(l == nullptr);
+ const StringName &a = *VariantGetInternalPtr<StringName>::get_ptr(left);
+
+ bool valid;
+ l->get(a, &valid);
+ *VariantGetInternalPtr<bool>::get_ptr(r_ret) = valid;
+ }
+ static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
+ bool valid;
+ PtrToArg<Object *>::convert(right)->get(PtrToArg<StringName>::convert(left), &valid);
+ PtrToArg<bool>::encode(valid, r_ret);
+ }
+ static Variant::Type get_return_type() { return Variant::BOOL; }
+};
+
+#endif // VARIANT_OP_H
diff --git a/core/variant/variant_parser.cpp b/core/variant/variant_parser.cpp
index edaeddbf27..a214a238a6 100644
--- a/core/variant/variant_parser.cpp
+++ b/core/variant/variant_parser.cpp
@@ -190,10 +190,13 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri
r_token.type = TK_COLOR;
return OK;
}
- case '@': {
+#ifndef DISABLE_DEPRECATED
+ case '@': // Compatibility with 3.x StringNames.
+#endif
+ case '&': { // StringName.
cchar = p_stream->get_char();
if (cchar != '"') {
- r_err_str = "Expected '\"' after '@'";
+ r_err_str = "Expected '\"' after '&'";
r_token.type = TK_ERROR;
return ERR_PARSE_ERROR;
}
@@ -503,9 +506,9 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
} else if (id == "null" || id == "nil") {
value = Variant();
} else if (id == "inf") {
- value = Math_INF;
+ value = INFINITY;
} else if (id == "nan") {
- value = Math_NAN;
+ value = NAN;
} else if (id == "Vector2") {
Vector<real_t> args;
Error err = _parse_construct<real_t>(p_stream, args, line, r_err_str);
@@ -614,7 +617,7 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
}
value = Plane(args[0], args[1], args[2], args[3]);
- } else if (id == "Quat") {
+ } else if (id == "Quaternion" || id == "Quat") { // "Quat" kept for compatibility
Vector<real_t> args;
Error err = _parse_construct<real_t>(p_stream, args, line, r_err_str);
if (err) {
@@ -626,7 +629,7 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
return ERR_PARSE_ERROR;
}
- value = Quat(args[0], args[1], args[2], args[3]);
+ value = Quaternion(args[0], args[1], args[2], args[3]);
} else if (id == "AABB" || id == "Rect3") {
Vector<real_t> args;
Error err = _parse_construct<real_t>(p_stream, args, line, r_err_str);
@@ -653,7 +656,7 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
}
value = Basis(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8]);
- } else if (id == "Transform") {
+ } else if (id == "Transform3D" || id == "Transform") { // "Transform" kept for compatibility with Godot <4.
Vector<real_t> args;
Error err = _parse_construct<real_t>(p_stream, args, line, r_err_str);
if (err) {
@@ -665,7 +668,7 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
return ERR_PARSE_ERROR;
}
- value = Transform(Basis(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8]), Vector3(args[9], args[10], args[11]));
+ value = Transform3D(Basis(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8]), Vector3(args[9], args[10], args[11]));
} else if (id == "Color") {
Vector<float> args;
Error err = _parse_construct<float>(p_stream, args, line, r_err_str);
@@ -735,14 +738,14 @@ 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;
}
- REF ref = REF(Object::cast_to<Reference>(obj));
+ REF ref = REF(Object::cast_to<RefCounted>(obj));
get_token(p_stream, token, line, r_err_str);
if (token.type != TK_COMMA) {
@@ -1201,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();
@@ -1404,7 +1423,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
p_store_string_func(p_store_string_ud, itos(p_variant.operator int64_t()));
} break;
case Variant::FLOAT: {
- String s = rtosfix(p_variant.operator real_t());
+ String s = rtosfix(p_variant.operator double());
if (s != "inf" && s != "nan") {
if (s.find(".") == -1 && s.find("e") == -1) {
s += ".0";
@@ -1420,47 +1439,47 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
} break;
case Variant::VECTOR2: {
Vector2 v = p_variant;
- p_store_string_func(p_store_string_ud, "Vector2( " + rtosfix(v.x) + ", " + rtosfix(v.y) + " )");
+ p_store_string_func(p_store_string_ud, "Vector2(" + rtosfix(v.x) + ", " + rtosfix(v.y) + ")");
} break;
case Variant::VECTOR2I: {
Vector2i v = p_variant;
- p_store_string_func(p_store_string_ud, "Vector2i( " + itos(v.x) + ", " + itos(v.y) + " )");
+ p_store_string_func(p_store_string_ud, "Vector2i(" + itos(v.x) + ", " + itos(v.y) + ")");
} break;
case Variant::RECT2: {
Rect2 aabb = p_variant;
- p_store_string_func(p_store_string_ud, "Rect2( " + rtosfix(aabb.position.x) + ", " + rtosfix(aabb.position.y) + ", " + rtosfix(aabb.size.x) + ", " + rtosfix(aabb.size.y) + " )");
+ p_store_string_func(p_store_string_ud, "Rect2(" + rtosfix(aabb.position.x) + ", " + rtosfix(aabb.position.y) + ", " + rtosfix(aabb.size.x) + ", " + rtosfix(aabb.size.y) + ")");
} break;
case Variant::RECT2I: {
Rect2i aabb = p_variant;
- p_store_string_func(p_store_string_ud, "Rect2i( " + itos(aabb.position.x) + ", " + itos(aabb.position.y) + ", " + itos(aabb.size.x) + ", " + itos(aabb.size.y) + " )");
+ p_store_string_func(p_store_string_ud, "Rect2i(" + itos(aabb.position.x) + ", " + itos(aabb.position.y) + ", " + itos(aabb.size.x) + ", " + itos(aabb.size.y) + ")");
} break;
case Variant::VECTOR3: {
Vector3 v = p_variant;
- p_store_string_func(p_store_string_ud, "Vector3( " + rtosfix(v.x) + ", " + rtosfix(v.y) + ", " + rtosfix(v.z) + " )");
+ p_store_string_func(p_store_string_ud, "Vector3(" + rtosfix(v.x) + ", " + rtosfix(v.y) + ", " + rtosfix(v.z) + ")");
} break;
case Variant::VECTOR3I: {
Vector3i v = p_variant;
- p_store_string_func(p_store_string_ud, "Vector3i( " + itos(v.x) + ", " + itos(v.y) + ", " + itos(v.z) + " )");
+ p_store_string_func(p_store_string_ud, "Vector3i(" + itos(v.x) + ", " + itos(v.y) + ", " + itos(v.z) + ")");
} break;
case Variant::PLANE: {
Plane p = p_variant;
- p_store_string_func(p_store_string_ud, "Plane( " + rtosfix(p.normal.x) + ", " + rtosfix(p.normal.y) + ", " + rtosfix(p.normal.z) + ", " + rtosfix(p.d) + " )");
+ p_store_string_func(p_store_string_ud, "Plane(" + rtosfix(p.normal.x) + ", " + rtosfix(p.normal.y) + ", " + rtosfix(p.normal.z) + ", " + rtosfix(p.d) + ")");
} break;
case Variant::AABB: {
AABB aabb = p_variant;
- p_store_string_func(p_store_string_ud, "AABB( " + rtosfix(aabb.position.x) + ", " + rtosfix(aabb.position.y) + ", " + rtosfix(aabb.position.z) + ", " + rtosfix(aabb.size.x) + ", " + rtosfix(aabb.size.y) + ", " + rtosfix(aabb.size.z) + " )");
+ p_store_string_func(p_store_string_ud, "AABB(" + rtosfix(aabb.position.x) + ", " + rtosfix(aabb.position.y) + ", " + rtosfix(aabb.position.z) + ", " + rtosfix(aabb.size.x) + ", " + rtosfix(aabb.size.y) + ", " + rtosfix(aabb.size.z) + ")");
} break;
- case Variant::QUAT: {
- Quat quat = p_variant;
- p_store_string_func(p_store_string_ud, "Quat( " + rtosfix(quat.x) + ", " + rtosfix(quat.y) + ", " + rtosfix(quat.z) + ", " + rtosfix(quat.w) + " )");
+ case Variant::QUATERNION: {
+ Quaternion quaternion = p_variant;
+ p_store_string_func(p_store_string_ud, "Quaternion(" + rtosfix(quaternion.x) + ", " + rtosfix(quaternion.y) + ", " + rtosfix(quaternion.z) + ", " + rtosfix(quaternion.w) + ")");
} break;
case Variant::TRANSFORM2D: {
- String s = "Transform2D( ";
+ String s = "Transform2D(";
Transform2D m3 = p_variant;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 2; j++) {
@@ -1471,11 +1490,11 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
}
}
- p_store_string_func(p_store_string_ud, s + " )");
+ p_store_string_func(p_store_string_ud, s + ")");
} break;
case Variant::BASIS: {
- String s = "Basis( ";
+ String s = "Basis(";
Basis m3 = p_variant;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
@@ -1486,12 +1505,12 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
}
}
- p_store_string_func(p_store_string_ud, s + " )");
+ p_store_string_func(p_store_string_ud, s + ")");
} break;
- case Variant::TRANSFORM: {
- String s = "Transform( ";
- Transform t = p_variant;
+ case Variant::TRANSFORM3D: {
+ String s = "Transform3D(";
+ Transform3D t = p_variant;
Basis &m3 = t.basis;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
@@ -1504,19 +1523,19 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
s = s + ", " + rtosfix(t.origin.x) + ", " + rtosfix(t.origin.y) + ", " + rtosfix(t.origin.z);
- p_store_string_func(p_store_string_ud, s + " )");
+ p_store_string_func(p_store_string_ud, s + ")");
} break;
// misc types
case Variant::COLOR: {
Color c = p_variant;
- p_store_string_func(p_store_string_ud, "Color( " + rtosfix(c.r) + ", " + rtosfix(c.g) + ", " + rtosfix(c.b) + ", " + rtosfix(c.a) + " )");
+ p_store_string_func(p_store_string_ud, "Color(" + rtosfix(c.r) + ", " + rtosfix(c.g) + ", " + rtosfix(c.b) + ", " + rtosfix(c.a) + ")");
} break;
case Variant::STRING_NAME: {
String str = p_variant;
- str = "@\"" + str.c_escape() + "\"";
+ str = "&\"" + str.c_escape() + "\"";
p_store_string_func(p_store_string_ud, str);
} break;
@@ -1550,7 +1569,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
if (res_text == String() && res->get_path().is_resource_file()) {
//external resource
String path = res->get_path();
- res_text = "Resource( \"" + path + "\")";
+ res_text = "Resource(\"" + path + "\")";
}
//could come up with some sort of text
@@ -1567,8 +1586,8 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
List<PropertyInfo> props;
obj->get_property_list(&props);
bool first = true;
- for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
- if (E->get().usage & PROPERTY_USAGE_STORAGE || E->get().usage & PROPERTY_USAGE_SCRIPT_VARIABLE) {
+ for (const PropertyInfo &E : props) {
+ if (E.usage & PROPERTY_USAGE_STORAGE || E.usage & PROPERTY_USAGE_SCRIPT_VARIABLE) {
//must be serialized
if (first) {
@@ -1577,8 +1596,8 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
p_store_string_func(p_store_string_ud, ",");
}
- p_store_string_func(p_store_string_ud, "\"" + E->get().name + "\":");
- write(obj->get(E->get().name), p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud);
+ p_store_string_func(p_store_string_ud, "\"" + E.name + "\":");
+ write(obj->get(E.name), p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud);
}
}
@@ -1596,7 +1615,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
p_store_string_func(p_store_string_ud, "{\n");
for (List<Variant>::Element *E = keys.front(); E; E = E->next()) {
/*
- if (!_check_type(dict[E->get()]))
+ if (!_check_type(dict[E]))
continue;
*/
write(E->get(), p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud);
@@ -1613,7 +1632,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
} break;
case Variant::ARRAY: {
- p_store_string_func(p_store_string_ud, "[ ");
+ p_store_string_func(p_store_string_ud, "[");
Array array = p_variant;
int len = array.size();
for (int i = 0; i < len; i++) {
@@ -1622,12 +1641,12 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
}
write(array[i], p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud);
}
- p_store_string_func(p_store_string_ud, " ]");
+ p_store_string_func(p_store_string_ud, "]");
} break;
case Variant::PACKED_BYTE_ARRAY: {
- p_store_string_func(p_store_string_ud, "PackedByteArray( ");
+ p_store_string_func(p_store_string_ud, "PackedByteArray(");
String s;
Vector<uint8_t> data = p_variant;
int len = data.size();
@@ -1641,11 +1660,11 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
p_store_string_func(p_store_string_ud, itos(ptr[i]));
}
- p_store_string_func(p_store_string_ud, " )");
+ p_store_string_func(p_store_string_ud, ")");
} break;
case Variant::PACKED_INT32_ARRAY: {
- p_store_string_func(p_store_string_ud, "PackedInt32Array( ");
+ p_store_string_func(p_store_string_ud, "PackedInt32Array(");
Vector<int32_t> data = p_variant;
int32_t len = data.size();
const int32_t *ptr = data.ptr();
@@ -1658,11 +1677,11 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
p_store_string_func(p_store_string_ud, itos(ptr[i]));
}
- p_store_string_func(p_store_string_ud, " )");
+ p_store_string_func(p_store_string_ud, ")");
} break;
case Variant::PACKED_INT64_ARRAY: {
- p_store_string_func(p_store_string_ud, "PackedInt64Array( ");
+ p_store_string_func(p_store_string_ud, "PackedInt64Array(");
Vector<int64_t> data = p_variant;
int64_t len = data.size();
const int64_t *ptr = data.ptr();
@@ -1675,11 +1694,11 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
p_store_string_func(p_store_string_ud, itos(ptr[i]));
}
- p_store_string_func(p_store_string_ud, " )");
+ p_store_string_func(p_store_string_ud, ")");
} break;
case Variant::PACKED_FLOAT32_ARRAY: {
- p_store_string_func(p_store_string_ud, "PackedFloat32Array( ");
+ p_store_string_func(p_store_string_ud, "PackedFloat32Array(");
Vector<float> data = p_variant;
int len = data.size();
const float *ptr = data.ptr();
@@ -1691,11 +1710,11 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
p_store_string_func(p_store_string_ud, rtosfix(ptr[i]));
}
- p_store_string_func(p_store_string_ud, " )");
+ p_store_string_func(p_store_string_ud, ")");
} break;
case Variant::PACKED_FLOAT64_ARRAY: {
- p_store_string_func(p_store_string_ud, "PackedFloat64Array( ");
+ p_store_string_func(p_store_string_ud, "PackedFloat64Array(");
Vector<double> data = p_variant;
int len = data.size();
const double *ptr = data.ptr();
@@ -1707,11 +1726,11 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
p_store_string_func(p_store_string_ud, rtosfix(ptr[i]));
}
- p_store_string_func(p_store_string_ud, " )");
+ p_store_string_func(p_store_string_ud, ")");
} break;
case Variant::PACKED_STRING_ARRAY: {
- p_store_string_func(p_store_string_ud, "PackedStringArray( ");
+ p_store_string_func(p_store_string_ud, "PackedStringArray(");
Vector<String> data = p_variant;
int len = data.size();
const String *ptr = data.ptr();
@@ -1727,11 +1746,11 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
p_store_string_func(p_store_string_ud, "\"" + str.c_escape() + "\"");
}
- p_store_string_func(p_store_string_ud, " )");
+ p_store_string_func(p_store_string_ud, ")");
} break;
case Variant::PACKED_VECTOR2_ARRAY: {
- p_store_string_func(p_store_string_ud, "PackedVector2Array( ");
+ p_store_string_func(p_store_string_ud, "PackedVector2Array(");
Vector<Vector2> data = p_variant;
int len = data.size();
const Vector2 *ptr = data.ptr();
@@ -1743,11 +1762,11 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
p_store_string_func(p_store_string_ud, rtosfix(ptr[i].x) + ", " + rtosfix(ptr[i].y));
}
- p_store_string_func(p_store_string_ud, " )");
+ p_store_string_func(p_store_string_ud, ")");
} break;
case Variant::PACKED_VECTOR3_ARRAY: {
- p_store_string_func(p_store_string_ud, "PackedVector3Array( ");
+ p_store_string_func(p_store_string_ud, "PackedVector3Array(");
Vector<Vector3> data = p_variant;
int len = data.size();
const Vector3 *ptr = data.ptr();
@@ -1759,12 +1778,11 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
p_store_string_func(p_store_string_ud, rtosfix(ptr[i].x) + ", " + rtosfix(ptr[i].y) + ", " + rtosfix(ptr[i].z));
}
- p_store_string_func(p_store_string_ud, " )");
+ p_store_string_func(p_store_string_ud, ")");
} break;
case Variant::PACKED_COLOR_ARRAY: {
- p_store_string_func(p_store_string_ud, "PackedColorArray( ");
-
+ p_store_string_func(p_store_string_ud, "PackedColorArray(");
Vector<Color> data = p_variant;
int len = data.size();
const Color *ptr = data.ptr();
@@ -1776,7 +1794,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
p_store_string_func(p_store_string_ud, rtosfix(ptr[i].r) + ", " + rtosfix(ptr[i].g) + ", " + rtosfix(ptr[i].b) + ", " + rtosfix(ptr[i].a));
}
- p_store_string_func(p_store_string_ud, " )");
+ p_store_string_func(p_store_string_ud, ")");
} break;
default: {
diff --git a/core/variant/variant_parser.h b/core/variant/variant_parser.h
index 5703f0200c..1ba26db6ed 100644
--- a/core/variant/variant_parser.h
+++ b/core/variant/variant_parser.h
@@ -31,8 +31,8 @@
#ifndef VARIANT_PARSER_H
#define VARIANT_PARSER_H
+#include "core/io/file_access.h"
#include "core/io/resource.h"
-#include "core/os/file_access.h"
#include "core/variant/variant.h"
class VariantParser {
@@ -73,9 +73,9 @@ public:
struct ResourceParser {
void *userdata = nullptr;
- ParseResourceFunc func;
- ParseResourceFunc ext_func;
- ParseResourceFunc sub_func;
+ ParseResourceFunc func = nullptr;
+ ParseResourceFunc ext_func = nullptr;
+ ParseResourceFunc sub_func = nullptr;
};
enum TokenType {
diff --git a/core/variant/variant_setget.cpp b/core/variant/variant_setget.cpp
index 9ab8602782..ae3c7685fd 100644
--- a/core/variant/variant_setget.cpp
+++ b/core/variant/variant_setget.cpp
@@ -28,282 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "variant.h"
-
-#include "core/core_string_names.h"
-#include "core/debugger/engine_debugger.h"
-#include "core/object/class_db.h"
-#include "core/templates/local_vector.h"
-#include "core/variant/variant_internal.h"
-
-/**** NAMED SETTERS AND GETTERS ****/
-
-#define SETGET_STRUCT(m_base_type, m_member_type, m_member) \
- struct VariantSetGet_##m_base_type##_##m_member { \
- static void get(const Variant *base, Variant *member) { \
- VariantTypeAdjust<m_member_type>::adjust(member); \
- *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_member; \
- } \
- static void ptr_get(const void *base, void *member) { \
- PtrToArg<m_member_type>::encode(PtrToArg<m_base_type>::convert(base).m_member, member); \
- } \
- static void set(Variant *base, const Variant *value, bool &valid) { \
- if (value->get_type() == GetTypeInfo<m_member_type>::VARIANT_TYPE) { \
- VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_member = *VariantGetInternalPtr<m_member_type>::get_ptr(value); \
- valid = true; \
- } else { \
- valid = false; \
- } \
- } \
- static void validated_set(Variant *base, const Variant *value) { \
- VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_member = *VariantGetInternalPtr<m_member_type>::get_ptr(value); \
- } \
- static void ptr_set(void *base, const void *member) { \
- m_base_type b = PtrToArg<m_base_type>::convert(base); \
- b.m_member = PtrToArg<m_member_type>::convert(member); \
- PtrToArg<m_base_type>::encode(b, base); \
- } \
- static Variant::Type get_type() { return GetTypeInfo<m_member_type>::VARIANT_TYPE; } \
- };
-
-#define SETGET_NUMBER_STRUCT(m_base_type, m_member_type, m_member) \
- struct VariantSetGet_##m_base_type##_##m_member { \
- static void get(const Variant *base, Variant *member) { \
- VariantTypeAdjust<m_member_type>::adjust(member); \
- *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_member; \
- } \
- static void ptr_get(const void *base, void *member) { \
- PtrToArg<m_member_type>::encode(PtrToArg<m_base_type>::convert(base).m_member, member); \
- } \
- static void set(Variant *base, const Variant *value, bool &valid) { \
- if (value->get_type() == Variant::FLOAT) { \
- VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_member = *VariantGetInternalPtr<double>::get_ptr(value); \
- valid = true; \
- } else if (value->get_type() == Variant::INT) { \
- VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_member = *VariantGetInternalPtr<int64_t>::get_ptr(value); \
- valid = true; \
- } else { \
- valid = false; \
- } \
- } \
- static void validated_set(Variant *base, const Variant *value) { \
- VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_member = *VariantGetInternalPtr<m_member_type>::get_ptr(value); \
- } \
- static void ptr_set(void *base, const void *member) { \
- m_base_type b = PtrToArg<m_base_type>::convert(base); \
- b.m_member = PtrToArg<m_member_type>::convert(member); \
- PtrToArg<m_base_type>::encode(b, base); \
- } \
- static Variant::Type get_type() { return GetTypeInfo<m_member_type>::VARIANT_TYPE; } \
- };
-
-#define SETGET_STRUCT_CUSTOM(m_base_type, m_member_type, m_member, m_custom) \
- struct VariantSetGet_##m_base_type##_##m_member { \
- static void get(const Variant *base, Variant *member) { \
- VariantTypeAdjust<m_member_type>::adjust(member); \
- *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_custom; \
- } \
- static void ptr_get(const void *base, void *member) { \
- PtrToArg<m_member_type>::encode(PtrToArg<m_base_type>::convert(base).m_custom, member); \
- } \
- static void set(Variant *base, const Variant *value, bool &valid) { \
- if (value->get_type() == GetTypeInfo<m_member_type>::VARIANT_TYPE) { \
- VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_custom = *VariantGetInternalPtr<m_member_type>::get_ptr(value); \
- valid = true; \
- } else { \
- valid = false; \
- } \
- } \
- static void validated_set(Variant *base, const Variant *value) { \
- VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_custom = *VariantGetInternalPtr<m_member_type>::get_ptr(value); \
- } \
- static void ptr_set(void *base, const void *member) { \
- m_base_type b = PtrToArg<m_base_type>::convert(base); \
- b.m_custom = PtrToArg<m_member_type>::convert(member); \
- PtrToArg<m_base_type>::encode(b, base); \
- } \
- static Variant::Type get_type() { return GetTypeInfo<m_member_type>::VARIANT_TYPE; } \
- };
-
-#define SETGET_NUMBER_STRUCT_CUSTOM(m_base_type, m_member_type, m_member, m_custom) \
- struct VariantSetGet_##m_base_type##_##m_member { \
- static void get(const Variant *base, Variant *member) { \
- VariantTypeAdjust<m_member_type>::adjust(member); \
- *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_custom; \
- } \
- static void ptr_get(const void *base, void *member) { \
- PtrToArg<m_member_type>::encode(PtrToArg<m_base_type>::convert(base).m_custom, member); \
- } \
- static void set(Variant *base, const Variant *value, bool &valid) { \
- if (value->get_type() == Variant::FLOAT) { \
- VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_custom = *VariantGetInternalPtr<double>::get_ptr(value); \
- valid = true; \
- } else if (value->get_type() == Variant::INT) { \
- VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_custom = *VariantGetInternalPtr<int64_t>::get_ptr(value); \
- valid = true; \
- } else { \
- valid = false; \
- } \
- } \
- static void validated_set(Variant *base, const Variant *value) { \
- VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_custom = *VariantGetInternalPtr<m_member_type>::get_ptr(value); \
- } \
- static void ptr_set(void *base, const void *member) { \
- m_base_type b = PtrToArg<m_base_type>::convert(base); \
- b.m_custom = PtrToArg<m_member_type>::convert(member); \
- PtrToArg<m_base_type>::encode(b, base); \
- } \
- static Variant::Type get_type() { return GetTypeInfo<m_member_type>::VARIANT_TYPE; } \
- };
-
-#define SETGET_STRUCT_FUNC(m_base_type, m_member_type, m_member, m_setter, m_getter) \
- struct VariantSetGet_##m_base_type##_##m_member { \
- static void get(const Variant *base, Variant *member) { \
- VariantTypeAdjust<m_member_type>::adjust(member); \
- *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_getter(); \
- } \
- static void ptr_get(const void *base, void *member) { \
- PtrToArg<m_member_type>::encode(PtrToArg<m_base_type>::convert(base).m_getter(), member); \
- } \
- static void set(Variant *base, const Variant *value, bool &valid) { \
- if (value->get_type() == GetTypeInfo<m_member_type>::VARIANT_TYPE) { \
- VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_setter(*VariantGetInternalPtr<m_member_type>::get_ptr(value)); \
- valid = true; \
- } else { \
- valid = false; \
- } \
- } \
- static void validated_set(Variant *base, const Variant *value) { \
- VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_setter(*VariantGetInternalPtr<m_member_type>::get_ptr(value)); \
- } \
- static void ptr_set(void *base, const void *member) { \
- m_base_type b = PtrToArg<m_base_type>::convert(base); \
- b.m_setter(PtrToArg<m_member_type>::convert(member)); \
- PtrToArg<m_base_type>::encode(b, base); \
- } \
- static Variant::Type get_type() { return GetTypeInfo<m_member_type>::VARIANT_TYPE; } \
- };
-
-#define SETGET_NUMBER_STRUCT_FUNC(m_base_type, m_member_type, m_member, m_setter, m_getter) \
- struct VariantSetGet_##m_base_type##_##m_member { \
- static void get(const Variant *base, Variant *member) { \
- VariantTypeAdjust<m_member_type>::adjust(member); \
- *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_getter(); \
- } \
- static void ptr_get(const void *base, void *member) { \
- PtrToArg<m_member_type>::encode(PtrToArg<m_base_type>::convert(base).m_getter(), member); \
- } \
- static void set(Variant *base, const Variant *value, bool &valid) { \
- if (value->get_type() == Variant::FLOAT) { \
- VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_setter(*VariantGetInternalPtr<double>::get_ptr(value)); \
- valid = true; \
- } else if (value->get_type() == Variant::INT) { \
- VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_setter(*VariantGetInternalPtr<int64_t>::get_ptr(value)); \
- valid = true; \
- } else { \
- valid = false; \
- } \
- } \
- static void validated_set(Variant *base, const Variant *value) { \
- VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_setter(*VariantGetInternalPtr<m_member_type>::get_ptr(value)); \
- } \
- static void ptr_set(void *base, const void *member) { \
- m_base_type b = PtrToArg<m_base_type>::convert(base); \
- b.m_setter(PtrToArg<m_member_type>::convert(member)); \
- PtrToArg<m_base_type>::encode(b, base); \
- } \
- static Variant::Type get_type() { return GetTypeInfo<m_member_type>::VARIANT_TYPE; } \
- };
-
-#define SETGET_STRUCT_FUNC_INDEX(m_base_type, m_member_type, m_member, m_setter, m_getter, m_index) \
- struct VariantSetGet_##m_base_type##_##m_member { \
- static void get(const Variant *base, Variant *member) { \
- VariantTypeAdjust<m_member_type>::adjust(member); \
- *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_getter(m_index); \
- } \
- static void ptr_get(const void *base, void *member) { \
- PtrToArg<m_member_type>::encode(PtrToArg<m_base_type>::convert(base).m_getter(m_index), member); \
- } \
- static void set(Variant *base, const Variant *value, bool &valid) { \
- if (value->get_type() == GetTypeInfo<m_member_type>::VARIANT_TYPE) { \
- VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_setter(m_index, *VariantGetInternalPtr<m_member_type>::get_ptr(value)); \
- valid = true; \
- } else { \
- valid = false; \
- } \
- } \
- static void validated_set(Variant *base, const Variant *value) { \
- VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_setter(m_index, *VariantGetInternalPtr<m_member_type>::get_ptr(value)); \
- } \
- static void ptr_set(void *base, const void *member) { \
- m_base_type b = PtrToArg<m_base_type>::convert(base); \
- b.m_setter(m_index, PtrToArg<m_member_type>::convert(member)); \
- PtrToArg<m_base_type>::encode(b, base); \
- } \
- static Variant::Type get_type() { return GetTypeInfo<m_member_type>::VARIANT_TYPE; } \
- };
-
-SETGET_NUMBER_STRUCT(Vector2, double, x)
-SETGET_NUMBER_STRUCT(Vector2, double, y)
-
-SETGET_NUMBER_STRUCT(Vector2i, int64_t, x)
-SETGET_NUMBER_STRUCT(Vector2i, int64_t, y)
-
-SETGET_NUMBER_STRUCT(Vector3, double, x)
-SETGET_NUMBER_STRUCT(Vector3, double, y)
-SETGET_NUMBER_STRUCT(Vector3, double, z)
-
-SETGET_NUMBER_STRUCT(Vector3i, int64_t, x)
-SETGET_NUMBER_STRUCT(Vector3i, int64_t, y)
-SETGET_NUMBER_STRUCT(Vector3i, int64_t, z)
-
-SETGET_STRUCT(Rect2, Vector2, position)
-SETGET_STRUCT(Rect2, Vector2, size)
-SETGET_STRUCT_FUNC(Rect2, Vector2, end, set_end, get_end)
-
-SETGET_STRUCT(Rect2i, Vector2i, position)
-SETGET_STRUCT(Rect2i, Vector2i, size)
-SETGET_STRUCT_FUNC(Rect2i, Vector2i, end, set_end, get_end)
-
-SETGET_STRUCT(AABB, Vector3, position)
-SETGET_STRUCT(AABB, Vector3, size)
-SETGET_STRUCT_FUNC(AABB, Vector3, end, set_end, get_end)
-
-SETGET_STRUCT_CUSTOM(Transform2D, Vector2, x, elements[0])
-SETGET_STRUCT_CUSTOM(Transform2D, Vector2, y, elements[1])
-SETGET_STRUCT_CUSTOM(Transform2D, Vector2, origin, elements[2])
-
-SETGET_NUMBER_STRUCT_CUSTOM(Plane, double, x, normal.x)
-SETGET_NUMBER_STRUCT_CUSTOM(Plane, double, y, normal.y)
-SETGET_NUMBER_STRUCT_CUSTOM(Plane, double, z, normal.z)
-SETGET_STRUCT(Plane, Vector3, normal)
-SETGET_NUMBER_STRUCT(Plane, double, d)
-
-SETGET_NUMBER_STRUCT(Quat, double, x)
-SETGET_NUMBER_STRUCT(Quat, double, y)
-SETGET_NUMBER_STRUCT(Quat, double, z)
-SETGET_NUMBER_STRUCT(Quat, 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(Transform, Basis, basis)
-SETGET_STRUCT(Transform, 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();
@@ -374,17 +99,17 @@ void register_named_setters_getters() {
REGISTER_MEMBER(Plane, d);
REGISTER_MEMBER(Plane, normal);
- REGISTER_MEMBER(Quat, x);
- REGISTER_MEMBER(Quat, y);
- REGISTER_MEMBER(Quat, z);
- REGISTER_MEMBER(Quat, w);
+ REGISTER_MEMBER(Quaternion, x);
+ REGISTER_MEMBER(Quaternion, y);
+ REGISTER_MEMBER(Quaternion, z);
+ REGISTER_MEMBER(Quaternion, w);
REGISTER_MEMBER(Basis, x);
REGISTER_MEMBER(Basis, y);
REGISTER_MEMBER(Basis, z);
- REGISTER_MEMBER(Transform, basis);
- REGISTER_MEMBER(Transform, origin);
+ REGISTER_MEMBER(Transform3D, basis);
+ REGISTER_MEMBER(Transform3D, origin);
REGISTER_MEMBER(Color, r);
REGISTER_MEMBER(Color, g);
@@ -975,7 +700,7 @@ INDEXED_SETGET_STRUCT_BULTIN_NUMERIC(Vector2, double, real_t, 2)
INDEXED_SETGET_STRUCT_BULTIN_NUMERIC(Vector2i, int64_t, int32_t, 2)
INDEXED_SETGET_STRUCT_BULTIN_NUMERIC(Vector3, double, real_t, 3)
INDEXED_SETGET_STRUCT_BULTIN_NUMERIC(Vector3i, int64_t, int32_t, 3)
-INDEXED_SETGET_STRUCT_BULTIN_NUMERIC(Quat, double, real_t, 4)
+INDEXED_SETGET_STRUCT_BULTIN_NUMERIC(Quaternion, double, real_t, 4)
INDEXED_SETGET_STRUCT_BULTIN_NUMERIC(Color, double, float, 4)
INDEXED_SETGET_STRUCT_BULTIN_ACCESSOR(Transform2D, Vector2, .elements, 3)
@@ -1037,7 +762,7 @@ void register_indexed_setters_getters() {
REGISTER_INDEXED_MEMBER(Vector2i);
REGISTER_INDEXED_MEMBER(Vector3);
REGISTER_INDEXED_MEMBER(Vector3i);
- REGISTER_INDEXED_MEMBER(Quat);
+ REGISTER_INDEXED_MEMBER(Quaternion);
REGISTER_INDEXED_MEMBER(Color);
REGISTER_INDEXED_MEMBER(Transform2D);
REGISTER_INDEXED_MEMBER(Basis);
@@ -1146,7 +871,7 @@ struct VariantKeyedSetGetDictionary {
*r_valid = true;
return VariantGetInternalPtr<Dictionary>::get_ptr(base)->has(*key);
}
- static bool ptr_has(const void *base, const void *key) {
+ static uint32_t ptr_has(const void *base, const void *key) {
/* avoid ptrconvert for performance*/
const Dictionary &v = *reinterpret_cast<const Dictionary *>(base);
return v.has(PtrToArg<Variant>::convert(key));
@@ -1196,7 +921,7 @@ struct VariantKeyedSetGetObject {
obj->getvar(*key, &exists);
return exists;
}
- static bool ptr_has(const void *base, const void *key) {
+ static uint32_t ptr_has(const void *base, const void *key) {
const Object *obj = PtrToArg<Object *>::convert(base);
ERR_FAIL_COND_V(!obj, false);
bool valid;
@@ -1368,9 +1093,9 @@ void Variant::get_property_list(List<PropertyInfo> *p_list) const {
const Dictionary *dic = reinterpret_cast<const Dictionary *>(_data._mem);
List<Variant> keys;
dic->get_key_list(&keys);
- for (List<Variant>::Element *E = keys.front(); E; E = E->next()) {
- if (E->get().get_type() == Variant::STRING) {
- p_list->push_back(PropertyInfo(Variant::STRING, E->get()));
+ for (const Variant &E : keys) {
+ if (E.get_type() == Variant::STRING) {
+ p_list->push_back(PropertyInfo(Variant::STRING, E));
}
}
} else if (type == OBJECT) {
@@ -1381,10 +1106,10 @@ void Variant::get_property_list(List<PropertyInfo> *p_list) const {
} else {
List<StringName> members;
get_member_list(type, &members);
- for (List<StringName>::Element *E = members.front(); E; E = E->next()) {
+ for (const StringName &E : members) {
PropertyInfo pi;
- pi.name = E->get();
- pi.type = get_member_type(type, E->get());
+ pi.name = E;
+ pi.type = get_member_type(type, E);
p_list->push_back(pi);
}
}
@@ -1453,7 +1178,7 @@ bool Variant::iter_init(Variant &r_iter, bool &valid) const {
#ifdef DEBUG_ENABLED
- if (EngineDebugger::is_active() && !_get_obj().id.is_reference() && ObjectDB::get_instance(_get_obj().id) == nullptr) {
+ if (EngineDebugger::is_active() && !_get_obj().id.is_ref_counted() && ObjectDB::get_instance(_get_obj().id) == nullptr) {
valid = false;
return false;
}
@@ -1680,7 +1405,7 @@ bool Variant::iter_next(Variant &r_iter, bool &valid) const {
#ifdef DEBUG_ENABLED
- if (EngineDebugger::is_active() && !_get_obj().id.is_reference() && ObjectDB::get_instance(_get_obj().id) == nullptr) {
+ if (EngineDebugger::is_active() && !_get_obj().id.is_ref_counted() && ObjectDB::get_instance(_get_obj().id) == nullptr) {
valid = false;
return false;
}
@@ -1865,7 +1590,7 @@ Variant Variant::iter_get(const Variant &r_iter, bool &r_valid) const {
return Variant();
}
#ifdef DEBUG_ENABLED
- if (EngineDebugger::is_active() && !_get_obj().id.is_reference() && ObjectDB::get_instance(_get_obj().id) == nullptr) {
+ if (EngineDebugger::is_active() && !_get_obj().id.is_ref_counted() && ObjectDB::get_instance(_get_obj().id) == nullptr) {
r_valid = false;
return Variant();
}
@@ -2135,10 +1860,10 @@ void Variant::blend(const Variant &a, const Variant &b, float c, Variant &r_dst)
r_dst = ::AABB(ra->position + rb->position * c, ra->size + rb->size * c);
}
return;
- case QUAT: {
- Quat empty_rot;
- const Quat *qa = reinterpret_cast<const Quat *>(a._data._mem);
- const Quat *qb = reinterpret_cast<const Quat *>(b._data._mem);
+ case QUATERNION: {
+ Quaternion empty_rot;
+ const Quaternion *qa = reinterpret_cast<const Quaternion *>(a._data._mem);
+ const Quaternion *qb = reinterpret_cast<const Quaternion *>(b._data._mem);
r_dst = *qa * empty_rot.slerp(*qb, c);
}
return;
@@ -2295,8 +2020,8 @@ void Variant::interpolate(const Variant &a, const Variant &b, float c, Variant &
r_dst = a;
}
return;
- case QUAT: {
- r_dst = reinterpret_cast<const Quat *>(a._data._mem)->slerp(*reinterpret_cast<const Quat *>(b._data._mem), c);
+ case QUATERNION: {
+ r_dst = reinterpret_cast<const Quaternion *>(a._data._mem)->slerp(*reinterpret_cast<const Quaternion *>(b._data._mem), c);
}
return;
case AABB: {
@@ -2304,11 +2029,11 @@ void Variant::interpolate(const Variant &a, const Variant &b, float c, Variant &
}
return;
case BASIS: {
- r_dst = Transform(*a._data._basis).interpolate_with(Transform(*b._data._basis), c).basis;
+ r_dst = Transform3D(*a._data._basis).interpolate_with(Transform3D(*b._data._basis), c).basis;
}
return;
- case TRANSFORM: {
- r_dst = a._data._transform->interpolate_with(*b._data._transform, c);
+ case TRANSFORM3D: {
+ r_dst = a._data._transform3d->interpolate_with(*b._data._transform3d, c);
}
return;
case COLOR: {
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 553f2b23a2..6c57d1de10 100644
--- a/core/variant/variant_utility.cpp
+++ b/core/variant/variant_utility.cpp
@@ -32,7 +32,7 @@
#include "core/core_string_names.h"
#include "core/io/marshalls.h"
-#include "core/object/reference.h"
+#include "core/object/ref_counted.h"
#include "core/os/os.h"
#include "core/templates/oa_hash_map.h"
#include "core/variant/binder_common.h"
@@ -249,10 +249,6 @@ struct VariantUtilityFunctions {
return Math::move_toward(from, to, delta);
}
- static inline double dectime(double value, double amount, double step) {
- return Math::dectime(value, amount, step);
- }
-
static inline double deg2rad(double angle_deg) {
return Math::deg2rad(angle_deg);
}
@@ -488,6 +484,14 @@ struct VariantUtilityFunctions {
return str;
}
+ static inline String error_string(Error error) {
+ if (error < 0 || error >= ERR_MAX) {
+ return String("(invalid error code)");
+ }
+
+ return String(error_names[error]);
+ }
+
static inline void print(const Variant **p_args, int p_arg_count, Callable::CallError &r_error) {
if (p_arg_count < 1) {
r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
@@ -1195,7 +1199,6 @@ void Variant::_register_variant_utility_functions() {
FUNCBINDR(smoothstep, sarray("from", "to", "x"), Variant::UTILITY_FUNC_TYPE_MATH);
FUNCBINDR(move_toward, sarray("from", "to", "delta"), Variant::UTILITY_FUNC_TYPE_MATH);
- FUNCBINDR(dectime, sarray("value", "amount", "step"), Variant::UTILITY_FUNC_TYPE_MATH);
FUNCBINDR(deg2rad, sarray("deg"), Variant::UTILITY_FUNC_TYPE_MATH);
FUNCBINDR(rad2deg, sarray("rad"), Variant::UTILITY_FUNC_TYPE_MATH);
@@ -1239,6 +1242,7 @@ void Variant::_register_variant_utility_functions() {
FUNCBINDVR(weakref, sarray("obj"), Variant::UTILITY_FUNC_TYPE_GENERAL);
FUNCBINDR(_typeof, sarray("variable"), Variant::UTILITY_FUNC_TYPE_GENERAL);
FUNCBINDVARARGS(str, sarray(), Variant::UTILITY_FUNC_TYPE_GENERAL);
+ FUNCBINDR(error_string, sarray("error"), Variant::UTILITY_FUNC_TYPE_GENERAL);
FUNCBINDVARARGV(print, sarray(), Variant::UTILITY_FUNC_TYPE_GENERAL);
FUNCBINDVARARGV(printerr, sarray(), Variant::UTILITY_FUNC_TYPE_GENERAL);
FUNCBINDVARARGV(printt, sarray(), Variant::UTILITY_FUNC_TYPE_GENERAL);
@@ -1348,8 +1352,8 @@ String Variant::get_utility_function_argument_name(const StringName &p_name, int
if (!bfi) {
return String();
}
- ERR_FAIL_COND_V(bfi->is_vararg, String());
ERR_FAIL_INDEX_V(p_arg, bfi->argnames.size(), String());
+ ERR_FAIL_COND_V(bfi->is_vararg, String());
return bfi->argnames[p_arg];
}
@@ -1379,9 +1383,26 @@ bool Variant::is_utility_function_vararg(const StringName &p_name) {
return bfi->is_vararg;
}
+uint32_t Variant::get_utility_function_hash(const StringName &p_name) {
+ const VariantUtilityFunctionInfo *bfi = utility_function_table.lookup_ptr(p_name);
+ ERR_FAIL_COND_V(!bfi, 0);
+
+ uint32_t hash = hash_djb2_one_32(bfi->is_vararg);
+ hash = hash_djb2_one_32(bfi->returns_value, hash);
+ if (bfi->returns_value) {
+ hash = hash_djb2_one_32(bfi->return_type, hash);
+ }
+ hash = hash_djb2_one_32(bfi->argcount, hash);
+ for (int i = 0; i < bfi->argcount; i++) {
+ hash = hash_djb2_one_32(bfi->get_arg_type(i), hash);
+ }
+
+ return hash;
+}
+
void Variant::get_utility_function_list(List<StringName> *r_functions) {
- for (List<StringName>::Element *E = utility_function_name_table.front(); E; E = E->next()) {
- r_functions->push_back(E->get());
+ for (const StringName &E : utility_function_name_table) {
+ r_functions->push_back(E);
}
}