diff --git a/core/doc_data.cpp b/core/doc_data.cpp index f40e878d52b9..d5e4c9ba7d5e 100644 --- a/core/doc_data.cpp +++ b/core/doc_data.cpp @@ -31,12 +31,13 @@ #include "doc_data.h" String DocData::get_default_value_string(const Variant &p_value) { + const int digits = 6; // Reduced precision is better for documentation, avoids unnecessary decimals. if (p_value.get_type() == Variant::ARRAY) { - return Variant(Array(p_value, 0, StringName(), Variant())).get_construct_string().replace("\n", " "); + return Variant(Array(p_value, 0, StringName(), Variant())).get_construct_string(digits).replace("\n", " "); } else if (p_value.get_type() == Variant::DICTIONARY) { - return Variant(Dictionary(p_value, 0, StringName(), Variant(), 0, StringName(), Variant())).get_construct_string().replace("\n", " "); + return Variant(Dictionary(p_value, 0, StringName(), Variant(), 0, StringName(), Variant())).get_construct_string(digits).replace("\n", " "); } else { - return p_value.get_construct_string().replace("\n", " "); + return p_value.get_construct_string(digits).replace("\n", " "); } } diff --git a/core/string/ustring.cpp b/core/string/ustring.cpp index e6f7492a189b..e4f0e9f1fa83 100644 --- a/core/string/ustring.cpp +++ b/core/string/ustring.cpp @@ -1938,7 +1938,7 @@ String String::num_real(double p_num, bool p_trailing) { return num(p_num, decimals); } -String String::num_scientific(double p_num) { +String String::num_scientific(double p_num, int p_digits) { if (Math::is_nan(p_num)) { return "nan"; } @@ -1951,6 +1951,9 @@ String String::num_scientific(double p_num) { } } + if (p_digits > MAX_DECIMALS) { + p_digits = MAX_DECIMALS; + } char buf[256]; #if defined(__GNUC__) || defined(_MSC_VER) @@ -1959,14 +1962,14 @@ String String::num_scientific(double p_num) { // MinGW requires _set_output_format() to conform to C99 output for printf unsigned int old_exponent_format = _set_output_format(_TWO_DIGIT_EXPONENT); #endif - snprintf(buf, 256, "%lg", p_num); + snprintf(buf, 256, "%.*g", p_digits, p_num); #if defined(__MINGW32__) && defined(_TWO_DIGIT_EXPONENT) && !defined(_UCRT) _set_output_format(old_exponent_format); #endif #else - sprintf(buf, "%.16lg", p_num); + sprintf(buf, "%.*g", p_digits, p_num); #endif buf[255] = 0; @@ -1974,6 +1977,10 @@ String String::num_scientific(double p_num) { return buf; } +String String::num_scientific_compat_bind(double p_num) { + return num_scientific(p_num); +} + String String::md5(const uint8_t *p_md5) { return String::hex_encode_buffer(p_md5, 16); } diff --git a/core/string/ustring.h b/core/string/ustring.h index aa62c9cb1889..b6dc1a3cd006 100644 --- a/core/string/ustring.h +++ b/core/string/ustring.h @@ -330,7 +330,8 @@ class String { String quote(const String "echar = "\"") const; String unquote() const; static String num(double p_num, int p_decimals = -1); - static String num_scientific(double p_num); + static String num_scientific(double p_num, int p_digits = 6); + static String num_scientific_compat_bind(double p_num); // Delete in Godot 5.0 static String num_real(double p_num, bool p_trailing = true); static String num_int64(int64_t p_num, int base = 10, bool capitalize_hex = false); static String num_uint64(uint64_t p_num, int base = 10, bool capitalize_hex = false); diff --git a/core/variant/variant.cpp b/core/variant/variant.cpp index e2865a06be9a..cd58b8fa319e 100644 --- a/core/variant/variant.cpp +++ b/core/variant/variant.cpp @@ -3619,9 +3619,9 @@ void Variant::construct_from_string(const String &p_string, Variant &r_value, Ob r_value = Variant(); } -String Variant::get_construct_string() const { +String Variant::get_construct_string(int p_max_digits) const { String vars; - VariantWriter::write_to_string(*this, vars); + VariantWriter::write_to_string(*this, vars, nullptr, nullptr, true, p_max_digits); return vars; } diff --git a/core/variant/variant.h b/core/variant/variant.h index c76b849abdb7..9d28e980e66f 100644 --- a/core/variant/variant.h +++ b/core/variant/variant.h @@ -805,7 +805,7 @@ class Variant { typedef String (*ObjectDeConstruct)(const Variant &p_object, void *ud); typedef void (*ObjectConstruct)(const String &p_text, void *ud, Variant &r_value); - String get_construct_string() const; + String get_construct_string(int p_max_digits = 17) const; static void construct_from_string(const String &p_string, Variant &r_value, ObjectConstruct p_obj_construct = nullptr, void *p_construct_ud = nullptr); void operator=(const Variant &p_variant); // only this is enough for all the other types diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp index 29e11462c923..693425f0aa4d 100644 --- a/core/variant/variant_call.cpp +++ b/core/variant/variant_call.cpp @@ -1591,6 +1591,16 @@ int Variant::get_enum_value(Variant::Type p_type, const StringName &p_enum_name, register_builtin_method(sarray(), m_default_args); #endif +#ifdef DEBUG_METHODS_ENABLED +#define bind_static_method_with_name(m_type, m_exposed_name, m_method, m_arg_names, m_default_args) \ + STATIC_METHOD_CLASS(m_type, m_exposed_name, m_type::m_method); \ + register_builtin_method(m_arg_names, m_default_args); +#else +#define bind_static_method_with_name(m_type, m_exposed_name, m_method, m_arg_names, m_default_args) \ + STATIC_METHOD_CLASS(m_type, m_exposed_name, m_type ::m_method); \ + register_builtin_method(sarray(), m_default_args); +#endif + #ifdef DEBUG_METHODS_ENABLED #define bind_methodv(m_type, m_name, m_method, m_arg_names, m_default_args) \ METHOD_CLASS(m_type, m_name, m_method); \ @@ -1769,7 +1779,7 @@ static void _register_variant_builtin_methods_string() { bind_string_method(hex_decode, sarray(), varray()); bind_string_method(to_wchar_buffer, sarray(), varray()); - bind_static_method(String, num_scientific, sarray("number"), varray()); + bind_static_method_with_name(String, num_scientific, num_scientific_compat_bind, sarray("number"), varray()); bind_static_method(String, num, sarray("number", "decimals"), varray(-1)); bind_static_method(String, num_int64, sarray("number", "base", "capitalize_hex"), varray(10, false)); bind_static_method(String, num_uint64, sarray("number", "base", "capitalize_hex"), varray(10, false)); diff --git a/core/variant/variant_parser.cpp b/core/variant/variant_parser.cpp index f5f96456d327..23cb5caee6c6 100644 --- a/core/variant/variant_parser.cpp +++ b/core/variant/variant_parser.cpp @@ -1931,9 +1931,11 @@ Error VariantParser::parse(Stream *p_stream, Variant &r_ret, String &r_err_str, ////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////// -static String rtos_fix(double p_value) { +// These two functions serialize floats or doubles in a way that ensures they +// can be read back in the same way (except collapsing -0 to 0, and NaN values). +static String serialize_real(float p_value, int p_max_digits = 9) { if (p_value == 0.0) { - return "0"; //avoid negative zero (-0) being written, which may annoy git, svn, etc. for changes when they don't exist. + return "0"; // Avoid negative zero (-0) being written, which may annoy git, svn, etc. for changes when they don't exist. } else if (isnan(p_value)) { return "nan"; } else if (isinf(p_value)) { @@ -1943,11 +1945,31 @@ static String rtos_fix(double p_value) { return "inf_neg"; } } else { - return rtoss(p_value); + int digits = p_max_digits > 9 ? 9 : p_max_digits; + return String::num_scientific(p_value, digits); } } -Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_string_func, void *p_store_string_ud, EncodeResourceFunc p_encode_res_func, void *p_encode_res_ud, int p_recursion_count, bool p_compat) { +static String serialize_real(double p_value, int p_max_digits = 17) { + if (p_value == 0.0) { + return "0"; // Avoid negative zero (-0) being written, which may annoy git, svn, etc. for changes when they don't exist. + } else if (isnan(p_value)) { + return "nan"; + } else if (isinf(p_value)) { + if (p_value > 0) { + return "inf"; + } else { + return "inf_neg"; + } + } else { + int digits = p_max_digits > 17 ? 17 : p_max_digits; + return String::num_scientific(p_value, digits); + } +} + +#define SERIALIZE_REAL(m_num) serialize_real(m_num, p_max_digits) + +Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_string_func, void *p_store_string_ud, EncodeResourceFunc p_encode_res_func, void *p_encode_res_ud, int p_recursion_count, bool p_compat, int p_max_digits) { switch (p_variant.get_type()) { case Variant::NIL: { p_store_string_func(p_store_string_ud, "null"); @@ -1959,7 +1981,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 = rtos_fix(p_variant.operator double()); + String s = SERIALIZE_REAL(p_variant.operator double()); if (s != "inf" && s != "inf_neg" && s != "nan") { if (!s.contains(".") && !s.contains("e")) { s += ".0"; @@ -1976,7 +1998,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str // Math types. case Variant::VECTOR2: { Vector2 v = p_variant; - p_store_string_func(p_store_string_ud, "Vector2(" + rtos_fix(v.x) + ", " + rtos_fix(v.y) + ")"); + p_store_string_func(p_store_string_ud, "Vector2(" + SERIALIZE_REAL(v.x) + ", " + SERIALIZE_REAL(v.y) + ")"); } break; case Variant::VECTOR2I: { Vector2i v = p_variant; @@ -1984,7 +2006,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str } break; case Variant::RECT2: { Rect2 aabb = p_variant; - p_store_string_func(p_store_string_ud, "Rect2(" + rtos_fix(aabb.position.x) + ", " + rtos_fix(aabb.position.y) + ", " + rtos_fix(aabb.size.x) + ", " + rtos_fix(aabb.size.y) + ")"); + p_store_string_func(p_store_string_ud, "Rect2(" + SERIALIZE_REAL(aabb.position.x) + ", " + SERIALIZE_REAL(aabb.position.y) + ", " + SERIALIZE_REAL(aabb.size.x) + ", " + SERIALIZE_REAL(aabb.size.y) + ")"); } break; case Variant::RECT2I: { Rect2i aabb = p_variant; @@ -1992,7 +2014,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str } break; case Variant::VECTOR3: { Vector3 v = p_variant; - p_store_string_func(p_store_string_ud, "Vector3(" + rtos_fix(v.x) + ", " + rtos_fix(v.y) + ", " + rtos_fix(v.z) + ")"); + p_store_string_func(p_store_string_ud, "Vector3(" + SERIALIZE_REAL(v.x) + ", " + SERIALIZE_REAL(v.y) + ", " + SERIALIZE_REAL(v.z) + ")"); } break; case Variant::VECTOR3I: { Vector3i v = p_variant; @@ -2000,7 +2022,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str } break; case Variant::VECTOR4: { Vector4 v = p_variant; - p_store_string_func(p_store_string_ud, "Vector4(" + rtos_fix(v.x) + ", " + rtos_fix(v.y) + ", " + rtos_fix(v.z) + ", " + rtos_fix(v.w) + ")"); + p_store_string_func(p_store_string_ud, "Vector4(" + SERIALIZE_REAL(v.x) + ", " + SERIALIZE_REAL(v.y) + ", " + SERIALIZE_REAL(v.z) + ", " + SERIALIZE_REAL(v.w) + ")"); } break; case Variant::VECTOR4I: { Vector4i v = p_variant; @@ -2008,15 +2030,15 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str } break; case Variant::PLANE: { Plane p = p_variant; - p_store_string_func(p_store_string_ud, "Plane(" + rtos_fix(p.normal.x) + ", " + rtos_fix(p.normal.y) + ", " + rtos_fix(p.normal.z) + ", " + rtos_fix(p.d) + ")"); + p_store_string_func(p_store_string_ud, "Plane(" + SERIALIZE_REAL(p.normal.x) + ", " + SERIALIZE_REAL(p.normal.y) + ", " + SERIALIZE_REAL(p.normal.z) + ", " + SERIALIZE_REAL(p.d) + ")"); } break; case Variant::AABB: { AABB aabb = p_variant; - p_store_string_func(p_store_string_ud, "AABB(" + rtos_fix(aabb.position.x) + ", " + rtos_fix(aabb.position.y) + ", " + rtos_fix(aabb.position.z) + ", " + rtos_fix(aabb.size.x) + ", " + rtos_fix(aabb.size.y) + ", " + rtos_fix(aabb.size.z) + ")"); + p_store_string_func(p_store_string_ud, "AABB(" + SERIALIZE_REAL(aabb.position.x) + ", " + SERIALIZE_REAL(aabb.position.y) + ", " + SERIALIZE_REAL(aabb.position.z) + ", " + SERIALIZE_REAL(aabb.size.x) + ", " + SERIALIZE_REAL(aabb.size.y) + ", " + SERIALIZE_REAL(aabb.size.z) + ")"); } break; case Variant::QUATERNION: { Quaternion quaternion = p_variant; - p_store_string_func(p_store_string_ud, "Quaternion(" + rtos_fix(quaternion.x) + ", " + rtos_fix(quaternion.y) + ", " + rtos_fix(quaternion.z) + ", " + rtos_fix(quaternion.w) + ")"); + p_store_string_func(p_store_string_ud, "Quaternion(" + SERIALIZE_REAL(quaternion.x) + ", " + SERIALIZE_REAL(quaternion.y) + ", " + SERIALIZE_REAL(quaternion.z) + ", " + SERIALIZE_REAL(quaternion.w) + ")"); } break; case Variant::TRANSFORM2D: { String s = "Transform2D("; @@ -2026,7 +2048,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str if (i != 0 || j != 0) { s += ", "; } - s += rtos_fix(m3.columns[i][j]); + s += SERIALIZE_REAL(m3.columns[i][j]); } } @@ -2040,7 +2062,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str if (i != 0 || j != 0) { s += ", "; } - s += rtos_fix(m3.rows[i][j]); + s += SERIALIZE_REAL(m3.rows[i][j]); } } @@ -2055,11 +2077,11 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str if (i != 0 || j != 0) { s += ", "; } - s += rtos_fix(m3.rows[i][j]); + s += SERIALIZE_REAL(m3.rows[i][j]); } } - s = s + ", " + rtos_fix(t.origin.x) + ", " + rtos_fix(t.origin.y) + ", " + rtos_fix(t.origin.z); + s = s + ", " + SERIALIZE_REAL(t.origin.x) + ", " + SERIALIZE_REAL(t.origin.y) + ", " + SERIALIZE_REAL(t.origin.z); p_store_string_func(p_store_string_ud, s + ")"); } break; @@ -2071,7 +2093,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str if (i != 0 || j != 0) { s += ", "; } - s += rtos_fix(t.columns[i][j]); + s += SERIALIZE_REAL(t.columns[i][j]); } } @@ -2081,7 +2103,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str // Misc types. case Variant::COLOR: { Color c = p_variant; - p_store_string_func(p_store_string_ud, "Color(" + rtos_fix(c.r) + ", " + rtos_fix(c.g) + ", " + rtos_fix(c.b) + ", " + rtos_fix(c.a) + ")"); + p_store_string_func(p_store_string_ud, "Color(" + SERIALIZE_REAL(c.r) + ", " + SERIALIZE_REAL(c.g) + ", " + SERIALIZE_REAL(c.b) + ", " + SERIALIZE_REAL(c.a) + ")"); } break; case Variant::STRING_NAME: { String str = p_variant; @@ -2396,7 +2418,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str if (i > 0) { p_store_string_func(p_store_string_ud, ", "); } - p_store_string_func(p_store_string_ud, rtos_fix(ptr[i])); + p_store_string_func(p_store_string_ud, SERIALIZE_REAL(ptr[i])); } p_store_string_func(p_store_string_ud, ")"); @@ -2411,7 +2433,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str if (i > 0) { p_store_string_func(p_store_string_ud, ", "); } - p_store_string_func(p_store_string_ud, rtos_fix(ptr[i])); + p_store_string_func(p_store_string_ud, SERIALIZE_REAL(ptr[i])); } p_store_string_func(p_store_string_ud, ")"); @@ -2441,7 +2463,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str if (i > 0) { p_store_string_func(p_store_string_ud, ", "); } - p_store_string_func(p_store_string_ud, rtos_fix(ptr[i].x) + ", " + rtos_fix(ptr[i].y)); + p_store_string_func(p_store_string_ud, SERIALIZE_REAL(ptr[i].x) + ", " + SERIALIZE_REAL(ptr[i].y)); } p_store_string_func(p_store_string_ud, ")"); @@ -2456,7 +2478,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str if (i > 0) { p_store_string_func(p_store_string_ud, ", "); } - p_store_string_func(p_store_string_ud, rtos_fix(ptr[i].x) + ", " + rtos_fix(ptr[i].y) + ", " + rtos_fix(ptr[i].z)); + p_store_string_func(p_store_string_ud, SERIALIZE_REAL(ptr[i].x) + ", " + SERIALIZE_REAL(ptr[i].y) + ", " + SERIALIZE_REAL(ptr[i].z)); } p_store_string_func(p_store_string_ud, ")"); @@ -2471,7 +2493,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str if (i > 0) { p_store_string_func(p_store_string_ud, ", "); } - p_store_string_func(p_store_string_ud, rtos_fix(ptr[i].r) + ", " + rtos_fix(ptr[i].g) + ", " + rtos_fix(ptr[i].b) + ", " + rtos_fix(ptr[i].a)); + p_store_string_func(p_store_string_ud, SERIALIZE_REAL(ptr[i].r) + ", " + SERIALIZE_REAL(ptr[i].g) + ", " + SERIALIZE_REAL(ptr[i].b) + ", " + SERIALIZE_REAL(ptr[i].a)); } p_store_string_func(p_store_string_ud, ")"); @@ -2486,7 +2508,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str if (i > 0) { p_store_string_func(p_store_string_ud, ", "); } - p_store_string_func(p_store_string_ud, rtos_fix(ptr[i].x) + ", " + rtos_fix(ptr[i].y) + ", " + rtos_fix(ptr[i].z) + ", " + rtos_fix(ptr[i].w)); + p_store_string_func(p_store_string_ud, SERIALIZE_REAL(ptr[i].x) + ", " + SERIALIZE_REAL(ptr[i].y) + ", " + SERIALIZE_REAL(ptr[i].z) + ", " + SERIALIZE_REAL(ptr[i].w)); } p_store_string_func(p_store_string_ud, ")"); @@ -2507,8 +2529,8 @@ static Error _write_to_str(void *ud, const String &p_string) { return OK; } -Error VariantWriter::write_to_string(const Variant &p_variant, String &r_string, EncodeResourceFunc p_encode_res_func, void *p_encode_res_ud, bool p_compat) { +Error VariantWriter::write_to_string(const Variant &p_variant, String &r_string, EncodeResourceFunc p_encode_res_func, void *p_encode_res_ud, bool p_compat, int p_max_digits) { r_string = String(); - return write(p_variant, _write_to_str, &r_string, p_encode_res_func, p_encode_res_ud, 0, p_compat); + return write(p_variant, _write_to_str, &r_string, p_encode_res_func, p_encode_res_ud, 0, p_compat, p_max_digits); } diff --git a/core/variant/variant_parser.h b/core/variant/variant_parser.h index b0ac07170da5..cbc9ea532a21 100644 --- a/core/variant/variant_parser.h +++ b/core/variant/variant_parser.h @@ -161,8 +161,8 @@ class VariantWriter { typedef Error (*StoreStringFunc)(void *ud, const String &p_string); typedef String (*EncodeResourceFunc)(void *ud, const Ref &p_resource); - static Error write(const Variant &p_variant, StoreStringFunc p_store_string_func, void *p_store_string_ud, EncodeResourceFunc p_encode_res_func, void *p_encode_res_ud, int p_recursion_count = 0, bool p_compat = true); - static Error write_to_string(const Variant &p_variant, String &r_string, EncodeResourceFunc p_encode_res_func = nullptr, void *p_encode_res_ud = nullptr, bool p_compat = true); + static Error write(const Variant &p_variant, StoreStringFunc p_store_string_func, void *p_store_string_ud, EncodeResourceFunc p_encode_res_func, void *p_encode_res_ud, int p_recursion_count = 0, bool p_compat = true, int p_max_digits = 17); + static Error write_to_string(const Variant &p_variant, String &r_string, EncodeResourceFunc p_encode_res_func = nullptr, void *p_encode_res_ud = nullptr, bool p_compat = true, int p_max_digits = 17); }; #endif // VARIANT_PARSER_H diff --git a/editor/doc_tools.cpp b/editor/doc_tools.cpp index 79e0c7ebd1bc..e4030e31f496 100644 --- a/editor/doc_tools.cpp +++ b/editor/doc_tools.cpp @@ -915,7 +915,8 @@ void DocTools::generate(BitField p_flags) { DocData::ConstantDoc constant; constant.name = E; Variant value = Variant::get_constant_value(Variant::Type(i), E); - constant.value = value.get_type() == Variant::INT ? itos(value) : value.get_construct_string().replace("\n", " "); + const int digits = 6; // Reduced precision is better for documentation, avoids unnecessary decimals. + constant.value = value.get_type() == Variant::INT ? itos(value) : value.get_construct_string(digits).replace("\n", " "); constant.is_value_valid = true; c.constants.push_back(constant); } diff --git a/misc/extension_api_validation/4.3-stable.expected b/misc/extension_api_validation/4.3-stable.expected index 960edd0575e7..5286db671e86 100644 --- a/misc/extension_api_validation/4.3-stable.expected +++ b/misc/extension_api_validation/4.3-stable.expected @@ -95,3 +95,156 @@ Validate extension JSON: Error: Field 'classes/InputMap/methods/add_action/argum Default deadzone value was changed. No adjustments should be necessary. Compatibility method registered. + + +GH-96676 +-------- +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/ALICE_BLUE': value changed value in new API, from "Color(0.941176, 0.972549, 1, 1)" to "Color(0.941176474, 0.972549021, 1, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/ANTIQUE_WHITE': value changed value in new API, from "Color(0.980392, 0.921569, 0.843137, 1)" to "Color(0.980392158, 0.921568632, 0.843137264, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/AQUAMARINE': value changed value in new API, from "Color(0.498039, 1, 0.831373, 1)" to "Color(0.498039216, 1, 0.831372559, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/AZURE': value changed value in new API, from "Color(0.941176, 1, 1, 1)" to "Color(0.941176474, 1, 1, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/BEIGE': value changed value in new API, from "Color(0.960784, 0.960784, 0.862745, 1)" to "Color(0.960784316, 0.960784316, 0.862745106, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/BISQUE': value changed value in new API, from "Color(1, 0.894118, 0.768627, 1)" to "Color(1, 0.894117653, 0.768627465, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/BLANCHED_ALMOND': value changed value in new API, from "Color(1, 0.921569, 0.803922, 1)" to "Color(1, 0.921568632, 0.80392158, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/BLUE_VIOLET': value changed value in new API, from "Color(0.541176, 0.168627, 0.886275, 1)" to "Color(0.541176498, 0.168627456, 0.886274517, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/BROWN': value changed value in new API, from "Color(0.647059, 0.164706, 0.164706, 1)" to "Color(0.647058845, 0.164705887, 0.164705887, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/BURLYWOOD': value changed value in new API, from "Color(0.870588, 0.721569, 0.529412, 1)" to "Color(0.870588243, 0.721568644, 0.529411793, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/CADET_BLUE': value changed value in new API, from "Color(0.372549, 0.619608, 0.627451, 1)" to "Color(0.372549027, 0.619607866, 0.627451003, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/CHARTREUSE': value changed value in new API, from "Color(0.498039, 1, 0, 1)" to "Color(0.498039216, 1, 0, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/CHOCOLATE': value changed value in new API, from "Color(0.823529, 0.411765, 0.117647, 1)" to "Color(0.823529422, 0.411764711, 0.117647059, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/CORAL': value changed value in new API, from "Color(1, 0.498039, 0.313726, 1)" to "Color(1, 0.498039216, 0.313725501, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/CORNFLOWER_BLUE': value changed value in new API, from "Color(0.392157, 0.584314, 0.929412, 1)" to "Color(0.392156869, 0.58431375, 0.929411769, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/CORNSILK': value changed value in new API, from "Color(1, 0.972549, 0.862745, 1)" to "Color(1, 0.972549021, 0.862745106, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/CRIMSON': value changed value in new API, from "Color(0.862745, 0.0784314, 0.235294, 1)" to "Color(0.862745106, 0.0784313753, 0.235294119, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/DARK_BLUE': value changed value in new API, from "Color(0, 0, 0.545098, 1)" to "Color(0, 0, 0.545098066, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/DARK_CYAN': value changed value in new API, from "Color(0, 0.545098, 0.545098, 1)" to "Color(0, 0.545098066, 0.545098066, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/DARK_GOLDENROD': value changed value in new API, from "Color(0.721569, 0.52549, 0.0431373, 1)" to "Color(0.721568644, 0.525490224, 0.0431372561, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/DARK_GRAY': value changed value in new API, from "Color(0.662745, 0.662745, 0.662745, 1)" to "Color(0.662745118, 0.662745118, 0.662745118, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/DARK_GREEN': value changed value in new API, from "Color(0, 0.392157, 0, 1)" to "Color(0, 0.392156869, 0, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/DARK_KHAKI': value changed value in new API, from "Color(0.741176, 0.717647, 0.419608, 1)" to "Color(0.741176486, 0.717647076, 0.419607848, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/DARK_MAGENTA': value changed value in new API, from "Color(0.545098, 0, 0.545098, 1)" to "Color(0.545098066, 0, 0.545098066, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/DARK_OLIVE_GREEN': value changed value in new API, from "Color(0.333333, 0.419608, 0.184314, 1)" to "Color(0.333333343, 0.419607848, 0.184313729, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/DARK_ORANGE': value changed value in new API, from "Color(1, 0.54902, 0, 1)" to "Color(1, 0.549019635, 0, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/DARK_ORCHID': value changed value in new API, from "Color(0.6, 0.196078, 0.8, 1)" to "Color(0.600000024, 0.196078435, 0.800000012, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/DARK_RED': value changed value in new API, from "Color(0.545098, 0, 0, 1)" to "Color(0.545098066, 0, 0, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/DARK_SALMON': value changed value in new API, from "Color(0.913725, 0.588235, 0.478431, 1)" to "Color(0.913725495, 0.588235319, 0.478431374, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/DARK_SEA_GREEN': value changed value in new API, from "Color(0.560784, 0.737255, 0.560784, 1)" to "Color(0.56078434, 0.737254918, 0.56078434, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/DARK_SLATE_BLUE': value changed value in new API, from "Color(0.282353, 0.239216, 0.545098, 1)" to "Color(0.282352954, 0.239215687, 0.545098066, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/DARK_SLATE_GRAY': value changed value in new API, from "Color(0.184314, 0.309804, 0.309804, 1)" to "Color(0.184313729, 0.309803933, 0.309803933, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/DARK_TURQUOISE': value changed value in new API, from "Color(0, 0.807843, 0.819608, 1)" to "Color(0, 0.807843149, 0.819607854, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/DARK_VIOLET': value changed value in new API, from "Color(0.580392, 0, 0.827451, 1)" to "Color(0.580392182, 0, 0.827450991, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/DEEP_PINK': value changed value in new API, from "Color(1, 0.0784314, 0.576471, 1)" to "Color(1, 0.0784313753, 0.576470613, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/DEEP_SKY_BLUE': value changed value in new API, from "Color(0, 0.74902, 1, 1)" to "Color(0, 0.749019623, 1, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/DIM_GRAY': value changed value in new API, from "Color(0.411765, 0.411765, 0.411765, 1)" to "Color(0.411764711, 0.411764711, 0.411764711, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/DODGER_BLUE': value changed value in new API, from "Color(0.117647, 0.564706, 1, 1)" to "Color(0.117647059, 0.564705908, 1, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/FIREBRICK': value changed value in new API, from "Color(0.698039, 0.133333, 0.133333, 1)" to "Color(0.698039234, 0.13333334, 0.13333334, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/FLORAL_WHITE': value changed value in new API, from "Color(1, 0.980392, 0.941176, 1)" to "Color(1, 0.980392158, 0.941176474, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/FOREST_GREEN': value changed value in new API, from "Color(0.133333, 0.545098, 0.133333, 1)" to "Color(0.13333334, 0.545098066, 0.13333334, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/GAINSBORO': value changed value in new API, from "Color(0.862745, 0.862745, 0.862745, 1)" to "Color(0.862745106, 0.862745106, 0.862745106, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/GHOST_WHITE': value changed value in new API, from "Color(0.972549, 0.972549, 1, 1)" to "Color(0.972549021, 0.972549021, 1, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/GOLD': value changed value in new API, from "Color(1, 0.843137, 0, 1)" to "Color(1, 0.843137264, 0, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/GOLDENROD': value changed value in new API, from "Color(0.854902, 0.647059, 0.12549, 1)" to "Color(0.854901969, 0.647058845, 0.125490203, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/GRAY': value changed value in new API, from "Color(0.745098, 0.745098, 0.745098, 1)" to "Color(0.745098054, 0.745098054, 0.745098054, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/GREEN_YELLOW': value changed value in new API, from "Color(0.678431, 1, 0.184314, 1)" to "Color(0.678431392, 1, 0.184313729, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/HONEYDEW': value changed value in new API, from "Color(0.941176, 1, 0.941176, 1)" to "Color(0.941176474, 1, 0.941176474, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/HOT_PINK': value changed value in new API, from "Color(1, 0.411765, 0.705882, 1)" to "Color(1, 0.411764711, 0.70588237, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/INDIAN_RED': value changed value in new API, from "Color(0.803922, 0.360784, 0.360784, 1)" to "Color(0.80392158, 0.360784322, 0.360784322, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/INDIGO': value changed value in new API, from "Color(0.294118, 0, 0.509804, 1)" to "Color(0.294117659, 0, 0.509803951, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/IVORY': value changed value in new API, from "Color(1, 1, 0.941176, 1)" to "Color(1, 1, 0.941176474, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/KHAKI': value changed value in new API, from "Color(0.941176, 0.901961, 0.54902, 1)" to "Color(0.941176474, 0.90196079, 0.549019635, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/LAVENDER': value changed value in new API, from "Color(0.901961, 0.901961, 0.980392, 1)" to "Color(0.90196079, 0.90196079, 0.980392158, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/LAVENDER_BLUSH': value changed value in new API, from "Color(1, 0.941176, 0.960784, 1)" to "Color(1, 0.941176474, 0.960784316, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/LAWN_GREEN': value changed value in new API, from "Color(0.486275, 0.988235, 0, 1)" to "Color(0.486274511, 0.988235295, 0, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/LEMON_CHIFFON': value changed value in new API, from "Color(1, 0.980392, 0.803922, 1)" to "Color(1, 0.980392158, 0.80392158, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/LIGHT_BLUE': value changed value in new API, from "Color(0.678431, 0.847059, 0.901961, 1)" to "Color(0.678431392, 0.847058833, 0.90196079, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/LIGHT_CORAL': value changed value in new API, from "Color(0.941176, 0.501961, 0.501961, 1)" to "Color(0.941176474, 0.501960814, 0.501960814, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/LIGHT_CYAN': value changed value in new API, from "Color(0.878431, 1, 1, 1)" to "Color(0.87843138, 1, 1, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/LIGHT_GOLDENROD': value changed value in new API, from "Color(0.980392, 0.980392, 0.823529, 1)" to "Color(0.980392158, 0.980392158, 0.823529422, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/LIGHT_GRAY': value changed value in new API, from "Color(0.827451, 0.827451, 0.827451, 1)" to "Color(0.827450991, 0.827450991, 0.827450991, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/LIGHT_GREEN': value changed value in new API, from "Color(0.564706, 0.933333, 0.564706, 1)" to "Color(0.564705908, 0.933333337, 0.564705908, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/LIGHT_PINK': value changed value in new API, from "Color(1, 0.713726, 0.756863, 1)" to "Color(1, 0.713725507, 0.75686276, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/LIGHT_SALMON': value changed value in new API, from "Color(1, 0.627451, 0.478431, 1)" to "Color(1, 0.627451003, 0.478431374, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/LIGHT_SEA_GREEN': value changed value in new API, from "Color(0.12549, 0.698039, 0.666667, 1)" to "Color(0.125490203, 0.698039234, 0.666666687, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/LIGHT_SKY_BLUE': value changed value in new API, from "Color(0.529412, 0.807843, 0.980392, 1)" to "Color(0.529411793, 0.807843149, 0.980392158, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/LIGHT_SLATE_GRAY': value changed value in new API, from "Color(0.466667, 0.533333, 0.6, 1)" to "Color(0.466666669, 0.533333361, 0.600000024, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/LIGHT_STEEL_BLUE': value changed value in new API, from "Color(0.690196, 0.768627, 0.870588, 1)" to "Color(0.690196097, 0.768627465, 0.870588243, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/LIGHT_YELLOW': value changed value in new API, from "Color(1, 1, 0.878431, 1)" to "Color(1, 1, 0.87843138, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/LIME_GREEN': value changed value in new API, from "Color(0.196078, 0.803922, 0.196078, 1)" to "Color(0.196078435, 0.80392158, 0.196078435, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/LINEN': value changed value in new API, from "Color(0.980392, 0.941176, 0.901961, 1)" to "Color(0.980392158, 0.941176474, 0.90196079, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/MAROON': value changed value in new API, from "Color(0.690196, 0.188235, 0.376471, 1)" to "Color(0.690196097, 0.188235298, 0.376470596, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/MEDIUM_AQUAMARINE': value changed value in new API, from "Color(0.4, 0.803922, 0.666667, 1)" to "Color(0.400000006, 0.80392158, 0.666666687, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/MEDIUM_BLUE': value changed value in new API, from "Color(0, 0, 0.803922, 1)" to "Color(0, 0, 0.80392158, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/MEDIUM_ORCHID': value changed value in new API, from "Color(0.729412, 0.333333, 0.827451, 1)" to "Color(0.729411781, 0.333333343, 0.827450991, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/MEDIUM_PURPLE': value changed value in new API, from "Color(0.576471, 0.439216, 0.858824, 1)" to "Color(0.576470613, 0.43921569, 0.858823538, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/MEDIUM_SEA_GREEN': value changed value in new API, from "Color(0.235294, 0.701961, 0.443137, 1)" to "Color(0.235294119, 0.701960802, 0.443137258, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/MEDIUM_SLATE_BLUE': value changed value in new API, from "Color(0.482353, 0.407843, 0.933333, 1)" to "Color(0.482352942, 0.407843143, 0.933333337, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/MEDIUM_SPRING_GREEN': value changed value in new API, from "Color(0, 0.980392, 0.603922, 1)" to "Color(0, 0.980392158, 0.603921592, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/MEDIUM_TURQUOISE': value changed value in new API, from "Color(0.282353, 0.819608, 0.8, 1)" to "Color(0.282352954, 0.819607854, 0.800000012, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/MEDIUM_VIOLET_RED': value changed value in new API, from "Color(0.780392, 0.0823529, 0.521569, 1)" to "Color(0.78039217, 0.0823529437, 0.521568656, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/MIDNIGHT_BLUE': value changed value in new API, from "Color(0.0980392, 0.0980392, 0.439216, 1)" to "Color(0.0980392173, 0.0980392173, 0.43921569, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/MINT_CREAM': value changed value in new API, from "Color(0.960784, 1, 0.980392, 1)" to "Color(0.960784316, 1, 0.980392158, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/MISTY_ROSE': value changed value in new API, from "Color(1, 0.894118, 0.882353, 1)" to "Color(1, 0.894117653, 0.882352948, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/MOCCASIN': value changed value in new API, from "Color(1, 0.894118, 0.709804, 1)" to "Color(1, 0.894117653, 0.709803939, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/NAVAJO_WHITE': value changed value in new API, from "Color(1, 0.870588, 0.678431, 1)" to "Color(1, 0.870588243, 0.678431392, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/NAVY_BLUE': value changed value in new API, from "Color(0, 0, 0.501961, 1)" to "Color(0, 0, 0.501960814, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/OLD_LACE': value changed value in new API, from "Color(0.992157, 0.960784, 0.901961, 1)" to "Color(0.992156863, 0.960784316, 0.90196079, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/OLIVE': value changed value in new API, from "Color(0.501961, 0.501961, 0, 1)" to "Color(0.501960814, 0.501960814, 0, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/OLIVE_DRAB': value changed value in new API, from "Color(0.419608, 0.556863, 0.137255, 1)" to "Color(0.419607848, 0.556862772, 0.137254909, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/ORANGE': value changed value in new API, from "Color(1, 0.647059, 0, 1)" to "Color(1, 0.647058845, 0, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/ORANGE_RED': value changed value in new API, from "Color(1, 0.270588, 0, 1)" to "Color(1, 0.270588249, 0, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/ORCHID': value changed value in new API, from "Color(0.854902, 0.439216, 0.839216, 1)" to "Color(0.854901969, 0.43921569, 0.839215696, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/PALE_GOLDENROD': value changed value in new API, from "Color(0.933333, 0.909804, 0.666667, 1)" to "Color(0.933333337, 0.909803927, 0.666666687, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/PALE_GREEN': value changed value in new API, from "Color(0.596078, 0.984314, 0.596078, 1)" to "Color(0.596078455, 0.984313726, 0.596078455, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/PALE_TURQUOISE': value changed value in new API, from "Color(0.686275, 0.933333, 0.933333, 1)" to "Color(0.686274529, 0.933333337, 0.933333337, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/PALE_VIOLET_RED': value changed value in new API, from "Color(0.858824, 0.439216, 0.576471, 1)" to "Color(0.858823538, 0.43921569, 0.576470613, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/PAPAYA_WHIP': value changed value in new API, from "Color(1, 0.937255, 0.835294, 1)" to "Color(1, 0.937254906, 0.835294127, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/PEACH_PUFF': value changed value in new API, from "Color(1, 0.854902, 0.72549, 1)" to "Color(1, 0.854901969, 0.725490212, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/PERU': value changed value in new API, from "Color(0.803922, 0.521569, 0.247059, 1)" to "Color(0.80392158, 0.521568656, 0.247058824, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/PINK': value changed value in new API, from "Color(1, 0.752941, 0.796078, 1)" to "Color(1, 0.752941191, 0.796078444, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/PLUM': value changed value in new API, from "Color(0.866667, 0.627451, 0.866667, 1)" to "Color(0.866666675, 0.627451003, 0.866666675, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/POWDER_BLUE': value changed value in new API, from "Color(0.690196, 0.878431, 0.901961, 1)" to "Color(0.690196097, 0.87843138, 0.90196079, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/PURPLE': value changed value in new API, from "Color(0.627451, 0.12549, 0.941176, 1)" to "Color(0.627451003, 0.125490203, 0.941176474, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/REBECCA_PURPLE': value changed value in new API, from "Color(0.4, 0.2, 0.6, 1)" to "Color(0.400000006, 0.200000003, 0.600000024, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/ROSY_BROWN': value changed value in new API, from "Color(0.737255, 0.560784, 0.560784, 1)" to "Color(0.737254918, 0.56078434, 0.56078434, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/ROYAL_BLUE': value changed value in new API, from "Color(0.254902, 0.411765, 0.882353, 1)" to "Color(0.254901975, 0.411764711, 0.882352948, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/SADDLE_BROWN': value changed value in new API, from "Color(0.545098, 0.270588, 0.0745098, 1)" to "Color(0.545098066, 0.270588249, 0.0745098069, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/SALMON': value changed value in new API, from "Color(0.980392, 0.501961, 0.447059, 1)" to "Color(0.980392158, 0.501960814, 0.447058827, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/SANDY_BROWN': value changed value in new API, from "Color(0.956863, 0.643137, 0.376471, 1)" to "Color(0.956862748, 0.643137276, 0.376470596, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/SEASHELL': value changed value in new API, from "Color(1, 0.960784, 0.933333, 1)" to "Color(1, 0.960784316, 0.933333337, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/SEA_GREEN': value changed value in new API, from "Color(0.180392, 0.545098, 0.341176, 1)" to "Color(0.180392161, 0.545098066, 0.34117648, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/SIENNA': value changed value in new API, from "Color(0.627451, 0.321569, 0.176471, 1)" to "Color(0.627451003, 0.321568638, 0.176470593, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/SILVER': value changed value in new API, from "Color(0.752941, 0.752941, 0.752941, 1)" to "Color(0.752941191, 0.752941191, 0.752941191, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/SKY_BLUE': value changed value in new API, from "Color(0.529412, 0.807843, 0.921569, 1)" to "Color(0.529411793, 0.807843149, 0.921568632, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/SLATE_BLUE': value changed value in new API, from "Color(0.415686, 0.352941, 0.803922, 1)" to "Color(0.41568628, 0.352941185, 0.80392158, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/SLATE_GRAY': value changed value in new API, from "Color(0.439216, 0.501961, 0.564706, 1)" to "Color(0.43921569, 0.501960814, 0.564705908, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/SNOW': value changed value in new API, from "Color(1, 0.980392, 0.980392, 1)" to "Color(1, 0.980392158, 0.980392158, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/SPRING_GREEN': value changed value in new API, from "Color(0, 1, 0.498039, 1)" to "Color(0, 1, 0.498039216, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/STEEL_BLUE': value changed value in new API, from "Color(0.27451, 0.509804, 0.705882, 1)" to "Color(0.274509817, 0.509803951, 0.70588237, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/TAN': value changed value in new API, from "Color(0.823529, 0.705882, 0.54902, 1)" to "Color(0.823529422, 0.70588237, 0.549019635, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/TEAL': value changed value in new API, from "Color(0, 0.501961, 0.501961, 1)" to "Color(0, 0.501960814, 0.501960814, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/THISTLE': value changed value in new API, from "Color(0.847059, 0.74902, 0.847059, 1)" to "Color(0.847058833, 0.749019623, 0.847058833, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/TOMATO': value changed value in new API, from "Color(1, 0.388235, 0.278431, 1)" to "Color(1, 0.388235301, 0.278431386, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/TURQUOISE': value changed value in new API, from "Color(0.25098, 0.878431, 0.815686, 1)" to "Color(0.250980407, 0.87843138, 0.815686285, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/VIOLET': value changed value in new API, from "Color(0.933333, 0.509804, 0.933333, 1)" to "Color(0.933333337, 0.509803951, 0.933333337, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/WEB_GRAY': value changed value in new API, from "Color(0.501961, 0.501961, 0.501961, 1)" to "Color(0.501960814, 0.501960814, 0.501960814, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/WEB_GREEN': value changed value in new API, from "Color(0, 0.501961, 0, 1)" to "Color(0, 0.501960814, 0, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/WEB_MAROON': value changed value in new API, from "Color(0.501961, 0, 0, 1)" to "Color(0.501960814, 0, 0, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/WEB_PURPLE': value changed value in new API, from "Color(0.501961, 0, 0.501961, 1)" to "Color(0.501960814, 0, 0.501960814, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/WHEAT': value changed value in new API, from "Color(0.960784, 0.870588, 0.701961, 1)" to "Color(0.960784316, 0.870588243, 0.701960802, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/WHITE_SMOKE': value changed value in new API, from "Color(0.960784, 0.960784, 0.960784, 1)" to "Color(0.960784316, 0.960784316, 0.960784316, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Color/constants/YELLOW_GREEN': value changed value in new API, from "Color(0.603922, 0.803922, 0.196078, 1)" to "Color(0.603921592, 0.80392158, 0.196078435, 1)". +Validate extension JSON: Error: Field 'builtin_classes/Plane/methods/has_point/arguments/1': default_value changed value in new API, from "1e-05" to "1.0000000000000001e-05". +Validate extension JSON: Error: Field 'classes/BitMap/methods/create_from_image_alpha/arguments/1': default_value changed value in new API, from "0.1" to "0.10000000000000001". +Validate extension JSON: Error: Field 'classes/Curve3D/methods/tessellate_even_length/arguments/1': default_value changed value in new API, from "0.2" to "0.20000000000000001". +Validate extension JSON: Error: Field 'classes/EditorInterface/methods/popup_dialog_centered_ratio/arguments/1': default_value changed value in new API, from "0.8" to "0.80000000000000004". +Validate extension JSON: Error: Field 'classes/GridMap/methods/make_baked_meshes/arguments/1': default_value changed value in new API, from "0.1" to "0.10000000000000001". +Validate extension JSON: Error: Field 'classes/Noise/methods/get_seamless_image/arguments/4': default_value changed value in new API, from "0.1" to "0.10000000000000001". +Validate extension JSON: Error: Field 'classes/Noise/methods/get_seamless_image_3d/arguments/4': default_value changed value in new API, from "0.1" to "0.10000000000000001". +Validate extension JSON: Error: Field 'classes/PhysicsBody2D/methods/move_and_collide/arguments/2': default_value changed value in new API, from "0.08" to "0.080000000000000002". +Validate extension JSON: Error: Field 'classes/PhysicsBody2D/methods/test_move/arguments/3': default_value changed value in new API, from "0.08" to "0.080000000000000002". +Validate extension JSON: Error: Field 'classes/PortableCompressedTexture2D/methods/create_from_image/arguments/3': default_value changed value in new API, from "0.8" to "0.80000000000000004". +Validate extension JSON: Error: Field 'classes/Window/methods/popup_centered_ratio/arguments/0': default_value changed value in new API, from "0.8" to "0.80000000000000004". +Validate extension JSON: Error: Field 'classes/Window/methods/popup_exclusive_centered_ratio/arguments/1': default_value changed value in new API, from "0.8" to "0.80000000000000004". +Validate extension JSON: Error: Field 'classes/InputMap/methods/add_action/arguments/1': default_value changed value in new API, from "0.5" to "0.20000000298023224". + +Precision of string-serialized Variant constants increased. diff --git a/modules/gdscript/editor/gdscript_docgen.cpp b/modules/gdscript/editor/gdscript_docgen.cpp index 32ef429b0d47..1b23049cfa42 100644 --- a/modules/gdscript/editor/gdscript_docgen.cpp +++ b/modules/gdscript/editor/gdscript_docgen.cpp @@ -283,8 +283,10 @@ String GDScriptDocGen::_docvalue_from_variant(const Variant &p_variant, int p_re return result; } break; - default: - return p_variant.get_construct_string(); + default: { + const int digits = 6; // Reduced precision is better for documentation, avoids unnecessary decimals. + return p_variant.get_construct_string(digits); + } break; } } diff --git a/tests/core/string/test_string.h b/tests/core/string/test_string.h index 8559737e74f2..3d888e805d1f 100644 --- a/tests/core/string/test_string.h +++ b/tests/core/string/test_string.h @@ -460,12 +460,18 @@ TEST_CASE("[String] Number to string") { CHECK(String::num(-0.0) == "-0"); // Includes sign even for zero. CHECK(String::num(3.141593) == "3.141593"); CHECK(String::num(3.141593, 3) == "3.142"); - CHECK(String::num_scientific(30000000) == "3e+07"); CHECK(String::num_int64(3141593) == "3141593"); CHECK(String::num_int64(0xA141593, 16) == "a141593"); CHECK(String::num_int64(0xA141593, 16, true) == "A141593"); CHECK(String::num(42.100023, 4) == "42.1"); // No trailing zeros. + // String::num_scientific tests. + CHECK(String::num_scientific(30000000.0) == "3e+07"); + CHECK(String::num_scientific(1234567890.0) == "1.23457e+09"); + CHECK(String::num_scientific(1234567890.0, 3) == "1.23e+09"); + CHECK(String::num_scientific(1234567890.0, 9) == "1.23456789e+09"); + CHECK(String::num_scientific(1234567890.0, 14) == "1234567890"); + // String::num_real tests. CHECK(String::num_real(1.0) == "1.0"); CHECK(String::num_real(1.0, false) == "1"); diff --git a/tests/core/variant/test_variant.h b/tests/core/variant/test_variant.h index be615975f889..7b8fc8c8f2fb 100644 --- a/tests/core/variant/test_variant.h +++ b/tests/core/variant/test_variant.h @@ -102,7 +102,7 @@ TEST_CASE("[Variant] Writer and parser Variant::FLOAT") { String a64_str; VariantWriter::write_to_string(a64, a64_str); - CHECK_MESSAGE(a64_str == "1.79769e+308", "Writes in scientific notation."); + CHECK_MESSAGE(a64_str == "1.7976931348623157e+308", "Writes in scientific notation."); CHECK_MESSAGE(a64_str != "inf", "Should not overflow."); CHECK_MESSAGE(a64_str != "nan", "The result should be defined."); @@ -116,7 +116,7 @@ TEST_CASE("[Variant] Writer and parser Variant::FLOAT") { VariantParser::parse(&bss, variant_parsed, errs, line); float_parsed = variant_parsed; // Loses precision, but that's alright. - CHECK_MESSAGE(float_parsed == 1.79769e+308, "Should parse back."); + CHECK_MESSAGE(float_parsed == 1.797693134862315708145274237317e+308, "Should parse back."); // Approximation of Googol with a double-precision float. VariantParser::StreamString css; @@ -1737,6 +1737,45 @@ TEST_CASE("[Variant] Assignment To Color from Bool,Int,Float,String,Vec2,Vec2i,V CHECK(object_v.get_type() == Variant::COLOR); } +TEST_CASE("[Variant] Writer and parser Vector2") { + Variant vec2_parsed; + String vec2_str; + String errs; + int line; + // Variant::VECTOR2 and Vector2 can be either 32-bit or 64-bit depending on the precision level of real_t. + { + Vector2 vec2 = Vector2(1.2, 3.4); + VariantWriter::write_to_string(vec2, vec2_str); + // Reminder: "1.2" and "3.4" are not exactly those decimal numbers. They are the closest float to them. + // Therefore, the serialized version, which includes unreliable digits, is not guaranteed to be exactly "1.2" and "3.4". + // However, a better algorithm would look for the closest decimal representation that would parse back to the same float. + // If such a better algorithm is implemented, the test should be updated. +#ifdef REAL_T_IS_DOUBLE + CHECK_MESSAGE(vec2_str == "Vector2(1.2, 3.3999999999999999)", "Should write with enough digits to ensure parsing back is exact."); +#else + CHECK_MESSAGE(vec2_str == "Vector2(1.20000005, 3.4000001)", "Should write with enough digits to ensure parsing back is exact."); +#endif + VariantParser::StreamString stream; + stream.s = vec2_str; + VariantParser::parse(&stream, vec2_parsed, errs, line); + CHECK_MESSAGE(Vector2(vec2_parsed) == vec2, "Should parse back to the same Vector2."); + } + // Check with big numbers and small numbers. + { + Vector2 vec2 = Vector2(1.234567898765432123456789e30, 1.234567898765432123456789e-10); + VariantWriter::write_to_string(vec2, vec2_str); +#ifdef REAL_T_IS_DOUBLE + CHECK_MESSAGE(vec2_str == "Vector2(1.2345678987654322e+30, 1.2345678987654322e-10)", "Should write with enough digits to ensure parsing back is exact."); +#else + CHECK_MESSAGE(vec2_str == "Vector2(1.23456789e+30, 1.23456786e-10)", "Should write with enough digits to ensure parsing back is exact."); +#endif + VariantParser::StreamString stream; + stream.s = vec2_str; + VariantParser::parse(&stream, vec2_parsed, errs, line); + CHECK_MESSAGE(Vector2(vec2_parsed) == vec2, "Should parse back to the same Vector2."); + } +} + TEST_CASE("[Variant] Writer and parser array") { Array a = build_array(1, String("hello"), build_array(Variant())); String a_str;