Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change: Improve number parsing #544

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
339 changes: 105 additions & 234 deletions source/OpenBVE/Parsers/Panel/Panel2CfgParser.cs

Large diffs are not rendered by default.

365 changes: 35 additions & 330 deletions source/OpenBVE/Parsers/Panel/PanelXmlParser.cs

Large diffs are not rendered by default.

38 changes: 2 additions & 36 deletions source/OpenBVE/Parsers/SoundConfiguration/SoundCfg.Xml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -634,24 +634,7 @@ private static void ParseNode(XmlNode node, out SoundBuffer Sound, ref Vector3 P
}
break;
case "position":
string[] Arguments = c.InnerText.Split(new char[] { ',' });
double x = 0.0, y = 0.0, z = 0.0;
if (Arguments.Length >= 1 && Arguments[0].Length > 0 && !NumberFormats.TryParseDoubleVb6(Arguments[0], out x))
{
Interface.AddMessage(MessageType.Error, false, "Sound radius X " + Arguments[0] + " in XML node " + node.Name + " is invalid.");
x = 0.0;
}
if (Arguments.Length >= 2 && Arguments[1].Length > 0 && !NumberFormats.TryParseDoubleVb6(Arguments[1], out y))
{
Interface.AddMessage(MessageType.Error, false, "Sound radius Y " + Arguments[1] + " in XML node " + node.Name + " is invalid.");
y = 0.0;
}
if (Arguments.Length >= 3 && Arguments[2].Length > 0 && !NumberFormats.TryParseDoubleVb6(Arguments[2], out z))
{
Interface.AddMessage(MessageType.Error, false, "Sound radius Z " + Arguments[2] + " in XML node " + node.Name + " is invalid.");
z = 0.0;
}
Position = new Vector3(x, y, z);
Position = NumberFormats.TryParseVector3(c.InnerText, node.Name, "Position", -1, fileName);
break;
case "radius":
if (!NumberFormats.TryParseDoubleVb6(c.InnerText, out Radius))
Expand Down Expand Up @@ -705,24 +688,7 @@ private static void ParseNode(XmlNode node, out CarSound Sound, Vector3 Position
}
break;
case "position":
string[] Arguments = c.InnerText.Split(new char[] { ',' });
double x = 0.0, y = 0.0, z = 0.0;
if (Arguments.Length >= 1 && Arguments[0].Length > 0 && !NumberFormats.TryParseDoubleVb6(Arguments[0], out x))
{
Interface.AddMessage(MessageType.Error, false, "Sound radius X " + Arguments[0] + " in XML node " + node.Name + " is invalid.");
x = 0.0;
}
if (Arguments.Length >= 2 && Arguments[1].Length > 0 && !NumberFormats.TryParseDoubleVb6(Arguments[1], out y))
{
Interface.AddMessage(MessageType.Error, false, "Sound radius Y " + Arguments[1] + " in XML node " + node.Name + " is invalid.");
y = 0.0;
}
if (Arguments.Length >= 3 && Arguments[2].Length > 0 && !NumberFormats.TryParseDoubleVb6(Arguments[2], out z))
{
Interface.AddMessage(MessageType.Error, false, "Sound radius Z " + Arguments[2] + " in XML node " + node.Name + " is invalid.");
z = 0.0;
}
Position = new Vector3(x,y,z);
Position = NumberFormats.TryParseVector3(c.InnerText, node.Name, "Position", -1, fileName);
break;
case "radius":
if (!NumberFormats.TryParseDoubleVb6(c.InnerText, out Radius))
Expand Down
81 changes: 81 additions & 0 deletions source/OpenBveApi/Math/Math.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
using System.Globalization;
using System.Linq;
using System.Windows.Forms;
using OpenBveApi.Interface;

