Skip to content

Commit 0474bf4

Browse files
authored
Merge pull request #206 from SpaceMadness/fix/locale-float-parsing
Fixed locale-specific decimal points while working with floats
2 parents 425838b + 15469b6 commit 0474bf4

File tree

5 files changed

+115
-71
lines changed

5 files changed

+115
-71
lines changed

Native/Android/LunarConsole/lunarConsole/src/main/java/spacemadness/com/lunarconsole/console/DefaultColorFactory.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,6 @@
3030
import spacemadness.com.lunarconsole.R;
3131
import spacemadness.com.lunarconsole.utils.StringUtils;
3232

33-
import static spacemadness.com.lunarconsole.utils.StringUtils.parseInt;
34-
3533
public class DefaultColorFactory implements ColorFactory {
3634
private final Context context;
3735
private final Map<String, Integer> colorLookup;

Native/Android/LunarConsole/lunarConsole/src/main/java/spacemadness/com/lunarconsole/utils/StringUtils.java

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,17 @@
2323
package spacemadness.com.lunarconsole.utils;
2424

2525
import java.text.DecimalFormat;
26+
import java.text.DecimalFormatSymbols;
2627
import java.text.NumberFormat;
28+
import java.text.ParseException;
2729
import java.util.List;
30+
import java.util.Locale;
2831
import java.util.Map;
2932

3033
public class StringUtils {
31-
private static final NumberFormat FLOATING_POINT_FORMAT = new DecimalFormat("0.#");
34+
// Force floating point numbers to '.' format
35+
private static final NumberFormat FLOATING_POINT_FORMAT = new DecimalFormat(
36+
"0.#", DecimalFormatSymbols.getInstance(Locale.ENGLISH));
3237

3338
public static boolean isValidInteger(String str) {
3439
try {
@@ -40,12 +45,7 @@ public static boolean isValidInteger(String str) {
4045
}
4146

4247
public static boolean isValidFloat(String str) {
43-
try {
44-
Float.parseFloat(str);
45-
return true;
46-
} catch (NumberFormatException e) {
47-
return false;
48-
}
48+
return parseFloat(str) != null;
4949
}
5050

5151
public static Integer parseInt(String str) {
@@ -66,18 +66,16 @@ public static int parseInt(String str, int defaultValue) {
6666

6767
public static Float parseFloat(String str) {
6868
try {
69-
return Float.parseFloat(str);
70-
} catch (NumberFormatException e) {
69+
final Number number = FLOATING_POINT_FORMAT.parse(str);
70+
return number != null ? number.floatValue() : null;
71+
} catch (NumberFormatException | ParseException e) {
7172
return null;
7273
}
7374
}
7475

7576
public static float parseFloat(String str, float defaultValue) {
76-
try {
77-
return Float.parseFloat(str);
78-
} catch (NumberFormatException e) {
79-
return defaultValue;
80-
}
77+
final Float number = parseFloat(str);
78+
return number != null ? number : defaultValue;
8179
}
8280

8381
public static int length(String str) {

Project/Assets/Editor/Tests/StringUtilsTest.cs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,55 @@
3131

3232
public class StringUtilsTest
3333
{
34+
#region Parsing
35+
36+
[Test]
37+
public void TestParseFloat()
38+
{
39+
Assert.AreEqual(123f, StringUtils.ParseFloat("123"));
40+
Assert.AreEqual(-123f, StringUtils.ParseFloat("-123"));
41+
Assert.AreEqual(0f, StringUtils.ParseFloat("0", float.NaN));
42+
Assert.AreEqual(3.14f, StringUtils.ParseFloat("3.14"));
43+
Assert.AreEqual(-3.14f, StringUtils.ParseFloat("-3.14"));
44+
Assert.AreEqual(float.NaN, StringUtils.ParseFloat("3.14f", float.NaN));
45+
Assert.AreEqual(float.NaN, StringUtils.ParseFloat("abs", float.NaN));
46+
47+
float actual;
48+
Assert.IsTrue(StringUtils.ParseFloat("123", out actual));
49+
Assert.AreEqual(123f, actual);
50+
51+
Assert.IsTrue(StringUtils.ParseFloat("-123", out actual));
52+
Assert.AreEqual(-123f, actual);
53+
54+
Assert.IsTrue(StringUtils.ParseFloat("0", out actual));
55+
Assert.AreEqual(0f, actual);
56+
57+
Assert.IsTrue(StringUtils.ParseFloat("3.14", out actual));
58+
Assert.AreEqual(3.14f, actual);
59+
60+
Assert.IsTrue(StringUtils.ParseFloat("-3.14", out actual));
61+
Assert.AreEqual(-3.14f, actual);
62+
63+
Assert.IsFalse(StringUtils.ParseFloat("-3.14f", out _));
64+
Assert.IsFalse(StringUtils.ParseFloat("abs", out _));
65+
}
66+
67+
#endregion
68+
69+
#region String Representation
70+
71+
[Test]
72+
public void TestFloatString()
73+
{
74+
Assert.AreEqual("3.14", StringUtils.ToString(3.14f));
75+
Assert.AreEqual("-3.14", StringUtils.ToString(-3.14f));
76+
Assert.AreEqual("0", StringUtils.ToString(0.0f));
77+
Assert.AreEqual("123", StringUtils.ToString(123.0f));
78+
Assert.AreEqual("-123", StringUtils.ToString(-123.0f));
79+
}
80+
81+
#endregion
82+
3483
#region Serialization
3584

3685
[Test]

Project/Assets/LunarConsole/Scripts/LunarConsole.cs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -548,7 +548,7 @@ void LoadVariables()
548548
continue;
549549
}
550550

551-
cvar.Value = value;
551+
cvar.Value = FixLegacyValue(cvar.Type, value);
552552
m_platform.OnVariableUpdated(m_registry, cvar);
553553
}
554554
}
@@ -608,6 +608,17 @@ bool ShouldSaveVar(CVar cvar)
608608
return !cvar.IsDefault && !cvar.HasFlag(CFlags.NoArchive);
609609
}
610610

611+
private static string FixLegacyValue(CVarType type, string value)
612+
{
613+
// we need to fix incorrect value: https://github.com/SpaceMadness/lunar-unity-console/issues/201
614+
if (type == CVarType.Float)
615+
{
616+
return value.Replace(',', '.');
617+
}
618+
619+
return value;
620+
}
621+
611622
#endregion
612623

613624
#region Messages
@@ -1253,7 +1264,7 @@ void ConsoleVariableSetHandler(IDictionary<string, string> data)
12531264
case CVarType.Float:
12541265
{
12551266
float floatValue;
1256-
if (float.TryParse(value, out floatValue))
1267+
if (StringUtils.ParseFloat(value, out floatValue))
12571268
{
12581269
variable.FloatValue = floatValue;
12591270
m_variablesDirty = true;

Project/Assets/LunarConsole/Scripts/Utils/StringUtils.cs

Lines changed: 41 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
using System;
2424
using System.Collections;
2525
using System.Collections.Generic;
26+
using System.Globalization;
2627
using System.Text;
2728
using System.Text.RegularExpressions;
2829

@@ -32,6 +33,7 @@ namespace LunarConsolePluginInternal
3233
{
3334
public static class StringUtils
3435
{
36+
private const NumberStyles FLOAT_NUMBER_STYLES = NumberStyles.Integer | NumberStyles.Float | NumberStyles.AllowDecimalPoint;
3537
private static readonly char[] kSpaceSplitChars = { ' ' };
3638

3739
internal static string TryFormat(string format, params object[] args)
@@ -116,34 +118,19 @@ public static int ParseInt(string str, out bool succeed)
116118
return 0;
117119
}
118120

119-
public static float ParseFloat(string str)
121+
public static float ParseFloat(string str, float defValue = 0.0f)
120122
{
121-
return ParseFloat(str, 0.0f);
122-
}
123-
124-
public static float ParseFloat(string str, float defValue)
125-
{
126-
if (!string.IsNullOrEmpty(str))
123+
if (ParseFloat(str, out float result))
127124
{
128-
float value;
129-
bool succeed = float.TryParse(str, out value);
130-
return succeed ? value : defValue;
125+
return result;
131126
}
132-
133127
return defValue;
134128
}
135129

136-
public static float ParseFloat(string str, out bool succeed)
130+
public static bool ParseFloat(string str, out float result)
137131
{
138-
if (!string.IsNullOrEmpty(str))
139-
{
140-
float value;
141-
succeed = float.TryParse(str, out value);
142-
return succeed ? value : 0.0f;
143-
}
144-
145-
succeed = false;
146-
return 0.0f;
132+
// Force '.' as decimal point
133+
return float.TryParse(str, FLOAT_NUMBER_STYLES, CultureInfo.InvariantCulture, out result);
147134
}
148135

149136
public static bool ParseBool(string str)
@@ -543,79 +530,80 @@ internal static string NonNullOrEmpty(string str)
543530

544531
#region string representation
545532

546-
internal static string ToString(object value)
533+
public static string ToString(object value)
547534
{
548535
return value != null ? value.ToString() : null;
549536
}
550-
551-
internal static string ToString(int value)
537+
538+
public static string ToString(int value)
552539
{
553540
return value.ToString();
554541
}
555542

556-
internal static string ToString(float value)
543+
public static string ToString(float value)
557544
{
558-
return value.ToString("G");
545+
// For '.' as decimal point
546+
return value.ToString("G", CultureInfo.InvariantCulture);
559547
}
560548

561-
internal static string ToString(bool value)
549+
public static string ToString(bool value)
562550
{
563551
return value.ToString();
564552
}
565553

566-
internal static string ToString(ref Color value)
554+
public static string ToString(ref Color value)
567555
{
568556
if (value.a > 0.0f)
569557
{
570558
return string.Format("{0} {1} {2} {3}",
571-
value.r.ToString("G"),
572-
value.g.ToString("G"),
573-
value.b.ToString("G"),
574-
value.a.ToString("G")
559+
ToString(value.r),
560+
ToString(value.g),
561+
ToString(value.b),
562+
ToString(value.a)
575563
);
576564
}
577565

578-
return string.Format("{0} {1} {2}",
579-
value.r.ToString("G"),
580-
value.g.ToString("G"),
581-
value.b.ToString("G")
566+
return string.Format("{0} {1} {2}",
567+
ToString(value.r),
568+
ToString(value.g),
569+
ToString(value.b)
582570
);
583571
}
584572

585-
internal static string ToString(ref Rect value)
573+
public static string ToString(ref Rect value)
586574
{
587575
return string.Format("{0} {1} {2} {3}",
588-
value.x.ToString("G"),
589-
value.y.ToString("G"),
590-
value.width.ToString("G"),
591-
value.height.ToString("G")
576+
ToString(value.x),
577+
ToString(value.y),
578+
ToString(value.width),
579+
ToString(value.height)
592580
);
593581
}
594582

595-
internal static string ToString(ref Vector2 value)
583+
public static string ToString(ref Vector2 value)
596584
{
597585
return string.Format("{0} {1}",
598-
value.x.ToString("G"),
599-
value.y.ToString("G")
586+
ToString(value.x),
587+
ToString(value.y)
600588
);
601589
}
602590

603-
internal static string ToString(ref Vector3 value)
591+
public static string ToString(ref Vector3 value)
604592
{
605593
return string.Format("{0} {1} {2}",
606-
value.x.ToString("G"),
607-
value.y.ToString("G"),
608-
value.z.ToString("G")
594+
ToString(value.x),
595+
ToString(value.y),
596+
ToString(value.z)
609597
);
610598
}
611599

612-
internal static string ToString(ref Vector4 value)
600+
public static string ToString(ref Vector4 value)
613601
{
614602
return string.Format("{0} {1} {2} {3}",
615-
value.x.ToString("G"),
616-
value.y.ToString("G"),
617-
value.z.ToString("G"),
618-
value.w.ToString("G")
603+
ToString(value.x),
604+
ToString(value.y),
605+
ToString(value.z),
606+
ToString(value.w)
619607
);
620608
}
621609

0 commit comments

Comments
 (0)