diff options
author | Arman Elgudzhyan <48544263+puchik@users.noreply.github.com> | 2023-03-07 19:13:00 -0800 |
---|---|---|
committer | Arman Elgudzhyan <48544263+puchik@users.noreply.github.com> | 2023-08-31 09:29:48 -0700 |
commit | ee272546020ffdbc0ab565c14d047a329d4c1ea2 (patch) | |
tree | b299237a045322c7fcd34964b51b95c3242e7e73 /core | |
parent | 549fcce5f8f7beace3e5c90e9bbe4335d4fd1476 (diff) | |
download | redot-engine-ee272546020ffdbc0ab565c14d047a329d4c1ea2.tar.gz |
Support both semantic (by default) and numeric Variant hash comparison
Hash comparison for Variant continues to perform semantic/logical comparison with NaN's considered equal by default (to prevent #16114, #7354, #6947, #8081), but now optionally allows for numeric comparison that does not consider NaN's equal to support proper value comparison (for #72222)
Diffstat (limited to 'core')
-rw-r--r-- | core/variant/array.cpp | 2 | ||||
-rw-r--r-- | core/variant/dictionary.cpp | 2 | ||||
-rw-r--r-- | core/variant/variant.cpp | 9 | ||||
-rw-r--r-- | core/variant/variant.h | 3 |
4 files changed, 10 insertions, 6 deletions
diff --git a/core/variant/array.cpp b/core/variant/array.cpp index 5a0ded6c01..8e9d6eddcf 100644 --- a/core/variant/array.cpp +++ b/core/variant/array.cpp @@ -137,7 +137,7 @@ bool Array::recursive_equal(const Array &p_array, int recursion_count) const { } recursion_count++; for (int i = 0; i < size; i++) { - if (!a1[i].hash_compare(a2[i], recursion_count)) { + if (!a1[i].hash_compare(a2[i], recursion_count, false)) { return false; } } diff --git a/core/variant/dictionary.cpp b/core/variant/dictionary.cpp index f019273735..88bc643551 100644 --- a/core/variant/dictionary.cpp +++ b/core/variant/dictionary.cpp @@ -210,7 +210,7 @@ bool Dictionary::recursive_equal(const Dictionary &p_dictionary, int recursion_c recursion_count++; for (const KeyValue<Variant, Variant> &this_E : _p->variant_map) { HashMap<Variant, Variant, VariantHasher, StringLikeVariantComparator>::ConstIterator other_E(p_dictionary._p->variant_map.find(this_E.key)); - if (!other_E || !this_E.value.hash_compare(other_E->value, recursion_count)) { + if (!other_E || !this_E.value.hash_compare(other_E->value, recursion_count, false)) { return false; } } diff --git a/core/variant/variant.cpp b/core/variant/variant.cpp index 8a0289898d..63ea3274ce 100644 --- a/core/variant/variant.cpp +++ b/core/variant/variant.cpp @@ -3235,8 +3235,11 @@ uint32_t Variant::recursive_hash(int recursion_count) const { return 0; } +#define hash_compare_scalar_base(p_lhs, p_rhs, semantic_comparison) \ + (((p_lhs) == (p_rhs)) || (semantic_comparison && Math::is_nan(p_lhs) && Math::is_nan(p_rhs))) + #define hash_compare_scalar(p_lhs, p_rhs) \ - (((p_lhs) == (p_rhs)) || (Math::is_nan(p_lhs) && Math::is_nan(p_rhs))) + (hash_compare_scalar_base(p_lhs, p_rhs, true)) #define hash_compare_vector2(p_lhs, p_rhs) \ (hash_compare_scalar((p_lhs).x, (p_rhs).x) && \ @@ -3282,7 +3285,7 @@ uint32_t Variant::recursive_hash(int recursion_count) const { \ return true -bool Variant::hash_compare(const Variant &p_variant, int recursion_count) const { +bool Variant::hash_compare(const Variant &p_variant, int recursion_count, bool semantic_comparison) const { if (type != p_variant.type) { return false; } @@ -3293,7 +3296,7 @@ bool Variant::hash_compare(const Variant &p_variant, int recursion_count) const } break; case FLOAT: { - return hash_compare_scalar(_data._float, p_variant._data._float); + return hash_compare_scalar_base(_data._float, p_variant._data._float, semantic_comparison); } break; case STRING: { diff --git a/core/variant/variant.h b/core/variant/variant.h index 04c2fe2012..d698f85754 100644 --- a/core/variant/variant.h +++ b/core/variant/variant.h @@ -751,7 +751,8 @@ public: uint32_t hash() const; uint32_t recursive_hash(int recursion_count) const; - bool hash_compare(const Variant &p_variant, int recursion_count = 0) const; + // By default, performs a semantic comparison. Otherwise, numeric/binary comparison (if appropriate). + bool hash_compare(const Variant &p_variant, int recursion_count = 0, bool semantic_comparison = true) const; bool identity_compare(const Variant &p_variant) const; bool booleanize() const; String stringify(int recursion_count = 0) const; |