namespace OpenBveApi.Math {

/// <summary>Contains methods required for parsing differently formatted numbers</summary>
public static class NumberFormats
{
/// <summary>The host application interface</summary>
internal static Hosts.HostInterface currentHost;
/// <summary>Parses a double formatted as a Visual Basic 6 string</summary>
/// <param name="Expression">The expression to parse</param>
/// <param name="Value">The value to return (Default 0.0)</param>
Expand Down Expand Up @@ -179,6 +183,83 @@ public static bool TryParseDoubleVb6(string Expression, double[] UnitFactors, ou
}
}

/// <summary>Parses a Vector2 formatted as a Visual Basic 6 string</summary>
/// <param name="Value">The string value</param>
/// <param name="Key">The key value</param>
/// <param name="Section">The section</param>
/// <param name="Line">The line</param>
/// <param name="FileName">The filename</param>
/// <param name="ExpectedArguments">Whether two arguments are expected</param>
/// <returns>True if parsing succeeds, false otherwise</returns>
leezer3 marked this conversation as resolved.
Show resolved Hide resolved
public static Vector2 TryParseVector2(string Value, string Key, string Section, int Line, string FileName, bool ExpectedArguments = false)
leezer3 marked this conversation as resolved.
Show resolved Hide resolved
{
Vector2 parsedVector = new Vector2();
CultureInfo Culture = CultureInfo.InvariantCulture;
int k = Value.IndexOf(',');
if (k >= 0)
{
string a = Value.Substring(0, k).TrimEnd(new char[] { });
string b = Value.Substring(k + 1).TrimStart(new char[] { });
if (a.Length != 0 && !NumberFormats.TryParseDoubleVb6(a, out parsedVector.X)) {
currentHost.AddMessage(MessageType.Error, false, "X is invalid in " + Key + " - " + Section + " at line " + (Line + 1).ToString(Culture) + " in " + FileName);
}
if (b.Length != 0 && !NumberFormats.TryParseDoubleVb6(b, out parsedVector.Y)) {
currentHost.AddMessage(MessageType.Error, false, "Y is invalid in " + Key + " - " + Section + " at line " + (Line + 1).ToString(Culture) + " in " + FileName);
}
} else {
if (ExpectedArguments)
{
currentHost.AddMessage(MessageType.Error, false, "Two arguments are expected in " + Key + " - " + Section + " at line " + (Line + 1).ToString(Culture) + " in " + FileName);
}

}
return parsedVector;
}

/// <summary>Parses a Vector3 formatted as a Visual Basic 6 string</summary>
/// <param name="Value">The string value</param>
/// <param name="Key">The key value</param>
/// <param name="Section">The section</param>
/// <param name="Line">The line</param>
/// <param name="FileName">The filename</param>
/// <param name="ExpectedArguments">Whether a minimum of three arguments is expected</param>
/// <returns>True if parsing succeeds, false otherwise</returns>
public static Vector3 TryParseVector3(string Value, string Key, string Section, int Line, string FileName, bool ExpectedArguments = false)
{
string[] Arguments = Value.Split(',');
return TryParseVector3(Arguments, Key, Section, Line, FileName, ExpectedArguments);
}

/// <summary>Parses a Vector3 formatted as an array of strings</summary>
/// <param name="Arguments">The vector values</param>
/// <param name="Key">The key value</param>
/// <param name="Section">The section</param>
/// <param name="Line">The line</param>
/// <param name="FileName">The filename</param>
/// <param name="ExpectedArguments">Whether a minimum of three arguments is expected</param>
/// <returns>True if parsing succeeds, false otherwise</returns>
public static Vector3 TryParseVector3(string[] Arguments, string Key, string Section, int Line, string FileName, bool ExpectedArguments = false)
{
Vector3 parsedVector = new Vector3();
CultureInfo Culture = CultureInfo.InvariantCulture;

if (Arguments.Length >= 1 && Arguments[0].Length > 0 && !NumberFormats.TryParseDoubleVb6(Arguments[0], out parsedVector.X)) {
currentHost.AddMessage(MessageType.Error, false, "X is invalid in " + Key + " - " + Section + " at line " + (Line + 1).ToString(Culture) + " in " + FileName);
}
if (Arguments.Length >= 2 && Arguments[1].Length > 0 && !NumberFormats.TryParseDoubleVb6(Arguments[1], out parsedVector.Y)) {
currentHost.AddMessage(MessageType.Error, false, "Y is invalid in " + Key + " - " + Section + " at line " + (Line + 1).ToString(Culture) + " in " + FileName);
}
if (Arguments.Length >= 3 && Arguments[2].Length > 0 && !NumberFormats.TryParseDoubleVb6(Arguments[2], out parsedVector.Z)) {
currentHost.AddMessage(MessageType.Error, false, "Z is invalid in " + Key + " - " + Section + " at line " + (Line + 1).ToString(Culture) + " in " + FileName);
}

if (Arguments.Length < 3 && ExpectedArguments)
{
currentHost.AddMessage(MessageType.Error, false, "Three arguments are expected in " + Key + " - " + Section + " at line " + (Line + 1).ToString(Culture) + " in " + FileName);
}
return parsedVector;
}

/// <summary>Converts a value given in degrees to Radians</summary>
public static double ToRadians(this double degrees)
{
Expand Down
20 changes: 8 additions & 12 deletions source/OpenBveApi/Objects/Helpers/MeshBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -151,30 +151,26 @@ public void Apply(ref StaticObject Object, bool EnableHacks = false)
}

/// <summary>Translates the MeshBuilder by the given values</summary>
public void ApplyTranslation(double x, double y, double z)
public void ApplyTranslation(Vector3 translation)
{
for (int i = 0; i < Vertices.Length; i++)
{
Vertices[i].Coordinates.X += x;
Vertices[i].Coordinates.Y += y;
Vertices[i].Coordinates.Z += z;
Vertices[i].Coordinates += translation;
}
}

/// <summary>Scales the MeshBuilder by the given values</summary>
public void ApplyScale(double x, double y, double z)
public void ApplyScale(Vector3 scale)
{
float rx = (float) (1.0 / x);
float ry = (float) (1.0 / y);
float rz = (float) (1.0 / z);
float rx = (float) (1.0 / scale.X);
float ry = (float) (1.0 / scale.Y);
float rz = (float) (1.0 / scale.Z);
float rx2 = rx * rx;
float ry2 = ry * ry;
float rz2 = rz * rz;
for (int i = 0; i < Vertices.Length; i++)
{
Vertices[i].Coordinates.X *= x;
Vertices[i].Coordinates.Y *= y;
Vertices[i].Coordinates.Z *= z;
Vertices[i].Coordinates *= scale;
}

for (int i = 0; i < Faces.Length; i++)
Expand All @@ -195,7 +191,7 @@ public void ApplyScale(double x, double y, double z)
}
}

