diff --git a/core/string/ustring.cpp b/core/string/ustring.cpp index c879cf990082..519d4d998cc0 100644 --- a/core/string/ustring.cpp +++ b/core/string/ustring.cpp @@ -1600,14 +1600,14 @@ String String::chr(char32_t p_char) { String String::num(double p_num, int p_decimals) { if (Math::is_nan(p_num)) { - return "nan"; + return "NAN"; } if (Math::is_inf(p_num)) { if (signbit(p_num)) { - return "-inf"; + return "-INF"; } else { - return "inf"; + return "INF"; } } diff --git a/core/variant/variant_parser.cpp b/core/variant/variant_parser.cpp index 3ce242d49c9d..c8d6c1e3d3f5 100644 --- a/core/variant/variant_parser.cpp +++ b/core/variant/variant_parser.cpp @@ -146,11 +146,12 @@ const char *VariantParser::tk_name[TK_MAX] = { }; static double stor_fix(const String &p_str) { - if (p_str == "inf") { + // Lower-case inf, inf_neg, and nan kept for compatibility. + if (p_str == "INF" || p_str == "inf") { return INFINITY; - } else if (p_str == "inf_neg") { + } else if (p_str == "-INF" || p_str == "inf_neg") { return -INFINITY; - } else if (p_str == "nan") { + } else if (p_str == "NAN" || p_str == "nan") { return NAN; } return -1; @@ -411,11 +412,13 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri if (cchar <= 32) { break; } - - if (cchar == '-' || (cchar >= '0' && cchar <= '9')) { + StringBuffer<> token_text; + if (cchar == '-') { + token_text += '-'; + cchar = p_stream->get_char(); + } + if (cchar >= '0' && cchar <= '9') { //a number - - StringBuffer<> num; #define READING_SIGN 0 #define READING_INT 1 #define READING_DEC 2 @@ -423,11 +426,6 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri #define READING_DONE 4 int reading = READING_INT; - if (cchar == '-') { - num += '-'; - cchar = p_stream->get_char(); - } - char32_t c = cchar; bool exp_sign = false; bool exp_beg = false; @@ -474,7 +472,7 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri if (reading == READING_DONE) { break; } - num += c; + token_text += c; c = p_stream->get_char(); } @@ -483,17 +481,16 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri r_token.type = TK_NUMBER; if (is_float) { - r_token.value = num.as_double(); + r_token.value = token_text.as_double(); } else { - r_token.value = num.as_int(); + r_token.value = token_text.as_int(); } return OK; } else if (is_ascii_alphabet_char(cchar) || is_underscore(cchar)) { - StringBuffer<> id; bool first = true; while (is_ascii_alphabet_char(cchar) || is_underscore(cchar) || (!first && is_digit(cchar))) { - id += cchar; + token_text += cchar; cchar = p_stream->get_char(); first = false; } @@ -501,7 +498,7 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri p_stream->saved = cchar; r_token.type = TK_IDENTIFIER; - r_token.value = id.as_string(); + r_token.value = token_text.as_string(); return OK; } else { r_err_str = "Unexpected character"; @@ -697,11 +694,12 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream, value = false; } else if (id == "null" || id == "nil") { value = Variant(); - } else if (id == "inf") { + } else if (id == "INF" || id == "inf") { + // Lower-case inf, inf_neg, and nan kept for compatibility. value = INFINITY; - } else if (id == "inf_neg") { + } else if (id == "-INF" || id == "inf_neg") { value = -INFINITY; - } else if (id == "nan") { + } else if (id == "NAN" || id == "nan") { value = NAN; } else if (id == "Vector2") { Vector args; @@ -1936,12 +1934,12 @@ static String rtos_fix(double p_value) { 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"; + return "NAN"; } else if (isinf(p_value)) { if (p_value > 0) { - return "inf"; + return "INF"; } else { - return "inf_neg"; + return "-INF"; } } else { return rtoss(p_value); @@ -1961,7 +1959,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str } break; case Variant::FLOAT: { String s = rtos_fix(p_variant.operator double()); - if (s != "inf" && s != "inf_neg" && s != "nan") { + if (s != "INF" && s != "-INF" && s != "NAN") { if (!s.contains_char('.') && !s.contains_char('e')) { s += ".0"; } diff --git a/doc/classes/Vector2.xml b/doc/classes/Vector2.xml index 75f1d511275a..fe5612cd3b0a 100644 --- a/doc/classes/Vector2.xml +++ b/doc/classes/Vector2.xml @@ -436,7 +436,7 @@ One vector, a vector with all components set to [code]1[/code]. - + Infinity vector, a vector with all components set to [constant @GDScript.INF]. diff --git a/doc/classes/Vector3.xml b/doc/classes/Vector3.xml index dd86c4b2874d..729fe882c3b8 100644 --- a/doc/classes/Vector3.xml +++ b/doc/classes/Vector3.xml @@ -436,7 +436,7 @@ One vector, a vector with all components set to [code]1[/code]. - + Infinity vector, a vector with all components set to [constant @GDScript.INF]. diff --git a/doc/classes/Vector4.xml b/doc/classes/Vector4.xml index bc5201baac56..b609cf45cdb6 100644 --- a/doc/classes/Vector4.xml +++ b/doc/classes/Vector4.xml @@ -305,7 +305,7 @@ One vector, a vector with all components set to [code]1[/code]. - + Infinity vector, a vector with all components set to [constant @GDScript.INF]. diff --git a/misc/extension_api_validation/4.3-stable.expected b/misc/extension_api_validation/4.3-stable.expected index 7b5889f464b9..14691f6e7548 100644 --- a/misc/extension_api_validation/4.3-stable.expected +++ b/misc/extension_api_validation/4.3-stable.expected @@ -309,3 +309,12 @@ Validate extension JSON: API was removed: classes/EditorSceneFormatImporter/meth This virtual method, and the internal public `get_import_flags`, were never used by the engine, since it was open sourced. So we're removing it despite the compat breakage as there's no way for users to rely on this affecting engine behavior. + + +GH-100414 +--------- +Validate extension JSON: Error: Field 'builtin_classes/Vector2/constants/INF': value changed value in new API, from "Vector2(inf, inf)" to "Vector2(INF, INF)". +Validate extension JSON: Error: Field 'builtin_classes/Vector3/constants/INF': value changed value in new API, from "Vector3(inf, inf, inf)" to "Vector3(INF, INF, INF)". +Validate extension JSON: Error: Field 'builtin_classes/Vector4/constants/INF': value changed value in new API, from "Vector4(inf, inf, inf, inf)" to "Vector4(INF, INF, INF, INF)". + +Infinity is now serialized as "INF" instead of "inf". diff --git a/modules/gdscript/doc_classes/@GDScript.xml b/modules/gdscript/doc_classes/@GDScript.xml index caed2a808d45..f022f6987b86 100644 --- a/modules/gdscript/doc_classes/@GDScript.xml +++ b/modules/gdscript/doc_classes/@GDScript.xml @@ -272,11 +272,11 @@ The circle constant, the circumference of the unit circle in radians. This is equivalent to [code]PI * 2[/code], or 360 degrees in rotations. - + Positive floating-point infinity. This is the result of floating-point division when the divisor is [code]0.0[/code]. For negative infinity, use [code]-INF[/code]. Dividing by [code]-0.0[/code] will result in negative infinity if the numerator is positive, so dividing by [code]0.0[/code] is not the same as dividing by [code]-0.0[/code] (despite [code]0.0 == -0.0[/code] returning [code]true[/code]). [b]Warning:[/b] Numeric infinity is only a concept with floating-point numbers, and has no equivalent for integers. Dividing an integer number by [code]0[/code] will not result in [constant INF] and will result in a run-time error instead. - + "Not a Number", an invalid floating-point value. [constant NAN] has special properties, including that [code]!=[/code] always returns [code]true[/code], while other comparison operators always return [code]false[/code]. This is true even when comparing with itself ([code]NAN == NAN[/code] returns [code]false[/code] and [code]NAN != NAN[/code] returns [code]true[/code]). It is returned by some invalid operations, such as dividing floating-point [code]0.0[/code] by [code]0.0[/code]. [b]Warning:[/b] "Not a Number" is only a concept with floating-point numbers, and has no equivalent for integers. Dividing an integer [code]0[/code] by [code]0[/code] will not result in [constant NAN] and will result in a run-time error instead. diff --git a/modules/gltf/doc_classes/GLTFLight.xml b/modules/gltf/doc_classes/GLTFLight.xml index e07d24a14463..9258bbdb703d 100644 --- a/modules/gltf/doc_classes/GLTFLight.xml +++ b/modules/gltf/doc_classes/GLTFLight.xml @@ -69,7 +69,7 @@ The outer angle of the cone in a spotlight. Must be greater than or equal to the inner angle. At this angle, the light drops off to zero brightness. Between the inner and outer cone angles, there is a transition from full brightness to zero brightness. If this angle is a half turn, then the spotlight emits in all directions. When creating a Godot [SpotLight3D], the outer cone angle is used as the angle of the spotlight. - + The range of the light, beyond which the light has no effect. glTF lights with no range defined behave like physical lights (which have infinite range). When creating a Godot light, the range is clamped to 4096. diff --git a/scene/gui/range.cpp b/scene/gui/range.cpp index d7b1a4933d02..9b76f2b8e1b5 100644 --- a/scene/gui/range.cpp +++ b/scene/gui/range.cpp @@ -94,10 +94,6 @@ void Range::set_value(double p_val) { } void Range::_set_value_no_signal(double p_val) { - if (!Math::is_finite(p_val)) { - return; - } - if (shared->step > 0) { p_val = Math::round((p_val - shared->min) / shared->step) * shared->step + shared->min; } diff --git a/tests/core/string/test_string.h b/tests/core/string/test_string.h index ea60230947d0..ed0533961972 100644 --- a/tests/core/string/test_string.h +++ b/tests/core/string/test_string.h @@ -923,7 +923,7 @@ TEST_CASE("[String] sprintf") { args.push_back(INFINITY); output = format.sprintf(args, &error); REQUIRE(error == false); - CHECK(output == String("fish inf frog")); + CHECK(output == String("fish INF frog")); // Real right-padded. format = "fish %-11f frog"; @@ -1041,13 +1041,13 @@ TEST_CASE("[String] sprintf") { REQUIRE(error == false); CHECK(output == String("fish ( 19.990000, 1.000000, -2.050000) frog")); - // Vector left-padded with inf/nan + // Vector left-padded with INF/NAN format = "fish %11v frog"; args.clear(); args.push_back(Variant(Vector2(INFINITY, NAN))); output = format.sprintf(args, &error); REQUIRE(error == false); - CHECK(output == String("fish ( inf, nan) frog")); + CHECK(output == String("fish ( INF, NAN) frog")); // Vector right-padded. format = "fish %-11v frog"; diff --git a/tests/core/variant/test_variant.h b/tests/core/variant/test_variant.h index 599a282b2009..72507b77893b 100644 --- a/tests/core/variant/test_variant.h +++ b/tests/core/variant/test_variant.h @@ -103,8 +103,8 @@ TEST_CASE("[Variant] Writer and parser Variant::FLOAT") { VariantWriter::write_to_string(a64, a64_str); CHECK_MESSAGE(a64_str == "1.79769e+308", "Writes in scientific notation."); - CHECK_MESSAGE(a64_str != "inf", "Should not overflow."); - CHECK_MESSAGE(a64_str != "nan", "The result should be defined."); + CHECK_MESSAGE(a64_str != "INF", "Should not overflow."); + CHECK_MESSAGE(a64_str != "NAN", "The result should be defined."); String errs; int line;