diff --git a/core/extension/extension_api_dump.cpp b/core/extension/extension_api_dump.cpp index 69be2d2a8f69..40be118884f8 100644 --- a/core/extension/extension_api_dump.cpp +++ b/core/extension/extension_api_dump.cpp @@ -1356,6 +1356,9 @@ static bool compare_dict_array(const Dictionary &p_old_api, const Dictionary &p_ Dictionary elem = var; ERR_FAIL_COND_V_MSG(!elem.has(p_name_field), false, vformat("Validate extension JSON: Element of base_array '%s' is missing field '%s'. This is a bug.", base_array, p_name_field)); String name = elem[p_name_field]; + if (name.is_valid_float()) { + name = name.trim_suffix(".0"); // Make "integers" stringified as integers. + } if (p_compare_operators && elem.has("right_type")) { name += " " + String(elem["right_type"]); } @@ -1371,6 +1374,9 @@ static bool compare_dict_array(const Dictionary &p_old_api, const Dictionary &p_ continue; } String name = old_elem[p_name_field]; + if (name.is_valid_float()) { + name = name.trim_suffix(".0"); // Make "integers" stringified as integers. + } if (p_compare_operators && old_elem.has("right_type")) { name += " " + String(old_elem["right_type"]); } diff --git a/core/math/rect2.cpp b/core/math/rect2.cpp index c55226a57ece..7f77b0786c2c 100644 --- a/core/math/rect2.cpp +++ b/core/math/rect2.cpp @@ -283,7 +283,7 @@ bool Rect2::intersects_transformed(const Transform2D &p_xform, const Rect2 &p_re } Rect2::operator String() const { - return "[P: " + position.operator String() + ", S: " + size + "]"; + return "[P: " + position.operator String() + ", S: " + size.operator String() + "]"; } Rect2::operator Rect2i() const { diff --git a/core/math/vector2.cpp b/core/math/vector2.cpp index 198fd85d205b..8f6f909fbd37 100644 --- a/core/math/vector2.cpp +++ b/core/math/vector2.cpp @@ -191,7 +191,7 @@ bool Vector2::is_finite() const { } Vector2::operator String() const { - return "(" + String::num_real(x, false) + ", " + String::num_real(y, false) + ")"; + return "(" + String::num_real(x, true) + ", " + String::num_real(y, true) + ")"; } Vector2::operator Vector2i() const { diff --git a/core/math/vector3.cpp b/core/math/vector3.cpp index fad5f2c0fb88..1fffefd446f0 100644 --- a/core/math/vector3.cpp +++ b/core/math/vector3.cpp @@ -146,7 +146,7 @@ bool Vector3::is_finite() const { } Vector3::operator String() const { - return "(" + String::num_real(x, false) + ", " + String::num_real(y, false) + ", " + String::num_real(z, false) + ")"; + return "(" + String::num_real(x, true) + ", " + String::num_real(y, true) + ", " + String::num_real(z, true) + ")"; } Vector3::operator Vector3i() const { diff --git a/core/string/ustring.cpp b/core/string/ustring.cpp index 2b62b72a51ad..5ea504ab2940 100644 --- a/core/string/ustring.cpp +++ b/core/string/ustring.cpp @@ -1603,7 +1603,7 @@ String String::num(double p_num, int p_decimals) { #endif buf[324] = 0; - //destroy trailing zeroes + // Destroy trailing zeroes, except one after period. { bool period = false; int z = 0; @@ -1620,7 +1620,7 @@ String String::num(double p_num, int p_decimals) { if (buf[z] == '0') { buf[z] = 0; } else if (buf[z] == '.') { - buf[z] = 0; + buf[z + 1] = '0'; break; } else { break; @@ -1709,14 +1709,28 @@ String String::num_real(double p_num, bool p_trailing) { return num_int64((int64_t)p_num); } } -#ifdef REAL_T_IS_DOUBLE int decimals = 14; -#else + // We want to align the digits to the above sane default, so we only need + // to subtract log10 for numbers with a positive power of ten magnitude. + const double abs_num = Math::abs(p_num); + if (abs_num > 10) { + decimals -= (int)floor(log10(abs_num)); + } + return num(p_num, decimals); +} + +String String::num_real(float p_num, bool p_trailing) { + if (p_num == (float)(int64_t)p_num) { + if (p_trailing) { + return num_int64((int64_t)p_num) + ".0"; + } else { + return num_int64((int64_t)p_num); + } + } int decimals = 6; -#endif // We want to align the digits to the above sane default, so we only need // to subtract log10 for numbers with a positive power of ten magnitude. - double abs_num = Math::abs(p_num); + const float abs_num = Math::abs(p_num); if (abs_num > 10) { decimals -= (int)floor(log10(abs_num)); } @@ -4025,7 +4039,7 @@ String String::humanize_size(uint64_t p_size) { } if (magnitude == 0) { - return String::num(p_size) + " " + RTR("B"); + return String::num_uint64(p_size) + " " + RTR("B"); } else { String suffix; switch (magnitude) { diff --git a/core/string/ustring.h b/core/string/ustring.h index 693df6dcbabd..c99ba4583df7 100644 --- a/core/string/ustring.h +++ b/core/string/ustring.h @@ -323,6 +323,7 @@ class String { static String num(double p_num, int p_decimals = -1); static String num_scientific(double p_num); static String num_real(double p_num, bool p_trailing = true); + static String num_real(float 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); static String chr(char32_t p_char); diff --git a/core/variant/variant.cpp b/core/variant/variant.cpp index 155a5b27817c..4fc0d9b662b0 100644 --- a/core/variant/variant.cpp +++ b/core/variant/variant.cpp @@ -1678,7 +1678,7 @@ String Variant::stringify(int recursion_count) const { case INT: return itos(_data._int); case FLOAT: - return rtos(_data._float); + return String::num_real(_data._float, true); case STRING: return *reinterpret_cast(_data._mem); case VECTOR2: diff --git a/modules/gdscript/tests/scripts/analyzer/features/class_inference_is_weak.out b/modules/gdscript/tests/scripts/analyzer/features/class_inference_is_weak.out index 94e2ec2af87f..fb616f1e94a3 100644 --- a/modules/gdscript/tests/scripts/analyzer/features/class_inference_is_weak.out +++ b/modules/gdscript/tests/scripts/analyzer/features/class_inference_is_weak.out @@ -1,2 +1,2 @@ GDTEST_OK -0 +0.0 diff --git a/modules/gdscript/tests/scripts/analyzer/features/const_conversions.gd b/modules/gdscript/tests/scripts/analyzer/features/const_conversions.gd index bed9dd0e96c8..cdcf16452d63 100644 --- a/modules/gdscript/tests/scripts/analyzer/features/const_conversions.gd +++ b/modules/gdscript/tests/scripts/analyzer/features/const_conversions.gd @@ -8,17 +8,17 @@ const const_packed_ints: PackedFloat64Array = [52] @warning_ignore("assert_always_true") func test(): assert(typeof(const_float_int) == TYPE_FLOAT) - assert(str(const_float_int) == '19') + assert(str(const_float_int) == '19.0') assert(typeof(const_float_plus) == TYPE_FLOAT) - assert(str(const_float_plus) == '34') + assert(str(const_float_plus) == '34.0') assert(typeof(const_float_cast) == TYPE_FLOAT) - assert(str(const_float_cast) == '76') + assert(str(const_float_cast) == '76.0') assert(typeof(const_packed_empty) == TYPE_PACKED_FLOAT64_ARRAY) assert(str(const_packed_empty) == '[]') assert(typeof(const_packed_ints) == TYPE_PACKED_FLOAT64_ARRAY) - assert(str(const_packed_ints) == '[52]') + assert(str(const_packed_ints) == '[52.0]') assert(typeof(const_packed_ints[0]) == TYPE_FLOAT) - assert(str(const_packed_ints[0]) == '52') + assert(str(const_packed_ints[0]) == '52.0') print('ok') diff --git a/modules/gdscript/tests/scripts/analyzer/features/external_inner_class_as_constant.out b/modules/gdscript/tests/scripts/analyzer/features/external_inner_class_as_constant.out index 15666c46ad86..abf11548cb51 100644 --- a/modules/gdscript/tests/scripts/analyzer/features/external_inner_class_as_constant.out +++ b/modules/gdscript/tests/scripts/analyzer/features/external_inner_class_as_constant.out @@ -1,2 +1,2 @@ GDTEST_OK -4 +4.0 diff --git a/modules/gdscript/tests/scripts/analyzer/features/typed_array_usage.gd b/modules/gdscript/tests/scripts/analyzer/features/typed_array_usage.gd index b000c8271794..e408f07733c0 100644 --- a/modules/gdscript/tests/scripts/analyzer/features/typed_array_usage.gd +++ b/modules/gdscript/tests/scripts/analyzer/features/typed_array_usage.gd @@ -55,39 +55,39 @@ func test(): untyped_basic.push_back(430.0) inferred_basic.push_back(263.0) typed_basic.push_back(518.0) - assert(str(empty_floats) == '[705, 430, 263, 518]') - assert(str(untyped_basic) == '[705, 430, 263, 518]') - assert(str(inferred_basic) == '[705, 430, 263, 518]') - assert(str(typed_basic) == '[705, 430, 263, 518]') + assert(str(empty_floats) == '[705.0, 430.0, 263.0, 518.0]') + assert(str(untyped_basic) == '[705.0, 430.0, 263.0, 518.0]') + assert(str(inferred_basic) == '[705.0, 430.0, 263.0, 518.0]') + assert(str(typed_basic) == '[705.0, 430.0, 263.0, 518.0]') const constant_float := 950.0 const constant_int := 170 var typed_float := 954.0 var filled_floats: Array[float] = [constant_float, constant_int, typed_float, empty_floats[1] + empty_floats[2]] - assert(str(filled_floats) == '[950, 170, 954, 693]') + assert(str(filled_floats) == '[950.0, 170.0, 954.0, 693.0]') assert(filled_floats.get_typed_builtin() == TYPE_FLOAT) var casted_floats := [empty_floats[2] * 2] as Array[float] - assert(str(casted_floats) == '[526]') + assert(str(casted_floats) == '[526.0]') assert(casted_floats.get_typed_builtin() == TYPE_FLOAT) var returned_floats = (func () -> Array[float]: return [554]).call() - assert(str(returned_floats) == '[554]') + assert(str(returned_floats) == '[554.0]') assert(returned_floats.get_typed_builtin() == TYPE_FLOAT) var passed_floats = floats_identity([663.0 if randf() > 0.5 else 663.0]) - assert(str(passed_floats) == '[663]') + assert(str(passed_floats) == '[663.0]') assert(passed_floats.get_typed_builtin() == TYPE_FLOAT) var default_floats = (func (floats: Array[float] = [364.0]): return floats).call() - assert(str(default_floats) == '[364]') + assert(str(default_floats) == '[364.0]') assert(default_floats.get_typed_builtin() == TYPE_FLOAT) var typed_int := 556 var converted_floats: Array[float] = [typed_int] converted_floats.push_back(498) - assert(str(converted_floats) == '[556, 498]') + assert(str(converted_floats) == '[556.0, 498.0]') assert(converted_floats.get_typed_builtin() == TYPE_FLOAT) @@ -96,7 +96,7 @@ func test(): assert(constant_basic.get_typed_builtin() == TYPE_NIL) const constant_floats: Array[float] = [constant_float - constant_basic[0] - constant_int] - assert(str(constant_floats) == '[552]') + assert(str(constant_floats) == '[552.0]') assert(constant_floats.get_typed_builtin() == TYPE_FLOAT) @@ -104,15 +104,15 @@ func test(): untyped_basic = source_floats var destination_floats: Array[float] = untyped_basic destination_floats[0] -= 0.74 - assert(str(source_floats) == '[999]') - assert(str(untyped_basic) == '[999]') - assert(str(destination_floats) == '[999]') + assert(str(source_floats) == '[999.0]') + assert(str(untyped_basic) == '[999.0]') + assert(str(destination_floats) == '[999.0]') assert(destination_floats.get_typed_builtin() == TYPE_FLOAT) var duplicated_floats := empty_floats.duplicate().slice(2, 3) duplicated_floats[0] *= 3 - assert(str(duplicated_floats) == '[789]') + assert(str(duplicated_floats) == '[789.0]') assert(duplicated_floats.get_typed_builtin() == TYPE_FLOAT) diff --git a/modules/gdscript/tests/scripts/parser/features/export_arrays.out b/modules/gdscript/tests/scripts/parser/features/export_arrays.out index 00e75fcc4364..442ba359afdd 100644 --- a/modules/gdscript/tests/scripts/parser/features/export_arrays.out +++ b/modules/gdscript/tests/scripts/parser/features/export_arrays.out @@ -80,21 +80,21 @@ var test_placeholder: Array var test_placeholder_packed: PackedStringArray hint=TYPE_STRING hint_string="String/PLACEHOLDER_TEXT:Placeholder" usage=DEFAULT|SCRIPT_VARIABLE var test_range_int: Array - hint=TYPE_STRING hint_string="int/RANGE:1,10" usage=DEFAULT|SCRIPT_VARIABLE + hint=TYPE_STRING hint_string="int/RANGE:1.0,10.0" usage=DEFAULT|SCRIPT_VARIABLE var test_range_int_packed_byte: PackedByteArray - hint=TYPE_STRING hint_string="int/RANGE:1,10" usage=DEFAULT|SCRIPT_VARIABLE + hint=TYPE_STRING hint_string="int/RANGE:1.0,10.0" usage=DEFAULT|SCRIPT_VARIABLE var test_range_int_packed32: PackedInt32Array - hint=TYPE_STRING hint_string="int/RANGE:1,10" usage=DEFAULT|SCRIPT_VARIABLE + hint=TYPE_STRING hint_string="int/RANGE:1.0,10.0" usage=DEFAULT|SCRIPT_VARIABLE var test_range_int_packed64: PackedInt64Array - hint=TYPE_STRING hint_string="int/RANGE:1,10" usage=DEFAULT|SCRIPT_VARIABLE + hint=TYPE_STRING hint_string="int/RANGE:1.0,10.0" usage=DEFAULT|SCRIPT_VARIABLE var test_range_int_float_step: Array - hint=TYPE_STRING hint_string="int/RANGE:1,10,0.01" usage=DEFAULT|SCRIPT_VARIABLE + hint=TYPE_STRING hint_string="int/RANGE:1.0,10.0,0.01" usage=DEFAULT|SCRIPT_VARIABLE var test_range_float: Array - hint=TYPE_STRING hint_string="float/RANGE:1,10" usage=DEFAULT|SCRIPT_VARIABLE + hint=TYPE_STRING hint_string="float/RANGE:1.0,10.0" usage=DEFAULT|SCRIPT_VARIABLE var test_range_float_packed32: PackedFloat32Array - hint=TYPE_STRING hint_string="float/RANGE:1,10" usage=DEFAULT|SCRIPT_VARIABLE + hint=TYPE_STRING hint_string="float/RANGE:1.0,10.0" usage=DEFAULT|SCRIPT_VARIABLE var test_range_float_packed64: PackedFloat64Array - hint=TYPE_STRING hint_string="float/RANGE:1,10" usage=DEFAULT|SCRIPT_VARIABLE + hint=TYPE_STRING hint_string="float/RANGE:1.0,10.0" usage=DEFAULT|SCRIPT_VARIABLE var test_exp_easing: Array hint=TYPE_STRING hint_string="float/EXP_EASING:" usage=DEFAULT|SCRIPT_VARIABLE var test_exp_easing_packed32: PackedFloat32Array @@ -124,14 +124,14 @@ var test_weak_packed_vector2_array: PackedVector2Array var test_weak_packed_vector3_array: PackedVector3Array hint=TYPE_STRING hint_string="Vector3:Vector3" usage=DEFAULT|SCRIPT_VARIABLE var test_range_weak_packed_byte_array: PackedByteArray - hint=TYPE_STRING hint_string="int/RANGE:1,10" usage=DEFAULT|SCRIPT_VARIABLE + hint=TYPE_STRING hint_string="int/RANGE:1.0,10.0" usage=DEFAULT|SCRIPT_VARIABLE var test_range_weak_packed_int32_array: PackedInt32Array - hint=TYPE_STRING hint_string="int/RANGE:1,10" usage=DEFAULT|SCRIPT_VARIABLE + hint=TYPE_STRING hint_string="int/RANGE:1.0,10.0" usage=DEFAULT|SCRIPT_VARIABLE var test_range_weak_packed_int64_array: PackedInt64Array - hint=TYPE_STRING hint_string="int/RANGE:1,10" usage=DEFAULT|SCRIPT_VARIABLE + hint=TYPE_STRING hint_string="int/RANGE:1.0,10.0" usage=DEFAULT|SCRIPT_VARIABLE var test_range_weak_packed_float32_array: PackedFloat32Array - hint=TYPE_STRING hint_string="float/RANGE:1,10" usage=DEFAULT|SCRIPT_VARIABLE + hint=TYPE_STRING hint_string="float/RANGE:1.0,10.0" usage=DEFAULT|SCRIPT_VARIABLE var test_range_weak_packed_float64_array: PackedFloat64Array - hint=TYPE_STRING hint_string="float/RANGE:1,10" usage=DEFAULT|SCRIPT_VARIABLE + hint=TYPE_STRING hint_string="float/RANGE:1.0,10.0" usage=DEFAULT|SCRIPT_VARIABLE var test_noalpha_weak_packed_color_array: PackedColorArray hint=TYPE_STRING hint_string="Color/COLOR_NO_ALPHA:" usage=DEFAULT|SCRIPT_VARIABLE diff --git a/modules/gdscript/tests/scripts/parser/features/export_variable.out b/modules/gdscript/tests/scripts/parser/features/export_variable.out index b3f9d0ca9ce5..1e978fe20c38 100644 --- a/modules/gdscript/tests/scripts/parser/features/export_variable.out +++ b/modules/gdscript/tests/scripts/parser/features/export_variable.out @@ -10,11 +10,11 @@ var test_storage_weak_int: Variant = 3 var test_storage_hard_int: int = 4 hint=NONE hint_string="" usage=STORAGE|SCRIPT_VARIABLE var test_range: int = 100 - hint=RANGE hint_string="0,100" usage=DEFAULT|SCRIPT_VARIABLE + hint=RANGE hint_string="0.0,100.0" usage=DEFAULT|SCRIPT_VARIABLE var test_range_step: int = 101 - hint=RANGE hint_string="0,100,1" usage=DEFAULT|SCRIPT_VARIABLE + hint=RANGE hint_string="0.0,100.0,1.0" usage=DEFAULT|SCRIPT_VARIABLE var test_range_step_or_greater: int = 102 - hint=RANGE hint_string="0,100,1,or_greater" usage=DEFAULT|SCRIPT_VARIABLE + hint=RANGE hint_string="0.0,100.0,1.0,or_greater" usage=DEFAULT|SCRIPT_VARIABLE var test_color: Color = Color(0, 0, 0, 1) hint=NONE hint_string="Color" usage=DEFAULT|SCRIPT_VARIABLE var test_color_no_alpha: Color = Color(0, 0, 0, 1) diff --git a/modules/gdscript/tests/scripts/parser/features/number_literals_with_sign.out b/modules/gdscript/tests/scripts/parser/features/number_literals_with_sign.out index c5958365ec73..d94cbe555695 100644 --- a/modules/gdscript/tests/scripts/parser/features/number_literals_with_sign.out +++ b/modules/gdscript/tests/scripts/parser/features/number_literals_with_sign.out @@ -13,4 +13,4 @@ true 0 -255 256 -2 +2.0 diff --git a/modules/gdscript/tests/scripts/parser/features/number_separators.out b/modules/gdscript/tests/scripts/parser/features/number_separators.out index b0d2fd94fe94..9407af9cd8d4 100644 --- a/modules/gdscript/tests/scripts/parser/features/number_separators.out +++ b/modules/gdscript/tests/scripts/parser/features/number_separators.out @@ -13,12 +13,12 @@ GDTEST_OK --- -1234.4567 -1234.4567 --1234 --1234 +-1234.0 +-1234.0 0.4567 0.4567 --- --1234500 --1234500 --1234500 --1234500 +-1234500.0 +-1234500.0 +-1234500.0 +-1234500.0 diff --git a/modules/gdscript/tests/scripts/parser/features/operator_assign.out b/modules/gdscript/tests/scripts/parser/features/operator_assign.out index b0cb63ef59d2..29910adf38d7 100644 --- a/modules/gdscript/tests/scripts/parser/features/operator_assign.out +++ b/modules/gdscript/tests/scripts/parser/features/operator_assign.out @@ -1,2 +1,2 @@ GDTEST_OK -8 +8.0 diff --git a/modules/gdscript/tests/scripts/runtime/features/chain_assignment_works.out b/modules/gdscript/tests/scripts/runtime/features/chain_assignment_works.out index 22929bf6361f..04b0773991fb 100644 --- a/modules/gdscript/tests/scripts/runtime/features/chain_assignment_works.out +++ b/modules/gdscript/tests/scripts/runtime/features/chain_assignment_works.out @@ -1,7 +1,7 @@ GDTEST_OK -{ 1: (2, 0) } -{ 3: (4, 0) } -[[(5, 0)]] -[[(6, 0)]] -[[(7, 0)]] -[X: (8, 9, 7), Y: (0, 1, 0), Z: (0, 0, 1), O: (0, 0, 0)] +{ 1: (2.0, 0.0) } +{ 3: (4.0, 0.0) } +[[(5.0, 0.0)]] +[[(6.0, 0.0)]] +[[(7.0, 0.0)]] +[X: (8.0, 9.0, 7.0), Y: (0.0, 1.0, 0.0), Z: (0.0, 0.0, 1.0), O: (0.0, 0.0, 0.0)] diff --git a/modules/gdscript/tests/scripts/runtime/features/conversion_for_default_parameter.out b/modules/gdscript/tests/scripts/runtime/features/conversion_for_default_parameter.out index a9ef4919cf1b..78ea2a2d807d 100644 --- a/modules/gdscript/tests/scripts/runtime/features/conversion_for_default_parameter.out +++ b/modules/gdscript/tests/scripts/runtime/features/conversion_for_default_parameter.out @@ -1,8 +1,8 @@ GDTEST_OK -x is 1 +x is 1.0 typeof x is 3 -x is 2 +x is 2.0 typeof x is 3 -x is 3 +x is 3.0 typeof x is 3 ok diff --git a/modules/gdscript/tests/scripts/runtime/features/parameter_shadowing.out b/modules/gdscript/tests/scripts/runtime/features/parameter_shadowing.out index 5b981bc8bb88..5492c8f76399 100644 --- a/modules/gdscript/tests/scripts/runtime/features/parameter_shadowing.out +++ b/modules/gdscript/tests/scripts/runtime/features/parameter_shadowing.out @@ -11,7 +11,7 @@ a 1 b 1 -(1, 1) -(0, 0) -(6, 1) -(0, 0) +(1.0, 1.0) +(0.0, 0.0) +(6.0, 1.0) +(0.0, 0.0) diff --git a/modules/gdscript/tests/scripts/runtime/features/stringify.out b/modules/gdscript/tests/scripts/runtime/features/stringify.out index 1f33de00ccee..ad672837892c 100644 --- a/modules/gdscript/tests/scripts/runtime/features/stringify.out +++ b/modules/gdscript/tests/scripts/runtime/features/stringify.out @@ -9,13 +9,13 @@ hello world [P: (0, 0), S: (0, 0)] (0.25, 0.25, 0.25) (0, 0, 0) -[X: (1, 0), Y: (0, 1), O: (0, 0)] -[N: (1, 2, 3), D: 4] -(1, 2, 3, 4) -[P: (0, 0, 0), S: (1, 1, 1)] -[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1)] -[X: (1, 0, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0, 0, 0)] +[X: (1.0, 0.0), Y: (0.0, 1.0), O: (0.0, 0.0)] +[N: (1.0, 2.0, 3.0), D: 4] (1, 2, 3, 4) +[P: (0.0, 0.0, 0.0), S: (1.0, 1.0, 1.0)] +[X: (1.0, 0.0, 0.0), Y: (0.0, 1.0, 0.0), Z: (0.0, 0.0, 1.0)] +[X: (1.0, 0.0, 0.0), Y: (0.0, 1.0, 0.0), Z: (0.0, 0.0, 1.0), O: (0.0, 0.0, 0.0)] +(1.0, 2.0, 3.0, 4.0) hello hello/world RID(0) @@ -26,9 +26,9 @@ Node::[signal]property_list_changed [255, 0, 1] [-1, 0, 1] [-1, 0, 1] -[-1, 0, 1] -[-1, 0, 1] +[-1.0, 0.0, 1.0] +[-1.0, 0.0, 1.0] ["hello", "world"] -[(1, 1), (0, 0)] -[(1, 1, 1), (0, 0, 0)] -[(1, 0, 0, 1), (0, 0, 1, 1), (0, 1, 0, 1)] +[(1.0, 1.0), (0.0, 0.0)] +[(1.0, 1.0, 1.0), (0.0, 0.0, 0.0)] +[(1.0, 0.0, 0.0, 1.0), (0.0, 0.0, 1.0, 1.0), (0.0, 1.0, 0.0, 1.0)] diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp index eb45ade285f4..2fc2a82b1166 100644 --- a/modules/mono/editor/bindings_generator.cpp +++ b/modules/mono/editor/bindings_generator.cpp @@ -4127,9 +4127,45 @@ bool BindingsGenerator::_populate_object_type_interfaces() { return true; } +static String _get_vector2_cs_ctor_args(const Vector2 &p_vec2) { + return String::num_real(p_vec2.x, true) + "f, " + + String::num_real(p_vec2.y, true) + "f"; +} + +static String _get_vector3_cs_ctor_args(const Vector3 &p_vec3) { + return String::num_real(p_vec3.x, true) + "f, " + + String::num_real(p_vec3.y, true) + "f, " + + String::num_real(p_vec3.z, true) + "f"; +} + +static String _get_vector4_cs_ctor_args(const Vector4 &p_vec4) { + return String::num_real(p_vec4.x, true) + "f, " + + String::num_real(p_vec4.y, true) + "f, " + + String::num_real(p_vec4.z, true) + "f, " + + String::num_real(p_vec4.w, true) + "f"; +} + +static String _get_vector2i_cs_ctor_args(const Vector2i &p_vec2i) { + return itos(p_vec2i.x) + ", " + itos(p_vec2i.y); +} + +static String _get_vector3i_cs_ctor_args(const Vector3i &p_vec3i) { + return itos(p_vec3i.x) + ", " + itos(p_vec3i.y) + ", " + itos(p_vec3i.z); +} + +static String _get_vector4i_cs_ctor_args(const Vector4i &p_vec4i) { + return itos(p_vec4i.x) + ", " + itos(p_vec4i.y) + ", " + itos(p_vec4i.z) + ", " + itos(p_vec4i.w); +} + +static String _get_color_cs_ctor_args(const Color &p_color) { + return String::num(p_color.r, 4) + "f, " + + String::num(p_color.g, 4) + "f, " + + String::num(p_color.b, 4) + "f, " + + String::num(p_color.a, 4) + "f"; +} + bool BindingsGenerator::_arg_default_value_from_variant(const Variant &p_val, ArgumentInterface &r_iarg) { r_iarg.def_param_value = p_val; - r_iarg.default_argument = p_val.operator String(); switch (p_val.get_type()) { case Variant::NIL: @@ -4142,10 +4178,14 @@ bool BindingsGenerator::_arg_default_value_from_variant(const Variant &p_val, Ar break; case Variant::INT: if (r_iarg.type.cname != name_cache.type_int) { - r_iarg.default_argument = "(%s)(" + r_iarg.default_argument + ")"; + r_iarg.default_argument = "(%s)(" + p_val.operator String() + ")"; + } else { + r_iarg.default_argument = p_val.operator String(); } break; case Variant::FLOAT: + r_iarg.default_argument = p_val.operator String(); + if (r_iarg.type.cname == name_cache.type_float) { r_iarg.default_argument += "f"; } @@ -4155,7 +4195,7 @@ bool BindingsGenerator::_arg_default_value_from_variant(const Variant &p_val, Ar case Variant::NODE_PATH: if (r_iarg.type.cname == name_cache.type_StringName || r_iarg.type.cname == name_cache.type_NodePath) { if (r_iarg.default_argument.length() > 0) { - r_iarg.default_argument = "(%s)\"" + r_iarg.default_argument + "\""; + r_iarg.default_argument = "(%s)\"" + p_val.operator String() + "\""; r_iarg.def_param_mode = ArgumentInterface::NULLABLE_REF; } else { // No need for a special `in` statement to change `null` to `""`. Marshaling takes care of this already. @@ -4163,40 +4203,62 @@ bool BindingsGenerator::_arg_default_value_from_variant(const Variant &p_val, Ar } } else { CRASH_COND(r_iarg.type.cname != name_cache.type_String); - r_iarg.default_argument = "\"" + r_iarg.default_argument + "\""; + r_iarg.default_argument = "\"" + p_val.operator String() + "\""; } break; case Variant::PLANE: { Plane plane = p_val.operator Plane(); - r_iarg.default_argument = "new Plane(new Vector3" + plane.normal.operator String() + ", " + rtos(plane.d) + ")"; + r_iarg.default_argument = "new Plane(new Vector3(" + + _get_vector3_cs_ctor_args(plane.normal) + "), " + rtos(plane.d) + "f)"; r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL; } break; case Variant::AABB: { AABB aabb = p_val.operator ::AABB(); - r_iarg.default_argument = "new Aabb(new Vector3" + aabb.position.operator String() + ", new Vector3" + aabb.size.operator String() + ")"; + r_iarg.default_argument = "new Aabb(new Vector3(" + + _get_vector3_cs_ctor_args(aabb.position) + "), new Vector3(" + + _get_vector3_cs_ctor_args(aabb.size) + "))"; r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL; } break; case Variant::RECT2: { Rect2 rect = p_val.operator Rect2(); - r_iarg.default_argument = "new Rect2(new Vector2" + rect.position.operator String() + ", new Vector2" + rect.size.operator String() + ")"; + r_iarg.default_argument = "new Rect2(new Vector2(" + + _get_vector2_cs_ctor_args(rect.position) + "), new Vector2(" + + _get_vector2_cs_ctor_args(rect.size) + "))"; r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL; } break; case Variant::RECT2I: { Rect2i rect = p_val.operator Rect2i(); - r_iarg.default_argument = "new Rect2I(new Vector2I" + rect.position.operator String() + ", new Vector2I" + rect.size.operator String() + ")"; + r_iarg.default_argument = "new Rect2I(new Vector2I(" + + _get_vector2i_cs_ctor_args(rect.position) + "), new Vector2I(" + + _get_vector2i_cs_ctor_args(rect.size) + "))"; r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL; } break; case Variant::COLOR: + r_iarg.default_argument = "new Color(" + _get_color_cs_ctor_args(p_val.operator Color()) + ")"; + r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL; + break; case Variant::VECTOR2: + r_iarg.default_argument = "new Vector2(" + _get_vector2_cs_ctor_args(p_val.operator Vector2()) + ")"; + r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL; + break; case Variant::VECTOR2I: + r_iarg.default_argument = "new Vector2I(" + _get_vector2i_cs_ctor_args(p_val.operator Vector2i()) + ")"; + r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL; + break; case Variant::VECTOR3: + r_iarg.default_argument = "new Vector3(" + _get_vector3_cs_ctor_args(p_val.operator Vector3()) + ")"; + r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL; + break; case Variant::VECTOR3I: - r_iarg.default_argument = "new %s" + r_iarg.default_argument; + r_iarg.default_argument = "new Vector3I(" + _get_vector3i_cs_ctor_args(p_val.operator Vector3i()) + ")"; r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL; break; case Variant::VECTOR4: + r_iarg.default_argument = "new Vector4(" + _get_vector4_cs_ctor_args(p_val.operator Vector4()) + ")"; + r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL; + break; case Variant::VECTOR4I: - r_iarg.default_argument = "new %s" + r_iarg.default_argument; + r_iarg.default_argument = "new Vector4I(" + _get_vector4i_cs_ctor_args(p_val.operator Vector4i()) + ")"; r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL; break; case Variant::OBJECT: @@ -4245,7 +4307,10 @@ bool BindingsGenerator::_arg_default_value_from_variant(const Variant &p_val, Ar if (transform == Transform2D()) { r_iarg.default_argument = "Transform2D.Identity"; } else { - r_iarg.default_argument = "new Transform2D(new Vector2" + transform.columns[0].operator String() + ", new Vector2" + transform.columns[1].operator String() + ", new Vector2" + transform.columns[2].operator String() + ")"; + r_iarg.default_argument = "new Transform2D(new Vector2(" + + _get_vector2_cs_ctor_args(transform.columns[0]) + "), new Vector2(" + + _get_vector2_cs_ctor_args(transform.columns[1]) + "), new Vector2(" + + _get_vector2_cs_ctor_args(transform.columns[2]) + "))"; } r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL; } break; @@ -4255,7 +4320,11 @@ bool BindingsGenerator::_arg_default_value_from_variant(const Variant &p_val, Ar r_iarg.default_argument = "Transform3D.Identity"; } else { Basis basis = transform.basis; - r_iarg.default_argument = "new Transform3D(new Vector3" + basis.get_column(0).operator String() + ", new Vector3" + basis.get_column(1).operator String() + ", new Vector3" + basis.get_column(2).operator String() + ", new Vector3" + transform.origin.operator String() + ")"; + r_iarg.default_argument = "new Transform3D(new Vector3(" + + _get_vector3_cs_ctor_args(basis.get_column(0)) + "), new Vector3(" + + _get_vector3_cs_ctor_args(basis.get_column(1)) + "), new Vector3(" + + _get_vector3_cs_ctor_args(basis.get_column(2)) + "), new Vector3(" + + _get_vector3_cs_ctor_args(transform.origin) + "))"; } r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL; } break; @@ -4264,7 +4333,11 @@ bool BindingsGenerator::_arg_default_value_from_variant(const Variant &p_val, Ar if (projection == Projection()) { r_iarg.default_argument = "Projection.Identity"; } else { - r_iarg.default_argument = "new Projection(new Vector4" + projection.columns[0].operator String() + ", new Vector4" + projection.columns[1].operator String() + ", new Vector4" + projection.columns[2].operator String() + ", new Vector4" + projection.columns[3].operator String() + ")"; + r_iarg.default_argument = "new Projection(new Vector4(" + + _get_vector4_cs_ctor_args(projection.columns[0]) + "), new Vector4(" + + _get_vector4_cs_ctor_args(projection.columns[1]) + "), new Vector4(" + + _get_vector4_cs_ctor_args(projection.columns[2]) + "), new Vector4(" + + _get_vector4_cs_ctor_args(projection.columns[3]) + "))"; } r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL; } break; @@ -4273,7 +4346,10 @@ bool BindingsGenerator::_arg_default_value_from_variant(const Variant &p_val, Ar if (basis == Basis()) { r_iarg.default_argument = "Basis.Identity"; } else { - r_iarg.default_argument = "new Basis(new Vector3" + basis.get_column(0).operator String() + ", new Vector3" + basis.get_column(1).operator String() + ", new Vector3" + basis.get_column(2).operator String() + ")"; + r_iarg.default_argument = "new Basis(new Vector3(" + + _get_vector3_cs_ctor_args(basis.get_column(0)) + "), new Vector3(" + + _get_vector3_cs_ctor_args(basis.get_column(1)) + "), new Vector3(" + + _get_vector3_cs_ctor_args(basis.get_column(2)) + "))"; } r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL; } break; @@ -4282,7 +4358,11 @@ bool BindingsGenerator::_arg_default_value_from_variant(const Variant &p_val, Ar if (quaternion == Quaternion()) { r_iarg.default_argument = "Quaternion.Identity"; } else { - r_iarg.default_argument = "new Quaternion" + quaternion.operator String(); + r_iarg.default_argument = "new Quaternion(" + + String::num_real(quaternion.x, false) + "f, " + + String::num_real(quaternion.y, false) + "f, " + + String::num_real(quaternion.z, false) + "f, " + + String::num_real(quaternion.w, false) + "f)"; } r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL; } break; diff --git a/scene/gui/code_edit.cpp b/scene/gui/code_edit.cpp index 4f90504e35f0..682ee6388801 100644 --- a/scene/gui/code_edit.cpp +++ b/scene/gui/code_edit.cpp @@ -1498,7 +1498,7 @@ bool CodeEdit::is_line_numbers_zero_padded() const { } void CodeEdit::_line_number_draw_callback(int p_line, int p_gutter, const Rect2 &p_region) { - String fc = String::num(p_line + 1).lpad(line_number_digits, line_number_padding); + String fc = String::num_int64(p_line + 1).lpad(line_number_digits, line_number_padding); if (is_localizing_numeral_system()) { fc = TS->format_number(fc); } diff --git a/tests/core/math/test_aabb.h b/tests/core/math/test_aabb.h index b9f84cca245a..15006e714239 100644 --- a/tests/core/math/test_aabb.h +++ b/tests/core/math/test_aabb.h @@ -48,7 +48,7 @@ TEST_CASE("[AABB] Constructor methods") { TEST_CASE("[AABB] String conversion") { CHECK_MESSAGE( - String(AABB(Vector3(-1.5, 2, -2.5), Vector3(4, 5, 6))) == "[P: (-1.5, 2, -2.5), S: (4, 5, 6)]", + String(AABB(Vector3(-1.5, 2, -2.5), Vector3(4, 5, 6))) == "[P: (-1.5, 2.0, -2.5), S: (4.0, 5.0, 6.0)]", "The string representation should match the expected value."); } diff --git a/tests/core/math/test_color.h b/tests/core/math/test_color.h index bd2d4f40e5dd..3d36079102ac 100644 --- a/tests/core/math/test_color.h +++ b/tests/core/math/test_color.h @@ -140,7 +140,7 @@ TEST_CASE("[Color] Conversion methods") { cyan.to_rgba64() == 0x0000'ffff'ffff'ffff, "The returned 64-bit BGR number should match the expected value."); CHECK_MESSAGE( - String(cyan) == "(0, 1, 1, 1)", + String(cyan) == "(0.0, 1.0, 1.0, 1.0)", "The string representation should match the expected value."); } diff --git a/tests/core/math/test_rect2.h b/tests/core/math/test_rect2.h index 26ab185aa2f4..0b990fc7e84d 100644 --- a/tests/core/math/test_rect2.h +++ b/tests/core/math/test_rect2.h @@ -57,7 +57,7 @@ TEST_CASE("[Rect2] Constructor methods") { TEST_CASE("[Rect2] String conversion") { // Note: This also depends on the Vector2 string representation. CHECK_MESSAGE( - String(Rect2(0, 100, 1280, 720)) == "[P: (0, 100), S: (1280, 720)]", + String(Rect2(0, 100, 1280, 720)) == "[P: (0.0, 100.0), S: (1280.0, 720.0)]", "The string representation should match the expected value."); } diff --git a/tests/core/string/test_string.h b/tests/core/string/test_string.h index 64f03e587997..af83d426eb10 100644 --- a/tests/core/string/test_string.h +++ b/tests/core/string/test_string.h @@ -412,9 +412,9 @@ TEST_CASE("[String] Erasing") { } TEST_CASE("[String] Number to string") { - CHECK(String::num(0) == "0"); - CHECK(String::num(0.0) == "0"); // No trailing zeros. - CHECK(String::num(-0.0) == "-0"); // Includes sign even for zero. + CHECK(String::num(0) == "0.0"); // The method takes double, so always add zeros. + CHECK(String::num(0.0) == "0.0"); + CHECK(String::num(-0.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"); @@ -433,15 +433,15 @@ TEST_CASE("[String] Number to string") { CHECK(String::num_real(3.141593) == "3.141593"); CHECK(String::num_real(3.141) == "3.141"); // No trailing zeros. #ifdef REAL_T_IS_DOUBLE - CHECK_MESSAGE(String::num_real(123.456789) == "123.456789", "Prints the appropriate amount of digits for real_t = double."); - CHECK_MESSAGE(String::num_real(-123.456789) == "-123.456789", "Prints the appropriate amount of digits for real_t = double."); - CHECK_MESSAGE(String::num_real(Math_PI) == "3.14159265358979", "Prints the appropriate amount of digits for real_t = double."); - CHECK_MESSAGE(String::num_real(3.1415f) == "3.1414999961853", "Prints more digits of 32-bit float when real_t = double (ones that would be reliable for double) and no trailing zero."); + CHECK_MESSAGE(String::num_real(real_t(123.456789)) == "123.456789", "Prints the appropriate amount of digits for real_t = double."); + CHECK_MESSAGE(String::num_real(real_t(-123.456789)) == "-123.456789", "Prints the appropriate amount of digits for real_t = double."); + CHECK_MESSAGE(String::num_real(real_t(Math_PI)) == "3.14159265358979", "Prints the appropriate amount of digits for real_t = double."); + CHECK_MESSAGE(String::num_real(real_t(3.1415f)) == "3.1414999961853", "Prints more digits of 32-bit float when real_t = double (ones that would be reliable for double) and no trailing zero."); #else - CHECK_MESSAGE(String::num_real(123.456789) == "123.4568", "Prints the appropriate amount of digits for real_t = float."); - CHECK_MESSAGE(String::num_real(-123.456789) == "-123.4568", "Prints the appropriate amount of digits for real_t = float."); - CHECK_MESSAGE(String::num_real(Math_PI) == "3.141593", "Prints the appropriate amount of digits for real_t = float."); - CHECK_MESSAGE(String::num_real(3.1415f) == "3.1415", "Prints only reliable digits of 32-bit float when real_t = float."); + CHECK_MESSAGE(String::num_real(real_t(123.456789)) == "123.4568", "Prints the appropriate amount of digits for real_t = float."); + CHECK_MESSAGE(String::num_real(real_t(-123.456789)) == "-123.4568", "Prints the appropriate amount of digits for real_t = float."); + CHECK_MESSAGE(String::num_real(real_t(Math_PI)) == "3.141593", "Prints the appropriate amount of digits for real_t = float."); + CHECK_MESSAGE(String::num_real(real_t(3.1415f)) == "3.1415", "Prints only reliable digits of 32-bit float when real_t = float."); #endif // REAL_T_IS_DOUBLE // Checks doubles with many decimal places. @@ -450,7 +450,7 @@ TEST_CASE("[String] Number to string") { CHECK(String::num(-0.0000012345432123454321) == "-0.00000123454321"); CHECK(String::num(-10000.0000012345432123454321) == "-10000.0000012345"); CHECK(String::num(0.0000000000012345432123454321) == "0.00000000000123"); - CHECK(String::num(0.0000000000012345432123454321, 3) == "0"); + CHECK(String::num(0.0000000000012345432123454321, 3) == "0.0"); // Note: When relevant (remainder > 0.5), the last digit gets rounded up, // which can also lead to not include a trailing zero, e.g. "...89" -> "...9". diff --git a/tests/core/variant/test_variant_utility.h b/tests/core/variant/test_variant_utility.h index 93458b63f4c9..34b4880d51fe 100644 --- a/tests/core/variant/test_variant_utility.h +++ b/tests/core/variant/test_variant_utility.h @@ -89,7 +89,7 @@ TEST_CASE("[VariantUtility] Type conversion") { converted = VariantUtilityFunctions::type_convert(basis, Variant::Type::STRING); CHECK(converted.get_type() == Variant::Type::STRING); - CHECK(converted == Variant("[X: (1.2, 0, 0), Y: (0, 3.4, 0), Z: (0, 0, 5.6)]")); + CHECK(converted == Variant("[X: (1.2, 0.0, 0.0), Y: (0.0, 3.4, 0.0), Z: (0.0, 0.0, 5.6)]")); } {