summaryrefslogtreecommitdiff
path: root/core/variant/variant.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'core/variant/variant.cpp')
-rw-r--r--core/variant/variant.cpp244
1 files changed, 80 insertions, 164 deletions
diff --git a/core/variant/variant.cpp b/core/variant/variant.cpp
index 3d11ed6303..aa640924e4 100644
--- a/core/variant/variant.cpp
+++ b/core/variant/variant.cpp
@@ -184,7 +184,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;
}
@@ -490,7 +490,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;
}
@@ -1620,6 +1620,27 @@ Variant::operator String() const {
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 s;
+}
+
template <class T>
String stringify_vector(const T &vec, int recursion_count) {
String str("[");
@@ -1627,7 +1648,8 @@ String stringify_vector(const T &vec, int recursion_count) {
if (i > 0) {
str += ", ";
}
- str = str + Variant(vec[i]).stringify(recursion_count);
+
+ str += stringify_variant_clean(vec[i], recursion_count);
}
str += "]";
return str;
@@ -1691,8 +1713,8 @@ String Variant::stringify(int recursion_count) const {
recursion_count++;
for (List<Variant>::Element *E = keys.front(); E; E = E->next()) {
_VariantStrPair sp;
- sp.key = E->get().stringify(recursion_count);
- sp.value = d[E->get()].stringify(recursion_count);
+ sp.key = stringify_variant_clean(E->get(), recursion_count);
+ sp.value = stringify_variant_clean(d[E->get()], recursion_count);
pairs.push_back(sp);
}
@@ -1741,8 +1763,7 @@ String Variant::stringify(int recursion_count) const {
return "[...]";
}
- String str = stringify_vector(arr, recursion_count);
- return str;
+ return stringify_vector(arr, recursion_count);
} break;
case OBJECT: {
@@ -1908,12 +1929,12 @@ 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 {
return Transform3D();
@@ -1926,12 +1947,12 @@ Variant::operator Transform2D() const {
} 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();
@@ -1972,7 +1993,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;
}
@@ -2767,106 +2788,50 @@ uint32_t Variant::recursive_hash(int recursion_count) 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 hash_murmur3_32(reinterpret_cast<const Vector2 *>(_data._mem), sizeof(Vector2));
} 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 hash_murmur3_32(reinterpret_cast<const Vector2i *>(_data._mem), sizeof(Vector2i));
} 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 hash_murmur3_32(reinterpret_cast<const Rect2 *>(_data._mem), sizeof(Rect2));
} 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 hash_murmur3_32(reinterpret_cast<const Rect2i *>(_data._mem), sizeof(Rect2i));
} 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);
- }
- }
-
- return hash;
+ return hash_murmur3_32(reinterpret_cast<const Transform2D *>(_data._transform2d), sizeof(Transform2D));
} 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 hash_murmur3_32(reinterpret_cast<const Vector3 *>(_data._mem), sizeof(Vector3));
} 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 hash_murmur3_32(reinterpret_cast<const Vector3i *>(_data._mem), sizeof(Vector3i));
} 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);
-
+ return hash_murmur3_32(reinterpret_cast<const Plane *>(_data._mem), sizeof(Plane));
} 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 hash_murmur3_32(_data._aabb, sizeof(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);
-
+ return hash_murmur3_32(reinterpret_cast<const Quaternion *>(_data._mem), sizeof(Quaternion));
} 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;
-
+ return hash_murmur3_32(_data._basis, sizeof(Basis));
} 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;
-
+ return hash_murmur3_32(_data._transform3d, sizeof(Transform3D));
} 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);
-
+ return hash_murmur3_32(reinterpret_cast<const Color *>(_data._mem), sizeof(Color));
} 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(make_uint64_t(_get_obj().obj));
} break;
case STRING_NAME: {
return reinterpret_cast<const StringName *>(_data._mem)->hash();
@@ -2897,7 +2862,7 @@ uint32_t Variant::recursive_hash(int recursion_count) 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_32((uint8_t *)&r[0], len);
} else {
return hash_djb2_one_64(0);
}
@@ -2908,7 +2873,7 @@ uint32_t Variant::recursive_hash(int recursion_count) 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_32((uint8_t *)&r[0], len * sizeof(int32_t));
} else {
return hash_djb2_one_64(0);
}
@@ -2919,7 +2884,7 @@ uint32_t Variant::recursive_hash(int recursion_count) 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_32((uint8_t *)&r[0], len * sizeof(int64_t));
} else {
return hash_djb2_one_64(0);
}
@@ -2931,7 +2896,7 @@ uint32_t Variant::recursive_hash(int recursion_count) const {
if (likely(len)) {
const float *r = arr.ptr();
- return hash_djb2_buffer((uint8_t *)&r[0], len * sizeof(float));
+ return hash_murmur3_32((uint8_t *)&r[0], len * sizeof(float));
} else {
return hash_djb2_one_float(0.0);
}
@@ -2943,7 +2908,7 @@ uint32_t Variant::recursive_hash(int recursion_count) const {
if (likely(len)) {
const double *r = arr.ptr();
- return hash_djb2_buffer((uint8_t *)&r[0], len * sizeof(double));
+ return hash_murmur3_32((uint8_t *)&r[0], len * sizeof(double));
} else {
return hash_djb2_one_float(0.0);
}
@@ -3081,6 +3046,10 @@ bool Variant::hash_compare(const Variant &p_variant, int recursion_count) 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);
@@ -3112,7 +3081,7 @@ bool Variant::hash_compare(const Variant &p_variant, int recursion_count) 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;
}
}
@@ -3162,7 +3131,7 @@ bool Variant::hash_compare(const Variant &p_variant, int recursion_count) 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;
}
}
@@ -3175,7 +3144,7 @@ bool Variant::hash_compare(const Variant &p_variant, int recursion_count) 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;
}
}
@@ -3309,21 +3278,7 @@ 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);
-
+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)) + "'.";
@@ -3341,8 +3296,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) {
@@ -3357,27 +3310,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) {
@@ -3402,37 +3335,20 @@ String Variant::get_call_error_text(Object *p_base, const StringName &p_method,
return "Call OK";
}
- String class_name = p_base->get_class();
- Ref<Resource> 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) {