diff options
Diffstat (limited to 'core/variant/variant.cpp')
-rw-r--r-- | core/variant/variant.cpp | 809 |
1 files changed, 543 insertions, 266 deletions
diff --git a/core/variant/variant.cpp b/core/variant/variant.cpp index 81428caca1..a5bc6c229d 100644 --- a/core/variant/variant.cpp +++ b/core/variant/variant.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 */ @@ -38,8 +38,10 @@ #include "core/math/math_funcs.h" #include "core/string/print_string.h" #include "core/variant/variant_parser.h" -#include "scene/gui/control.h" -#include "scene/main/node.h" + +PagedAllocator<Variant::Pools::BucketSmall, true> Variant::Pools::_bucket_small; +PagedAllocator<Variant::Pools::BucketMedium, true> Variant::Pools::_bucket_medium; +PagedAllocator<Variant::Pools::BucketLarge, true> Variant::Pools::_bucket_large; String Variant::get_type_name(Variant::Type p_type) { switch (p_type) { @@ -85,6 +87,12 @@ String Variant::get_type_name(Variant::Type p_type) { case VECTOR3I: { return "Vector3i"; } break; + case VECTOR4: { + return "Vector4"; + } break; + case VECTOR4I: { + return "Vector4i"; + } break; case PLANE: { return "Plane"; @@ -104,6 +112,10 @@ String Variant::get_type_name(Variant::Type p_type) { return "Transform3D"; } break; + case PROJECTION: { + return "Projection"; + + } break; // misc types case COLOR: { @@ -186,7 +198,7 @@ bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) { if (p_type_from == p_type_to) { return true; } - if (p_type_to == NIL && p_type_from != NIL) { //nil can convert to anything + if (p_type_to == NIL) { //nil can convert to anything return true; } @@ -300,6 +312,24 @@ bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) { valid_types = valid; } break; + case VECTOR4: { + static const Type valid[] = { + VECTOR4I, + NIL, + }; + + valid_types = valid; + + } break; + case VECTOR4I: { + static const Type valid[] = { + VECTOR4, + NIL, + }; + + valid_types = valid; + + } break; case QUATERNION: { static const Type valid[] = { @@ -324,6 +354,16 @@ bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) { TRANSFORM2D, QUATERNION, BASIS, + PROJECTION, + NIL + }; + + valid_types = valid; + + } break; + case PROJECTION: { + static const Type valid[] = { + TRANSFORM3D, NIL }; @@ -492,7 +532,7 @@ bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type if (p_type_from == p_type_to) { return true; } - if (p_type_to == NIL && p_type_from != NIL) { //nil can convert to anything + if (p_type_to == NIL) { //nil can convert to anything return true; } @@ -606,6 +646,24 @@ bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type valid_types = valid; } break; + case VECTOR4: { + static const Type valid[] = { + VECTOR4I, + NIL, + }; + + valid_types = valid; + + } break; + case VECTOR4I: { + static const Type valid[] = { + VECTOR4, + NIL, + }; + + valid_types = valid; + + } break; case QUATERNION: { static const Type valid[] = { @@ -630,6 +688,16 @@ bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type TRANSFORM2D, QUATERNION, BASIS, + PROJECTION, + NIL + }; + + valid_types = valid; + + } break; + case PROJECTION: { + static const Type valid[] = { + TRANSFORM3D, NIL }; @@ -784,16 +852,11 @@ bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type } bool Variant::operator==(const Variant &p_variant) const { - if (type != p_variant.type) { //evaluation of operator== needs to be more strict - return false; - } - bool v; - Variant r; - evaluate(OP_EQUAL, *this, p_variant, r, v); - return r; + return hash_compare(p_variant); } bool Variant::operator!=(const Variant &p_variant) const { + // Don't use `!hash_compare(p_variant)` given it makes use of OP_EQUAL if (type != p_variant.type) { //evaluation of operator== needs to be more strict return true; } @@ -865,6 +928,14 @@ bool Variant::is_zero() const { return *reinterpret_cast<const Vector3i *>(_data._mem) == Vector3i(); } break; + case VECTOR4: { + return *reinterpret_cast<const Vector4 *>(_data._mem) == Vector4(); + + } break; + case VECTOR4I: { + return *reinterpret_cast<const Vector4i *>(_data._mem) == Vector4i(); + + } break; case PLANE: { return *reinterpret_cast<const Plane *>(_data._mem) == Plane(); @@ -884,6 +955,10 @@ bool Variant::is_zero() const { return *_data._transform3d == Transform3D(); } break; + case PROJECTION: { + return *_data._projection == Projection(); + + } break; // misc types case COLOR: { @@ -1005,6 +1080,14 @@ bool Variant::is_one() const { return *reinterpret_cast<const Vector3i *>(_data._mem) == Vector3i(1, 1, 1); } break; + case VECTOR4: { + return *reinterpret_cast<const Vector4 *>(_data._mem) == Vector4(1, 1, 1, 1); + + } break; + case VECTOR4I: { + return *reinterpret_cast<const Vector4i *>(_data._mem) == Vector4i(1, 1, 1, 1); + + } break; case PLANE: { return *reinterpret_cast<const Plane *>(_data._mem) == Plane(1, 1, 1, 1); @@ -1030,6 +1113,13 @@ bool Variant::is_null() const { } } +bool Variant::initialize_ref(Object *p_object) { + RefCounted *ref_counted = const_cast<RefCounted *>(static_cast<const RefCounted *>(p_object)); + if (!ref_counted->init_ref()) { + return false; + } + return true; +} void Variant::reference(const Variant &p_variant) { switch (type) { case NIL: @@ -1076,7 +1166,8 @@ void Variant::reference(const Variant &p_variant) { memnew_placement(_data._mem, Rect2i(*reinterpret_cast<const Rect2i *>(p_variant._data._mem))); } break; case TRANSFORM2D: { - _data._transform2d = memnew(Transform2D(*p_variant._data._transform2d)); + _data._transform2d = (Transform2D *)Pools::_bucket_small.alloc(); + memnew_placement(_data._transform2d, Transform2D(*p_variant._data._transform2d)); } break; case VECTOR3: { memnew_placement(_data._mem, Vector3(*reinterpret_cast<const Vector3 *>(p_variant._data._mem))); @@ -1084,23 +1175,33 @@ void Variant::reference(const Variant &p_variant) { case VECTOR3I: { memnew_placement(_data._mem, Vector3i(*reinterpret_cast<const Vector3i *>(p_variant._data._mem))); } break; + case VECTOR4: { + memnew_placement(_data._mem, Vector4(*reinterpret_cast<const Vector4 *>(p_variant._data._mem))); + } break; + case VECTOR4I: { + memnew_placement(_data._mem, Vector4i(*reinterpret_cast<const Vector4i *>(p_variant._data._mem))); + } break; case PLANE: { memnew_placement(_data._mem, Plane(*reinterpret_cast<const Plane *>(p_variant._data._mem))); } break; - case AABB: { - _data._aabb = memnew(::AABB(*p_variant._data._aabb)); + _data._aabb = (::AABB *)Pools::_bucket_small.alloc(); + memnew_placement(_data._aabb, ::AABB(*p_variant._data._aabb)); } break; 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)); - + _data._basis = (Basis *)Pools::_bucket_medium.alloc(); + memnew_placement(_data._basis, Basis(*p_variant._data._basis)); } break; case TRANSFORM3D: { - _data._transform3d = memnew(Transform3D(*p_variant._data._transform3d)); + _data._transform3d = (Transform3D *)Pools::_bucket_medium.alloc(); + memnew_placement(_data._transform3d, Transform3D(*p_variant._data._transform3d)); + } break; + case PROJECTION: { + _data._projection = (Projection *)Pools::_bucket_large.alloc(); + memnew_placement(_data._projection, Projection(*p_variant._data._projection)); } break; // misc types @@ -1250,6 +1351,12 @@ void Variant::zero() { case VECTOR3I: *reinterpret_cast<Vector3i *>(this->_data._mem) = Vector3i(); break; + case VECTOR4: + *reinterpret_cast<Vector4 *>(this->_data._mem) = Vector4(); + break; + case VECTOR4I: + *reinterpret_cast<Vector4i *>(this->_data._mem) = Vector4i(); + break; case PLANE: *reinterpret_cast<Plane *>(this->_data._mem) = Plane(); break; @@ -1280,18 +1387,40 @@ void Variant::_clear_internal() { RECT2 */ case TRANSFORM2D: { - memdelete(_data._transform2d); + if (_data._transform2d) { + _data._transform2d->~Transform2D(); + Pools::_bucket_small.free((Pools::BucketSmall *)_data._transform2d); + _data._transform2d = nullptr; + } } break; case AABB: { - memdelete(_data._aabb); + if (_data._aabb) { + _data._aabb->~AABB(); + Pools::_bucket_small.free((Pools::BucketSmall *)_data._aabb); + _data._aabb = nullptr; + } } break; case BASIS: { - memdelete(_data._basis); + if (_data._basis) { + _data._basis->~Basis(); + Pools::_bucket_medium.free((Pools::BucketMedium *)_data._basis); + _data._basis = nullptr; + } } break; case TRANSFORM3D: { - memdelete(_data._transform3d); + if (_data._transform3d) { + _data._transform3d->~Transform3D(); + Pools::_bucket_medium.free((Pools::BucketMedium *)_data._transform3d); + _data._transform3d = nullptr; + } + } break; + case PROJECTION: { + if (_data._projection) { + _data._projection->~Projection(); + Pools::_bucket_large.free((Pools::BucketLarge *)_data._projection); + _data._projection = nullptr; + } } break; - // misc types case STRING_NAME: { reinterpret_cast<StringName *>(_data._mem)->~StringName(); @@ -1617,25 +1746,45 @@ struct _VariantStrPair { }; Variant::operator String() const { - List<const void *> stack; + return stringify(0); +} + +String stringify_variant_clean(const Variant p_variant, int recursion_count) { + String s = p_variant.stringify(recursion_count); + + // Wrap strings in quotes to avoid ambiguity. + switch (p_variant.get_type()) { + case Variant::STRING: { + s = s.c_escape().quote(); + } break; + case Variant::STRING_NAME: { + s = "&" + s.c_escape().quote(); + } break; + case Variant::NODE_PATH: { + s = "^" + s.c_escape().quote(); + } break; + default: { + } break; + } - return stringify(stack); + return s; } template <class T> -String stringify_vector(const T &vec, List<const void *> &stack) { +String stringify_vector(const T &vec, int recursion_count) { String str("["); for (int i = 0; i < vec.size(); i++) { if (i > 0) { str += ", "; } - str = str + Variant(vec[i]).stringify(stack); + + str += stringify_variant_clean(vec[i], recursion_count); } str += "]"; return str; } -String Variant::stringify(List<const void *> &stack) const { +String Variant::stringify(int recursion_count) const { switch (type) { case NIL: return "null"; @@ -1661,6 +1810,10 @@ String Variant::stringify(List<const void *> &stack) const { return operator Vector3(); case VECTOR3I: return operator Vector3i(); + case VECTOR4: + return operator Vector4(); + case VECTOR4I: + return operator Vector4i(); case PLANE: return operator Plane(); case AABB: @@ -1671,6 +1824,8 @@ String Variant::stringify(List<const void *> &stack) const { return operator Basis(); case TRANSFORM3D: return operator Transform3D(); + case PROJECTION: + return operator Projection(); case STRING_NAME: return operator StringName(); case NODE_PATH: @@ -1679,29 +1834,26 @@ String Variant::stringify(List<const void *> &stack) const { return operator Color(); case DICTIONARY: { const Dictionary &d = *reinterpret_cast<const Dictionary *>(_data._mem); - if (stack.find(d.id())) { + if (recursion_count > MAX_RECURSION) { + ERR_PRINT("Max recursion reached"); return "{...}"; } - stack.push_back(d.id()); - - //const String *K=nullptr; String str("{"); List<Variant> keys; d.get_key_list(&keys); Vector<_VariantStrPair> pairs; - for (const Variant &E : keys) { + recursion_count++; + for (List<Variant>::Element *E = keys.front(); E; E = E->next()) { _VariantStrPair sp; - sp.key = E.stringify(stack); - sp.value = d[E].stringify(stack); + sp.key = stringify_variant_clean(E->get(), recursion_count); + sp.value = stringify_variant_clean(d[E->get()], recursion_count); pairs.push_back(sp); } - pairs.sort(); - for (int i = 0; i < pairs.size(); i++) { if (i > 0) { str += ", "; @@ -1710,47 +1862,43 @@ String Variant::stringify(List<const void *> &stack) const { } str += "}"; - stack.erase(d.id()); return str; } break; case PACKED_VECTOR2_ARRAY: { - return stringify_vector(operator Vector<Vector2>(), stack); + return stringify_vector(operator Vector<Vector2>(), recursion_count); } break; case PACKED_VECTOR3_ARRAY: { - return stringify_vector(operator Vector<Vector3>(), stack); + return stringify_vector(operator Vector<Vector3>(), recursion_count); } break; case PACKED_COLOR_ARRAY: { - return stringify_vector(operator Vector<Color>(), stack); + return stringify_vector(operator Vector<Color>(), recursion_count); } break; case PACKED_STRING_ARRAY: { - return stringify_vector(operator Vector<String>(), stack); + return stringify_vector(operator Vector<String>(), recursion_count); } break; case PACKED_BYTE_ARRAY: { - return stringify_vector(operator Vector<uint8_t>(), stack); + return stringify_vector(operator Vector<uint8_t>(), recursion_count); } break; case PACKED_INT32_ARRAY: { - return stringify_vector(operator Vector<int32_t>(), stack); + return stringify_vector(operator Vector<int32_t>(), recursion_count); } break; case PACKED_INT64_ARRAY: { - return stringify_vector(operator Vector<int64_t>(), stack); + return stringify_vector(operator Vector<int64_t>(), recursion_count); } break; case PACKED_FLOAT32_ARRAY: { - return stringify_vector(operator Vector<float>(), stack); + return stringify_vector(operator Vector<float>(), recursion_count); } break; case PACKED_FLOAT64_ARRAY: { - return stringify_vector(operator Vector<double>(), stack); + return stringify_vector(operator Vector<double>(), recursion_count); } break; case ARRAY: { Array arr = operator Array(); - if (stack.find(arr.id())) { + if (recursion_count > MAX_RECURSION) { + ERR_PRINT("Max recursion reached"); return "[...]"; } - stack.push_back(arr.id()); - - String str = stringify_vector(arr, stack); - stack.erase(arr.id()); - return str; + return stringify_vector(arr, recursion_count); } break; case OBJECT: { @@ -1799,6 +1947,10 @@ Variant::operator Vector2() const { return Vector2(reinterpret_cast<const Vector3 *>(_data._mem)->x, reinterpret_cast<const Vector3 *>(_data._mem)->y); } else if (type == VECTOR3I) { return Vector2(reinterpret_cast<const Vector3i *>(_data._mem)->x, reinterpret_cast<const Vector3i *>(_data._mem)->y); + } else if (type == VECTOR4) { + return Vector2(reinterpret_cast<const Vector4 *>(_data._mem)->x, reinterpret_cast<const Vector4 *>(_data._mem)->y); + } else if (type == VECTOR4I) { + return Vector2(reinterpret_cast<const Vector4i *>(_data._mem)->x, reinterpret_cast<const Vector4i *>(_data._mem)->y); } else { return Vector2(); } @@ -1813,6 +1965,10 @@ Variant::operator Vector2i() const { return Vector2(reinterpret_cast<const Vector3 *>(_data._mem)->x, reinterpret_cast<const Vector3 *>(_data._mem)->y); } else if (type == VECTOR3I) { return Vector2(reinterpret_cast<const Vector3i *>(_data._mem)->x, reinterpret_cast<const Vector3i *>(_data._mem)->y); + } else if (type == VECTOR4) { + return Vector2(reinterpret_cast<const Vector4 *>(_data._mem)->x, reinterpret_cast<const Vector4 *>(_data._mem)->y); + } else if (type == VECTOR4I) { + return Vector2(reinterpret_cast<const Vector4i *>(_data._mem)->x, reinterpret_cast<const Vector4i *>(_data._mem)->y); } else { return Vector2i(); } @@ -1847,6 +2003,10 @@ Variant::operator Vector3() const { return Vector3(reinterpret_cast<const Vector2 *>(_data._mem)->x, reinterpret_cast<const Vector2 *>(_data._mem)->y, 0.0); } else if (type == VECTOR2I) { return Vector3(reinterpret_cast<const Vector2i *>(_data._mem)->x, reinterpret_cast<const Vector2i *>(_data._mem)->y, 0.0); + } else if (type == VECTOR4) { + return Vector3(reinterpret_cast<const Vector4 *>(_data._mem)->x, reinterpret_cast<const Vector4 *>(_data._mem)->y, reinterpret_cast<const Vector4 *>(_data._mem)->z); + } else if (type == VECTOR4I) { + return Vector3(reinterpret_cast<const Vector4i *>(_data._mem)->x, reinterpret_cast<const Vector4i *>(_data._mem)->y, reinterpret_cast<const Vector4i *>(_data._mem)->z); } else { return Vector3(); } @@ -1861,11 +2021,52 @@ Variant::operator Vector3i() const { return Vector3i(reinterpret_cast<const Vector2 *>(_data._mem)->x, reinterpret_cast<const Vector2 *>(_data._mem)->y, 0.0); } else if (type == VECTOR2I) { return Vector3i(reinterpret_cast<const Vector2i *>(_data._mem)->x, reinterpret_cast<const Vector2i *>(_data._mem)->y, 0.0); + } else if (type == VECTOR4) { + return Vector3i(reinterpret_cast<const Vector4 *>(_data._mem)->x, reinterpret_cast<const Vector4 *>(_data._mem)->y, reinterpret_cast<const Vector4 *>(_data._mem)->z); + } else if (type == VECTOR4I) { + return Vector3i(reinterpret_cast<const Vector4i *>(_data._mem)->x, reinterpret_cast<const Vector4i *>(_data._mem)->y, reinterpret_cast<const Vector4i *>(_data._mem)->z); } else { return Vector3i(); } } +Variant::operator Vector4() const { + if (type == VECTOR4) { + return *reinterpret_cast<const Vector4 *>(_data._mem); + } else if (type == VECTOR4I) { + return *reinterpret_cast<const Vector4i *>(_data._mem); + } else if (type == VECTOR2) { + return Vector4(reinterpret_cast<const Vector2 *>(_data._mem)->x, reinterpret_cast<const Vector2 *>(_data._mem)->y, 0.0, 0.0); + } else if (type == VECTOR2I) { + return Vector4(reinterpret_cast<const Vector2i *>(_data._mem)->x, reinterpret_cast<const Vector2i *>(_data._mem)->y, 0.0, 0.0); + } else if (type == VECTOR3) { + return Vector4(reinterpret_cast<const Vector3 *>(_data._mem)->x, reinterpret_cast<const Vector3 *>(_data._mem)->y, reinterpret_cast<const Vector3 *>(_data._mem)->z, 0.0); + } else if (type == VECTOR3I) { + return Vector4(reinterpret_cast<const Vector3i *>(_data._mem)->x, reinterpret_cast<const Vector3i *>(_data._mem)->y, reinterpret_cast<const Vector3i *>(_data._mem)->z, 0.0); + } else { + return Vector4(); + } +} + +Variant::operator Vector4i() const { + if (type == VECTOR4I) { + return *reinterpret_cast<const Vector4i *>(_data._mem); + } else if (type == VECTOR4) { + const Vector4 &v4 = *reinterpret_cast<const Vector4 *>(_data._mem); + return Vector4i(v4.x, v4.y, v4.z, v4.w); + } else if (type == VECTOR2) { + return Vector4i(reinterpret_cast<const Vector2 *>(_data._mem)->x, reinterpret_cast<const Vector2 *>(_data._mem)->y, 0.0, 0.0); + } else if (type == VECTOR2I) { + return Vector4i(reinterpret_cast<const Vector2i *>(_data._mem)->x, reinterpret_cast<const Vector2i *>(_data._mem)->y, 0.0, 0.0); + } else if (type == VECTOR3) { + return Vector4i(reinterpret_cast<const Vector3 *>(_data._mem)->x, reinterpret_cast<const Vector3 *>(_data._mem)->y, reinterpret_cast<const Vector3 *>(_data._mem)->z, 0.0); + } else if (type == VECTOR3I) { + return Vector4i(reinterpret_cast<const Vector3i *>(_data._mem)->x, reinterpret_cast<const Vector3i *>(_data._mem)->y, reinterpret_cast<const Vector3i *>(_data._mem)->z, 0.0); + } else { + return Vector4i(); + } +} + Variant::operator Plane() const { if (type == PLANE) { return *reinterpret_cast<const Plane *>(_data._mem); @@ -1916,30 +2117,56 @@ Variant::operator Transform3D() const { } else if (type == TRANSFORM2D) { const Transform2D &t = *_data._transform2d; 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]; - m.basis.elements[1][1] = t.elements[1][1]; - m.origin[0] = t.elements[2][0]; - m.origin[1] = t.elements[2][1]; + m.basis.rows[0][0] = t.columns[0][0]; + m.basis.rows[1][0] = t.columns[0][1]; + m.basis.rows[0][1] = t.columns[1][0]; + m.basis.rows[1][1] = t.columns[1][1]; + m.origin[0] = t.columns[2][0]; + m.origin[1] = t.columns[2][1]; return m; + } else if (type == PROJECTION) { + return *_data._projection; } else { return Transform3D(); } } +Variant::operator Projection() const { + if (type == TRANSFORM3D) { + return *_data._transform3d; + } else if (type == BASIS) { + 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; + Transform3D m; + m.basis.rows[0][0] = t.columns[0][0]; + m.basis.rows[1][0] = t.columns[0][1]; + m.basis.rows[0][1] = t.columns[1][0]; + m.basis.rows[1][1] = t.columns[1][1]; + m.origin[0] = t.columns[2][0]; + m.origin[1] = t.columns[2][1]; + return m; + } else if (type == PROJECTION) { + return *_data._projection; + } else { + return Projection(); + } +} + Variant::operator Transform2D() const { if (type == TRANSFORM2D) { return *_data._transform2d; } 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]; - m.elements[1][0] = t.basis.elements[0][1]; - m.elements[1][1] = t.basis.elements[1][1]; - m.elements[2][0] = t.origin[0]; - m.elements[2][1] = t.origin[1]; + m.columns[0][0] = t.basis.rows[0][0]; + m.columns[0][1] = t.basis.rows[1][0]; + m.columns[1][0] = t.basis.rows[0][1]; + m.columns[1][1] = t.basis.rows[1][1]; + m.columns[2][0] = t.origin[0]; + m.columns[2][1] = t.origin[1]; return m; } else { return Transform2D(); @@ -1980,7 +2207,7 @@ Variant::operator ::RID() const { } #endif Callable::CallError ce; - Variant ret = _get_obj().obj->call(CoreStringNames::get_singleton()->get_rid, nullptr, 0, ce); + Variant ret = _get_obj().obj->callp(CoreStringNames::get_singleton()->get_rid, nullptr, 0, ce); if (ce.error == Callable::CallError::CALL_OK && ret.get_type() == Variant::RID) { return ret; } @@ -2017,22 +2244,6 @@ Object *Variant::get_validated_object() const { } } -Variant::operator Node *() const { - if (type == OBJECT) { - return Object::cast_to<Node>(_get_obj().obj); - } else { - return nullptr; - } -} - -Variant::operator Control *() const { - if (type == OBJECT) { - return Object::cast_to<Control>(_get_obj().obj); - } else { - return nullptr; - } -} - Variant::operator Dictionary() const { if (type == DICTIONARY) { return *reinterpret_cast<const Dictionary *>(_data._mem); @@ -2387,6 +2598,16 @@ Variant::Variant(const Vector3i &p_vector3i) { memnew_placement(_data._mem, Vector3i(p_vector3i)); } +Variant::Variant(const Vector4 &p_vector4) { + type = VECTOR4; + memnew_placement(_data._mem, Vector4(p_vector4)); +} + +Variant::Variant(const Vector4i &p_vector4i) { + type = VECTOR4I; + memnew_placement(_data._mem, Vector4i(p_vector4i)); +} + Variant::Variant(const Vector2 &p_vector2) { type = VECTOR2; memnew_placement(_data._mem, Vector2(p_vector2)); @@ -2414,12 +2635,14 @@ Variant::Variant(const Plane &p_plane) { Variant::Variant(const ::AABB &p_aabb) { type = AABB; - _data._aabb = memnew(::AABB(p_aabb)); + _data._aabb = (::AABB *)Pools::_bucket_small.alloc(); + memnew_placement(_data._aabb, ::AABB(p_aabb)); } Variant::Variant(const Basis &p_matrix) { type = BASIS; - _data._basis = memnew(Basis(p_matrix)); + _data._basis = (Basis *)Pools::_bucket_medium.alloc(); + memnew_placement(_data._basis, Basis(p_matrix)); } Variant::Variant(const Quaternion &p_quaternion) { @@ -2429,12 +2652,20 @@ Variant::Variant(const Quaternion &p_quaternion) { Variant::Variant(const Transform3D &p_transform) { type = TRANSFORM3D; - _data._transform3d = memnew(Transform3D(p_transform)); + _data._transform3d = (Transform3D *)Pools::_bucket_medium.alloc(); + memnew_placement(_data._transform3d, Transform3D(p_transform)); +} + +Variant::Variant(const Projection &pp_projection) { + type = PROJECTION; + _data._projection = (Projection *)Pools::_bucket_large.alloc(); + memnew_placement(_data._projection, Projection(pp_projection)); } Variant::Variant(const Transform2D &p_transform) { type = TRANSFORM2D; - _data._transform2d = memnew(Transform2D(p_transform)); + _data._transform2d = (Transform2D *)Pools::_bucket_small.alloc(); + memnew_placement(_data._transform2d, Transform2D(p_transform)); } Variant::Variant(const Color &p_color) { @@ -2659,6 +2890,12 @@ void Variant::operator=(const Variant &p_variant) { case VECTOR3I: { *reinterpret_cast<Vector3i *>(_data._mem) = *reinterpret_cast<const Vector3i *>(p_variant._data._mem); } break; + case VECTOR4: { + *reinterpret_cast<Vector4 *>(_data._mem) = *reinterpret_cast<const Vector4 *>(p_variant._data._mem); + } break; + case VECTOR4I: { + *reinterpret_cast<Vector4i *>(_data._mem) = *reinterpret_cast<const Vector4i *>(p_variant._data._mem); + } break; case PLANE: { *reinterpret_cast<Plane *>(_data._mem) = *reinterpret_cast<const Plane *>(p_variant._data._mem); } break; @@ -2675,6 +2912,9 @@ void Variant::operator=(const Variant &p_variant) { case TRANSFORM3D: { *_data._transform3d = *(p_variant._data._transform3d); } break; + case PROJECTION: { + *_data._projection = *(p_variant._data._projection); + } break; // misc types case COLOR: { @@ -2768,6 +3008,10 @@ Variant::Variant(const Variant &p_variant) { } uint32_t Variant::hash() const { + return recursive_hash(0); +} + +uint32_t Variant::recursive_hash(int recursion_count) const { switch (type) { case NIL: { return 0; @@ -2779,7 +3023,7 @@ uint32_t Variant::hash() const { return hash_one_uint64((uint64_t)_data._int); } break; case FLOAT: { - return hash_djb2_one_float(_data._float); + return hash_murmur3_one_float(_data._float); } break; case STRING: { return reinterpret_cast<const String *>(_data._mem)->hash(); @@ -2787,106 +3031,129 @@ uint32_t Variant::hash() const { // math types case VECTOR2: { - uint32_t hash = hash_djb2_one_float(reinterpret_cast<const Vector2 *>(_data._mem)->x); - return hash_djb2_one_float(reinterpret_cast<const Vector2 *>(_data._mem)->y, hash); + return HashMapHasherDefault::hash(*reinterpret_cast<const Vector2 *>(_data._mem)); } break; case VECTOR2I: { - uint32_t hash = hash_djb2_one_32((uint32_t) reinterpret_cast<const Vector2i *>(_data._mem)->x); - return hash_djb2_one_32((uint32_t) reinterpret_cast<const Vector2i *>(_data._mem)->y, hash); + return HashMapHasherDefault::hash(*reinterpret_cast<const Vector2i *>(_data._mem)); } break; case RECT2: { - uint32_t hash = hash_djb2_one_float(reinterpret_cast<const Rect2 *>(_data._mem)->position.x); - hash = hash_djb2_one_float(reinterpret_cast<const Rect2 *>(_data._mem)->position.y, hash); - hash = hash_djb2_one_float(reinterpret_cast<const Rect2 *>(_data._mem)->size.x, hash); - return hash_djb2_one_float(reinterpret_cast<const Rect2 *>(_data._mem)->size.y, hash); + return HashMapHasherDefault::hash(*reinterpret_cast<const Rect2 *>(_data._mem)); } break; case RECT2I: { - uint32_t hash = hash_djb2_one_32((uint32_t) reinterpret_cast<const Rect2i *>(_data._mem)->position.x); - hash = hash_djb2_one_32((uint32_t) reinterpret_cast<const Rect2i *>(_data._mem)->position.y, hash); - hash = hash_djb2_one_32((uint32_t) reinterpret_cast<const Rect2i *>(_data._mem)->size.x, hash); - return hash_djb2_one_32((uint32_t) reinterpret_cast<const Rect2i *>(_data._mem)->size.y, hash); + return HashMapHasherDefault::hash(*reinterpret_cast<const Rect2i *>(_data._mem)); } break; case TRANSFORM2D: { - uint32_t hash = 5831; - for (int i = 0; i < 3; i++) { - for (int j = 0; j < 2; j++) { - hash = hash_djb2_one_float(_data._transform2d->elements[i][j], hash); - } - } + uint32_t h = HASH_MURMUR3_SEED; + const Transform2D &t = *_data._transform2d; + h = hash_murmur3_one_real(t[0].x, h); + h = hash_murmur3_one_real(t[0].y, h); + h = hash_murmur3_one_real(t[1].x, h); + h = hash_murmur3_one_real(t[1].y, h); + h = hash_murmur3_one_real(t[2].x, h); + h = hash_murmur3_one_real(t[2].y, h); - return hash; + return hash_fmix32(h); } break; case VECTOR3: { - uint32_t hash = hash_djb2_one_float(reinterpret_cast<const Vector3 *>(_data._mem)->x); - hash = hash_djb2_one_float(reinterpret_cast<const Vector3 *>(_data._mem)->y, hash); - return hash_djb2_one_float(reinterpret_cast<const Vector3 *>(_data._mem)->z, hash); + return HashMapHasherDefault::hash(*reinterpret_cast<const Vector3 *>(_data._mem)); } break; case VECTOR3I: { - uint32_t hash = hash_djb2_one_32((uint32_t) reinterpret_cast<const Vector3i *>(_data._mem)->x); - hash = hash_djb2_one_32((uint32_t) reinterpret_cast<const Vector3i *>(_data._mem)->y, hash); - return hash_djb2_one_32((uint32_t) reinterpret_cast<const Vector3i *>(_data._mem)->z, hash); + return HashMapHasherDefault::hash(*reinterpret_cast<const Vector3i *>(_data._mem)); + } break; + case VECTOR4: { + return HashMapHasherDefault::hash(*reinterpret_cast<const Vector4 *>(_data._mem)); + } break; + case VECTOR4I: { + return HashMapHasherDefault::hash(*reinterpret_cast<const Vector4i *>(_data._mem)); } break; case PLANE: { - uint32_t hash = hash_djb2_one_float(reinterpret_cast<const Plane *>(_data._mem)->normal.x); - hash = hash_djb2_one_float(reinterpret_cast<const Plane *>(_data._mem)->normal.y, hash); - hash = hash_djb2_one_float(reinterpret_cast<const Plane *>(_data._mem)->normal.z, hash); - return hash_djb2_one_float(reinterpret_cast<const Plane *>(_data._mem)->d, hash); - + uint32_t h = HASH_MURMUR3_SEED; + const Plane &p = *reinterpret_cast<const Plane *>(_data._mem); + h = hash_murmur3_one_real(p.normal.x, h); + h = hash_murmur3_one_real(p.normal.y, h); + h = hash_murmur3_one_real(p.normal.z, h); + h = hash_murmur3_one_real(p.d, h); + return hash_fmix32(h); } break; case AABB: { - uint32_t hash = 5831; - for (int i = 0; i < 3; i++) { - hash = hash_djb2_one_float(_data._aabb->position[i], hash); - hash = hash_djb2_one_float(_data._aabb->size[i], hash); - } - - return hash; - + return HashMapHasherDefault::hash(*_data._aabb); } break; 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); - + uint32_t h = HASH_MURMUR3_SEED; + const Quaternion &q = *reinterpret_cast<const Quaternion *>(_data._mem); + h = hash_murmur3_one_real(q.x, h); + h = hash_murmur3_one_real(q.y, h); + h = hash_murmur3_one_real(q.z, h); + h = hash_murmur3_one_real(q.w, h); + return hash_fmix32(h); } break; case BASIS: { - uint32_t hash = 5831; - for (int i = 0; i < 3; i++) { - for (int j = 0; j < 3; j++) { - hash = hash_djb2_one_float(_data._basis->elements[i][j], hash); - } - } - - return hash; - + uint32_t h = HASH_MURMUR3_SEED; + const Basis &b = *_data._basis; + h = hash_murmur3_one_real(b[0].x, h); + h = hash_murmur3_one_real(b[0].y, h); + h = hash_murmur3_one_real(b[0].z, h); + h = hash_murmur3_one_real(b[1].x, h); + h = hash_murmur3_one_real(b[1].y, h); + h = hash_murmur3_one_real(b[1].z, h); + h = hash_murmur3_one_real(b[2].x, h); + h = hash_murmur3_one_real(b[2].y, h); + h = hash_murmur3_one_real(b[2].z, h); + return hash_fmix32(h); } break; 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._transform3d->basis.elements[i][j], hash); - } - hash = hash_djb2_one_float(_data._transform3d->origin[i], hash); - } - - return hash; - + uint32_t h = HASH_MURMUR3_SEED; + const Transform3D &t = *_data._transform3d; + h = hash_murmur3_one_real(t.basis[0].x, h); + h = hash_murmur3_one_real(t.basis[0].y, h); + h = hash_murmur3_one_real(t.basis[0].z, h); + h = hash_murmur3_one_real(t.basis[1].x, h); + h = hash_murmur3_one_real(t.basis[1].y, h); + h = hash_murmur3_one_real(t.basis[1].z, h); + h = hash_murmur3_one_real(t.basis[2].x, h); + h = hash_murmur3_one_real(t.basis[2].y, h); + h = hash_murmur3_one_real(t.basis[2].z, h); + h = hash_murmur3_one_real(t.origin.x, h); + h = hash_murmur3_one_real(t.origin.y, h); + h = hash_murmur3_one_real(t.origin.z, h); + return hash_fmix32(h); + } break; + case PROJECTION: { + uint32_t h = HASH_MURMUR3_SEED; + const Projection &t = *_data._projection; + h = hash_murmur3_one_real(t.matrix[0].x, h); + h = hash_murmur3_one_real(t.matrix[0].y, h); + h = hash_murmur3_one_real(t.matrix[0].z, h); + h = hash_murmur3_one_real(t.matrix[0].w, h); + h = hash_murmur3_one_real(t.matrix[1].x, h); + h = hash_murmur3_one_real(t.matrix[1].y, h); + h = hash_murmur3_one_real(t.matrix[1].z, h); + h = hash_murmur3_one_real(t.matrix[1].w, h); + h = hash_murmur3_one_real(t.matrix[2].x, h); + h = hash_murmur3_one_real(t.matrix[2].y, h); + h = hash_murmur3_one_real(t.matrix[2].z, h); + h = hash_murmur3_one_real(t.matrix[2].w, h); + h = hash_murmur3_one_real(t.matrix[3].x, h); + h = hash_murmur3_one_real(t.matrix[3].y, h); + h = hash_murmur3_one_real(t.matrix[3].z, h); + h = hash_murmur3_one_real(t.matrix[3].w, h); + return hash_fmix32(h); } break; - // misc types case COLOR: { - uint32_t hash = hash_djb2_one_float(reinterpret_cast<const Color *>(_data._mem)->r); - hash = hash_djb2_one_float(reinterpret_cast<const Color *>(_data._mem)->g, hash); - hash = hash_djb2_one_float(reinterpret_cast<const Color *>(_data._mem)->b, hash); - return hash_djb2_one_float(reinterpret_cast<const Color *>(_data._mem)->a, hash); - + uint32_t h = HASH_MURMUR3_SEED; + const Color &c = *reinterpret_cast<const Color *>(_data._mem); + h = hash_murmur3_one_float(c.r, h); + h = hash_murmur3_one_float(c.g, h); + h = hash_murmur3_one_float(c.b, h); + h = hash_murmur3_one_float(c.a, h); + return hash_fmix32(h); } break; case RID: { - return hash_djb2_one_64(reinterpret_cast<const ::RID *>(_data._mem)->get_id()); + return hash_one_uint64(reinterpret_cast<const ::RID *>(_data._mem)->get_id()); } break; case OBJECT: { - return hash_djb2_one_64(make_uint64_t(_get_obj().obj)); + return hash_one_uint64(hash_make_uint64_t(_get_obj().obj)); } break; case STRING_NAME: { return reinterpret_cast<const StringName *>(_data._mem)->hash(); @@ -2895,7 +3162,7 @@ uint32_t Variant::hash() const { return reinterpret_cast<const NodePath *>(_data._mem)->hash(); } break; case DICTIONARY: { - return reinterpret_cast<const Dictionary *>(_data._mem)->hash(); + return reinterpret_cast<const Dictionary *>(_data._mem)->recursive_hash(recursion_count); } break; case CALLABLE: { @@ -2905,11 +3172,11 @@ uint32_t Variant::hash() const { case SIGNAL: { const Signal &s = *reinterpret_cast<const Signal *>(_data._mem); uint32_t hash = s.get_name().hash(); - return hash_djb2_one_64(s.get_object_id(), hash); + return hash_murmur3_one_64(s.get_object_id(), hash); } break; case ARRAY: { const Array &arr = *reinterpret_cast<const Array *>(_data._mem); - return arr.hash(); + return arr.recursive_hash(recursion_count); } break; case PACKED_BYTE_ARRAY: { @@ -2917,9 +3184,9 @@ uint32_t Variant::hash() const { int len = arr.size(); if (likely(len)) { const uint8_t *r = arr.ptr(); - return hash_djb2_buffer((uint8_t *)&r[0], len); + return hash_murmur3_buffer((uint8_t *)&r[0], len); } else { - return hash_djb2_one_64(0); + return hash_murmur3_one_64(0); } } break; @@ -2928,9 +3195,9 @@ uint32_t Variant::hash() const { int len = arr.size(); if (likely(len)) { const int32_t *r = arr.ptr(); - return hash_djb2_buffer((uint8_t *)&r[0], len * sizeof(int32_t)); + return hash_murmur3_buffer((uint8_t *)&r[0], len * sizeof(int32_t)); } else { - return hash_djb2_one_64(0); + return hash_murmur3_one_64(0); } } break; @@ -2939,9 +3206,9 @@ uint32_t Variant::hash() const { int len = arr.size(); if (likely(len)) { const int64_t *r = arr.ptr(); - return hash_djb2_buffer((uint8_t *)&r[0], len * sizeof(int64_t)); + return hash_murmur3_buffer((uint8_t *)&r[0], len * sizeof(int64_t)); } else { - return hash_djb2_one_64(0); + return hash_murmur3_one_64(0); } } break; @@ -2951,9 +3218,13 @@ uint32_t Variant::hash() const { if (likely(len)) { const float *r = arr.ptr(); - return hash_djb2_buffer((uint8_t *)&r[0], len * sizeof(float)); + uint32_t h = HASH_MURMUR3_SEED; + for (int32_t i = 0; i < len; i++) { + h = hash_murmur3_one_float(r[i], h); + } + return hash_fmix32(h); } else { - return hash_djb2_one_float(0.0); + return hash_murmur3_one_float(0.0); } } break; @@ -2963,14 +3234,18 @@ uint32_t Variant::hash() const { if (likely(len)) { const double *r = arr.ptr(); - return hash_djb2_buffer((uint8_t *)&r[0], len * sizeof(double)); + uint32_t h = HASH_MURMUR3_SEED; + for (int32_t i = 0; i < len; i++) { + h = hash_murmur3_one_double(r[i], h); + } + return hash_fmix32(h); } else { - return hash_djb2_one_float(0.0); + return hash_murmur3_one_float(0.0); } } break; case PACKED_STRING_ARRAY: { - uint32_t hash = 5831; + uint32_t hash = HASH_MURMUR3_SEED; const Vector<String> &arr = PackedArrayRef<String>::get_array(_data.packed_array); int len = arr.size(); @@ -2978,14 +3253,15 @@ uint32_t Variant::hash() const { const String *r = arr.ptr(); for (int i = 0; i < len; i++) { - hash = hash_djb2_one_32(r[i].hash(), hash); + hash = hash_murmur3_one_32(r[i].hash(), hash); } + hash = hash_fmix32(hash); } return hash; } break; case PACKED_VECTOR2_ARRAY: { - uint32_t hash = 5831; + uint32_t hash = HASH_MURMUR3_SEED; const Vector<Vector2> &arr = PackedArrayRef<Vector2>::get_array(_data.packed_array); int len = arr.size(); @@ -2993,15 +3269,16 @@ uint32_t Variant::hash() const { const Vector2 *r = arr.ptr(); for (int i = 0; i < len; i++) { - hash = hash_djb2_one_float(r[i].x, hash); - hash = hash_djb2_one_float(r[i].y, hash); + hash = hash_murmur3_one_real(r[i].x, hash); + hash = hash_murmur3_one_real(r[i].y, hash); } + hash = hash_fmix32(hash); } return hash; } break; case PACKED_VECTOR3_ARRAY: { - uint32_t hash = 5831; + uint32_t hash = HASH_MURMUR3_SEED; const Vector<Vector3> &arr = PackedArrayRef<Vector3>::get_array(_data.packed_array); int len = arr.size(); @@ -3009,16 +3286,17 @@ uint32_t Variant::hash() const { const Vector3 *r = arr.ptr(); for (int i = 0; i < len; i++) { - hash = hash_djb2_one_float(r[i].x, hash); - hash = hash_djb2_one_float(r[i].y, hash); - hash = hash_djb2_one_float(r[i].z, hash); + hash = hash_murmur3_one_real(r[i].x, hash); + hash = hash_murmur3_one_real(r[i].y, hash); + hash = hash_murmur3_one_real(r[i].z, hash); } + hash = hash_fmix32(hash); } return hash; } break; case PACKED_COLOR_ARRAY: { - uint32_t hash = 5831; + uint32_t hash = HASH_MURMUR3_SEED; const Vector<Color> &arr = PackedArrayRef<Color>::get_array(_data.packed_array); int len = arr.size(); @@ -3026,11 +3304,12 @@ uint32_t Variant::hash() const { const Color *r = arr.ptr(); for (int i = 0; i < len; i++) { - hash = hash_djb2_one_float(r[i].r, hash); - hash = hash_djb2_one_float(r[i].g, hash); - hash = hash_djb2_one_float(r[i].b, hash); - hash = hash_djb2_one_float(r[i].a, hash); + hash = hash_murmur3_one_float(r[i].r, hash); + hash = hash_murmur3_one_float(r[i].g, hash); + hash = hash_murmur3_one_float(r[i].b, hash); + hash = hash_murmur3_one_float(r[i].a, hash); } + hash = hash_fmix32(hash); } return hash; @@ -3053,6 +3332,11 @@ uint32_t Variant::hash() const { (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)) +#define hash_compare_vector4(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)) && \ + (hash_compare_scalar((p_lhs).w, (p_rhs).w)) #define hash_compare_quaternion(p_lhs, p_rhs) \ (hash_compare_scalar((p_lhs).x, (p_rhs).x)) && \ @@ -3083,7 +3367,7 @@ uint32_t Variant::hash() const { \ return true -bool Variant::hash_compare(const Variant &p_variant) const { +bool Variant::hash_compare(const Variant &p_variant, int recursion_count) const { if (type != p_variant.type) { return false; } @@ -3101,6 +3385,10 @@ bool Variant::hash_compare(const Variant &p_variant) const { return *reinterpret_cast<const String *>(_data._mem) == *reinterpret_cast<const String *>(p_variant._data._mem); } break; + case STRING_NAME: { + return *reinterpret_cast<const StringName *>(_data._mem) == *reinterpret_cast<const StringName *>(p_variant._data._mem); + } break; + case VECTOR2: { const Vector2 *l = reinterpret_cast<const Vector2 *>(_data._mem); const Vector2 *r = reinterpret_cast<const Vector2 *>(p_variant._data._mem); @@ -3118,7 +3406,7 @@ bool Variant::hash_compare(const Variant &p_variant) const { const Rect2 *r = reinterpret_cast<const Rect2 *>(p_variant._data._mem); return (hash_compare_vector2(l->position, r->position)) && - (hash_compare_vector2(l->size, r->size)); + (hash_compare_vector2(l->size, r->size)); } break; case RECT2I: { const Rect2i *l = reinterpret_cast<const Rect2i *>(_data._mem); @@ -3132,7 +3420,7 @@ bool Variant::hash_compare(const Variant &p_variant) const { Transform2D *r = p_variant._data._transform2d; for (int i = 0; i < 3; i++) { - if (!(hash_compare_vector2(l->elements[i], r->elements[i]))) { + if (!(hash_compare_vector2(l->columns[i], r->columns[i]))) { return false; } } @@ -3152,13 +3440,25 @@ bool Variant::hash_compare(const Variant &p_variant) const { return *l == *r; } break; + case VECTOR4: { + const Vector4 *l = reinterpret_cast<const Vector4 *>(_data._mem); + const Vector4 *r = reinterpret_cast<const Vector4 *>(p_variant._data._mem); + + return hash_compare_vector4(*l, *r); + } break; + case VECTOR4I: { + const Vector4i *l = reinterpret_cast<const Vector4i *>(_data._mem); + const Vector4i *r = reinterpret_cast<const Vector4i *>(p_variant._data._mem); + + return *l == *r; + } break; case PLANE: { const Plane *l = reinterpret_cast<const Plane *>(_data._mem); const Plane *r = reinterpret_cast<const Plane *>(p_variant._data._mem); return (hash_compare_vector3(l->normal, r->normal)) && - (hash_compare_scalar(l->d, r->d)); + (hash_compare_scalar(l->d, r->d)); } break; case AABB: { @@ -3182,7 +3482,7 @@ bool Variant::hash_compare(const Variant &p_variant) const { const Basis *r = p_variant._data._basis; for (int i = 0; i < 3; i++) { - if (!(hash_compare_vector3(l->elements[i], r->elements[i]))) { + if (!(hash_compare_vector3(l->rows[i], r->rows[i]))) { return false; } } @@ -3195,13 +3495,25 @@ bool Variant::hash_compare(const Variant &p_variant) const { 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]))) { + if (!(hash_compare_vector3(l->basis.rows[i], r->basis.rows[i]))) { return false; } } return hash_compare_vector3(l->origin, r->origin); } break; + case PROJECTION: { + const Projection *l = _data._projection; + const Projection *r = p_variant._data._projection; + + for (int i = 0; i < 4; i++) { + if (!(hash_compare_vector4(l->matrix[i], r->matrix[i]))) { + return false; + } + } + + return true; + } break; case COLOR: { const Color *l = reinterpret_cast<const Color *>(_data._mem); @@ -3214,14 +3526,19 @@ bool Variant::hash_compare(const Variant &p_variant) const { const Array &l = *(reinterpret_cast<const Array *>(_data._mem)); const Array &r = *(reinterpret_cast<const Array *>(p_variant._data._mem)); - if (l.size() != r.size()) { + if (!l.recursive_equal(r, recursion_count + 1)) { return false; } - for (int i = 0; i < l.size(); ++i) { - if (!l[i].hash_compare(r[i])) { - return false; - } + return true; + } break; + + case DICTIONARY: { + const Dictionary &l = *(reinterpret_cast<const Dictionary *>(_data._mem)); + const Dictionary &r = *(reinterpret_cast<const Dictionary *>(p_variant._data._mem)); + + if (!l.recursive_equal(r, recursion_count + 1)) { + return false; } return true; @@ -3258,7 +3575,7 @@ bool Variant::hash_compare(const Variant &p_variant) const { return false; } -bool Variant::is_ref() const { +bool Variant::is_ref_counted() const { return type == OBJECT && _get_obj().id.is_ref_counted(); } @@ -3309,13 +3626,20 @@ Vector<Variant> varray(const Variant &p_arg1, const Variant &p_arg2, const Varia void Variant::static_assign(const Variant &p_variant) { } -bool Variant::is_shared() const { - switch (type) { +bool Variant::is_type_shared(Variant::Type p_type) { + switch (p_type) { case OBJECT: - return true; case ARRAY: - return true; case DICTIONARY: + case PACKED_BYTE_ARRAY: + case PACKED_INT32_ARRAY: + case PACKED_INT64_ARRAY: + case PACKED_FLOAT32_ARRAY: + case PACKED_FLOAT64_ARRAY: + case PACKED_STRING_ARRAY: + case PACKED_VECTOR2_ARRAY: + case PACKED_VECTOR3_ARRAY: + case PACKED_COLOR_ARRAY: return true; default: { } @@ -3324,21 +3648,11 @@ bool Variant::is_shared() const { return false; } -Variant Variant::call(const StringName &p_method, VARIANT_ARG_DECLARE) { - VARIANT_ARGPTRS; - int argc = 0; - for (int i = 0; i < VARIANT_ARG_MAX; i++) { - if (argptr[i]->get_type() == Variant::NIL) { - break; - } - argc++; - } - - Callable::CallError error; - - Variant ret; - call(p_method, argptr, argc, ret, error); +bool Variant::is_shared() const { + return is_type_shared(type); +} +void Variant::_variant_call_error(const String &p_method, Callable::CallError &error) { switch (error.error) { case Callable::CallError::CALL_ERROR_INVALID_ARGUMENT: { String err = "Invalid type for argument #" + itos(error.argument) + ", expected '" + Variant::get_type_name(Variant::Type(error.expected)) + "'."; @@ -3356,8 +3670,6 @@ Variant Variant::call(const StringName &p_method, VARIANT_ARG_DECLARE) { default: { } } - - return ret; } void Variant::construct_from_string(const String &p_string, Variant &r_value, ObjectConstruct p_obj_construct, void *p_construct_ud) { @@ -3372,27 +3684,7 @@ String Variant::get_construct_string() const { } String Variant::get_call_error_text(const StringName &p_method, const Variant **p_argptrs, int p_argcount, const Callable::CallError &ce) { - String err_text; - - if (ce.error == Callable::CallError::CALL_ERROR_INVALID_ARGUMENT) { - int errorarg = ce.argument; - if (p_argptrs) { - err_text = "Cannot convert argument " + itos(errorarg + 1) + " from " + Variant::get_type_name(p_argptrs[errorarg]->get_type()) + " to " + Variant::get_type_name(Variant::Type(ce.expected)) + "."; - } else { - err_text = "Cannot convert argument " + itos(errorarg + 1) + " from [missing argptr, type unknown] to " + Variant::get_type_name(Variant::Type(ce.expected)) + "."; - } - } else if (ce.error == Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS) { - err_text = "Method expected " + itos(ce.argument) + " arguments, but called with " + itos(p_argcount) + "."; - } else if (ce.error == Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS) { - err_text = "Method expected " + itos(ce.argument) + " arguments, but called with " + itos(p_argcount) + "."; - } else if (ce.error == Callable::CallError::CALL_ERROR_INVALID_METHOD) { - err_text = "Method not found."; - } else if (ce.error == Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL) { - err_text = "Instance is null"; - } else if (ce.error == Callable::CallError::CALL_OK) { - return "Call OK"; - } - return "'" + String(p_method) + "': " + err_text; + return get_call_error_text(nullptr, p_method, p_argptrs, p_argcount, ce); } String Variant::get_call_error_text(Object *p_base, const StringName &p_method, const Variant **p_argptrs, int p_argcount, const Callable::CallError &ce) { @@ -3413,41 +3705,26 @@ String Variant::get_call_error_text(Object *p_base, const StringName &p_method, err_text = "Method not found."; } else if (ce.error == Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL) { err_text = "Instance is null"; + } else if (ce.error == Callable::CallError::CALL_ERROR_METHOD_NOT_CONST) { + err_text = "Method not const in const instance"; } else if (ce.error == Callable::CallError::CALL_OK) { return "Call OK"; } - String class_name = p_base->get_class(); - Ref<Script> script = p_base->get_script(); - if (script.is_valid() && script->get_path().is_resource_file()) { - class_name += "(" + script->get_path().get_file() + ")"; + String base_text; + if (p_base) { + base_text = p_base->get_class(); + Ref<Resource> script = p_base->get_script(); + if (script.is_valid() && script->get_path().is_resource_file()) { + base_text += "(" + script->get_path().get_file() + ")"; + } + base_text += "::"; } - return "'" + class_name + "::" + String(p_method) + "': " + err_text; + return "'" + base_text + String(p_method) + "': " + err_text; } String Variant::get_callable_error_text(const Callable &p_callable, const Variant **p_argptrs, int p_argcount, const Callable::CallError &ce) { - String err_text; - - if (ce.error == Callable::CallError::CALL_ERROR_INVALID_ARGUMENT) { - int errorarg = ce.argument; - if (p_argptrs) { - err_text = "Cannot convert argument " + itos(errorarg + 1) + " from " + Variant::get_type_name(p_argptrs[errorarg]->get_type()) + " to " + Variant::get_type_name(Variant::Type(ce.expected)) + "."; - } else { - err_text = "Cannot convert argument " + itos(errorarg + 1) + " from [missing argptr, type unknown] to " + Variant::get_type_name(Variant::Type(ce.expected)) + "."; - } - } else if (ce.error == Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS) { - err_text = "Method expected " + itos(ce.argument) + " arguments, but called with " + itos(p_argcount) + "."; - } else if (ce.error == Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS) { - err_text = "Method expected " + itos(ce.argument) + " arguments, but called with " + itos(p_argcount) + "."; - } else if (ce.error == Callable::CallError::CALL_ERROR_INVALID_METHOD) { - err_text = "Method not found."; - } else if (ce.error == Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL) { - err_text = "Instance is null"; - } else if (ce.error == Callable::CallError::CALL_OK) { - return "Call OK"; - } - - return String(p_callable) + " : " + err_text; + return get_call_error_text(p_callable.get_object(), p_callable.get_method(), p_argptrs, p_argcount, ce); } String vformat(const String &p_text, const Variant &p1, const Variant &p2, const Variant &p3, const Variant &p4, const Variant &p5) { |