if (x * y * z < 0.0)
if (scale.X * scale.Y * scale.Z < 0.0)
{
for (int i = 0; i < Faces.Length; i++)
{
Expand Down
7 changes: 7 additions & 0 deletions source/OpenBveApi/System/Hosts.cs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,13 @@ protected HostInterface(HostApplication host)
Application = host;
StaticObjectCache = new Dictionary<ValueTuple<string, bool>, StaticObject>();
AnimatedObjectCollectionCache = new Dictionary<string, AnimatedObjectCollection>();
/*
* Let's cheat a little-
* When we parse a number, we may want to add a message that it's invalid
* We can assume that only one host interface is ever present, hence assign it here
* as it's in the same API
*/
NumberFormats.currentHost = this;
}

/// <summary></summary>
Expand Down
11 changes: 10 additions & 1 deletion source/OpenBveApi/Textures/Textures.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#pragma warning disable 0659, 0661
#pragma warning disable 0659, 0661

using System;
using System.Drawing;
Expand Down Expand Up @@ -149,6 +149,15 @@ public int Height
this.MyHeight = value;
}
}

/// <summary>Gets the size of the texture.</summary>
public OpenBveApi.Math.Vector2 Size
{
get
{
return new OpenBveApi.Math.Vector2(this.MyWidth, this.MyHeight);
}
}
/// <summary>Gets the number of bits per pixel.</summary>
public int BitsPerPixel
{
Expand Down
Loading