Working on improving the serialization system and ObjectProperty/IPropertyObject (TODO: come up with better names). The plan is to:
- Add support for some of the most common types (vectors, colors, rects) so there's no need to parse the values in the setters of the serializable properties (see Holdable.HoldPos for example). - Make a generic version of the item editing HUD that can be used on any IPropertyObject. Should make it easier to implement things like the character editor, editing structure properties, particle editor, etc. - Improve the interface of the editing HUD. Instead of having to type in a string value into a textbox, there should be number input fields for numeric properties, sliders for properties that only accept a range of values, a color picker, etc. And tooltips.
This commit is contained in:
@@ -0,0 +1,17 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
interface IPropertyObject
|
||||
{
|
||||
string Name
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
Dictionary<string, ObjectProperty> ObjectProperties
|
||||
{
|
||||
get;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,385 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Xml.Linq;
|
||||
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Property)]
|
||||
public class Editable : System.Attribute
|
||||
{
|
||||
public int MaxLength;
|
||||
|
||||
public Editable(int maxLength = 20)
|
||||
{
|
||||
MaxLength = maxLength;
|
||||
}
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Property)]
|
||||
public class InGameEditable : Editable
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
[AttributeUsage(AttributeTargets.Property)]
|
||||
public class SerializableProperty : System.Attribute
|
||||
{
|
||||
public object defaultValue;
|
||||
public bool isSaveable;
|
||||
|
||||
public SerializableProperty(object defaultValue, bool isSaveable)
|
||||
{
|
||||
this.defaultValue = defaultValue;
|
||||
this.isSaveable = isSaveable;
|
||||
}
|
||||
}
|
||||
|
||||
class ObjectProperty
|
||||
{
|
||||
private readonly PropertyDescriptor propertyDescriptor;
|
||||
private readonly PropertyInfo propertyInfo;
|
||||
private readonly object obj;
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return propertyDescriptor.Name; }
|
||||
}
|
||||
|
||||
public AttributeCollection Attributes
|
||||
{
|
||||
get { return propertyDescriptor.Attributes; }
|
||||
}
|
||||
|
||||
public Type PropertyType
|
||||
{
|
||||
get
|
||||
{
|
||||
return propertyInfo.PropertyType;
|
||||
}
|
||||
}
|
||||
|
||||
public ObjectProperty(PropertyDescriptor property, object obj)
|
||||
{
|
||||
this.propertyDescriptor = property;
|
||||
propertyInfo = property.ComponentType.GetProperty(property.Name);
|
||||
this.obj = obj;
|
||||
}
|
||||
|
||||
public bool TrySetValue(string value)
|
||||
{
|
||||
if (value == null) return false;
|
||||
|
||||
if (propertyDescriptor.PropertyType == typeof(string))
|
||||
{
|
||||
propertyInfo.SetValue(obj, value, null);
|
||||
}
|
||||
else if (propertyDescriptor.PropertyType == typeof(float))
|
||||
{
|
||||
float floatVal;
|
||||
if (float.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out floatVal))
|
||||
{
|
||||
propertyInfo.SetValue(obj, floatVal, null);
|
||||
}
|
||||
}
|
||||
else if (propertyDescriptor.PropertyType == typeof(bool))
|
||||
{
|
||||
propertyInfo.SetValue(obj, value.ToLowerInvariant() == "true", null);
|
||||
}
|
||||
else if (propertyDescriptor.PropertyType == typeof(int))
|
||||
{
|
||||
int intVal;
|
||||
if (int.TryParse(value, out intVal))
|
||||
{
|
||||
propertyInfo.SetValue(obj, intVal, null);
|
||||
}
|
||||
}
|
||||
else if (propertyDescriptor.PropertyType == typeof(Vector2))
|
||||
{
|
||||
propertyInfo.SetValue(obj, XMLExtensions.ParseToVector2(value));
|
||||
}
|
||||
else if (propertyDescriptor.PropertyType == typeof(Vector3))
|
||||
{
|
||||
propertyInfo.SetValue(obj, XMLExtensions.ParseToVector3(value));
|
||||
}
|
||||
else if (propertyDescriptor.PropertyType == typeof(Vector4))
|
||||
{
|
||||
propertyInfo.SetValue(obj, XMLExtensions.ParseToVector4(value));
|
||||
}
|
||||
else if (propertyDescriptor.PropertyType == typeof(Color))
|
||||
{
|
||||
propertyInfo.SetValue(obj, XMLExtensions.ParseToColor(value));
|
||||
}
|
||||
else if (propertyDescriptor.PropertyType.IsEnum)
|
||||
{
|
||||
object enumVal;
|
||||
try
|
||||
{
|
||||
enumVal = Enum.Parse(propertyInfo.PropertyType, value);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugConsole.ThrowError("Failed to set the value of the property \"" + Name + "\" of \"" + obj + "\" to " + value + " (not a valid " + propertyInfo.PropertyType + ")", e);
|
||||
return false;
|
||||
}
|
||||
propertyInfo.SetValue(obj, enumVal);
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugConsole.ThrowError("Failed to set the value of the property \"" + Name + "\" of \"" + obj + "\" to " + value);
|
||||
DebugConsole.ThrowError("(Type not implemented)");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool TrySetValue(object value)
|
||||
{
|
||||
if (value == null) return false;
|
||||
if (obj == null || propertyDescriptor == null) return false;
|
||||
try
|
||||
{
|
||||
if (value.GetType() == typeof(string) &&
|
||||
propertyDescriptor.PropertyType == typeof(Vector2))
|
||||
{
|
||||
propertyInfo.SetValue(obj, XMLExtensions.ParseToVector2(value.ToString()));
|
||||
}
|
||||
else if (value.GetType() == typeof(string) &&
|
||||
propertyDescriptor.PropertyType == typeof(Vector3))
|
||||
{
|
||||
propertyInfo.SetValue(obj, XMLExtensions.ParseToVector3(value.ToString()));
|
||||
}
|
||||
else if (value.GetType() == typeof(string) &&
|
||||
propertyDescriptor.PropertyType == typeof(Vector4))
|
||||
{
|
||||
propertyInfo.SetValue(obj, XMLExtensions.ParseToVector4(value.ToString()));
|
||||
}
|
||||
else if (value.GetType() == typeof(string) &&
|
||||
propertyDescriptor.PropertyType == typeof(Color))
|
||||
{
|
||||
propertyInfo.SetValue(obj, XMLExtensions.ParseToColor(value.ToString()));
|
||||
}
|
||||
else if (propertyDescriptor.PropertyType != value.GetType())
|
||||
{
|
||||
DebugConsole.ThrowError("Failed to set the value of the property \"" + Name + "\" of \"" + obj.ToString() + "\" to " + value.ToString());
|
||||
DebugConsole.ThrowError("(Non-matching type, should be " + propertyDescriptor.PropertyType + " instead of " + value.GetType() + ")");
|
||||
return false;
|
||||
}
|
||||
|
||||
propertyInfo.SetValue(obj, value, null);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool TrySetValue(float value)
|
||||
{
|
||||
try
|
||||
{
|
||||
propertyInfo.SetValue(obj, value, null);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool TrySetValue(bool value)
|
||||
{
|
||||
try
|
||||
{
|
||||
propertyInfo.SetValue(obj, value, null);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool TrySetValue(int value)
|
||||
{
|
||||
try
|
||||
{
|
||||
propertyInfo.SetValue(obj, value, null);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public object GetValue()
|
||||
{
|
||||
if (obj == null || propertyDescriptor == null) return false;
|
||||
|
||||
try
|
||||
{
|
||||
return propertyInfo.GetValue(obj, null);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static List<ObjectProperty> GetProperties<T>(IPropertyObject obj)
|
||||
{
|
||||
List<ObjectProperty> editableProperties = new List<ObjectProperty>();
|
||||
|
||||
foreach (var property in obj.ObjectProperties.Values)
|
||||
{
|
||||
if (property.Attributes.OfType<T>().Any()) editableProperties.Add(property);
|
||||
}
|
||||
|
||||
return editableProperties;
|
||||
}
|
||||
|
||||
public static Dictionary<string, ObjectProperty> GetProperties(IPropertyObject obj)
|
||||
{
|
||||
var properties = TypeDescriptor.GetProperties(obj.GetType()).Cast<PropertyDescriptor>();
|
||||
|
||||
Dictionary<string, ObjectProperty> dictionary = new Dictionary<string, ObjectProperty>();
|
||||
|
||||
foreach (var property in properties)
|
||||
{
|
||||
dictionary.Add(property.Name.ToLowerInvariant(), new ObjectProperty(property, obj));
|
||||
}
|
||||
|
||||
return dictionary;
|
||||
}
|
||||
|
||||
/*/// <summary>
|
||||
/// Sets all serializable properties to their default value
|
||||
/// </summary>
|
||||
/// <param name="obj"></param>
|
||||
/// <returns></returns>
|
||||
public static Dictionary<string, ObjectProperty> InitProperties(IPropertyObject obj)
|
||||
{
|
||||
return DeserializeProperties(obj, null);
|
||||
}*/
|
||||
|
||||
public static Dictionary<string, ObjectProperty> DeserializeProperties(IPropertyObject obj, XElement element)
|
||||
{
|
||||
var properties = TypeDescriptor.GetProperties(obj.GetType()).Cast<PropertyDescriptor>();
|
||||
|
||||
Dictionary<string, ObjectProperty> dictionary = new Dictionary<string, ObjectProperty>();
|
||||
|
||||
foreach (var property in properties)
|
||||
{
|
||||
ObjectProperty objProperty = new ObjectProperty(property, obj);
|
||||
dictionary.Add(property.Name.ToLowerInvariant(), objProperty);
|
||||
|
||||
//set the value of the property to the default value if there is one
|
||||
foreach (var ini in property.Attributes.OfType<SerializableProperty>())
|
||||
{
|
||||
objProperty.TrySetValue(ini.defaultValue);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (element != null)
|
||||
{
|
||||
//go through all the attributes in the xml element
|
||||
//and set the value of the matching property if it is initializable
|
||||
foreach (XAttribute attribute in element.Attributes())
|
||||
{
|
||||
ObjectProperty property = null;
|
||||
if (!dictionary.TryGetValue(attribute.Name.ToString().ToLowerInvariant(), out property)) continue;
|
||||
if (!property.Attributes.OfType<SerializableProperty>().Any()) continue;
|
||||
property.TrySetValue(attribute.Value);
|
||||
}
|
||||
}
|
||||
|
||||
return dictionary;
|
||||
}
|
||||
|
||||
public static void SerializeProperties(IPropertyObject obj, XElement element, bool saveIfDefault = false)
|
||||
{
|
||||
var saveProperties = GetProperties<SerializableProperty>(obj);
|
||||
foreach (var property in saveProperties)
|
||||
{
|
||||
object value = property.GetValue();
|
||||
if (value == null) continue;
|
||||
|
||||
if (!saveIfDefault)
|
||||
{
|
||||
//only save
|
||||
// - if the attribute is saveable and it's different from the default value
|
||||
// - or can be changed in-game or in the editor
|
||||
bool save = false;
|
||||
foreach (var attribute in property.Attributes.OfType<SerializableProperty>())
|
||||
{
|
||||
if ((attribute.isSaveable && !attribute.defaultValue.Equals(value)) ||
|
||||
property.Attributes.OfType<Editable>().Any())
|
||||
{
|
||||
save = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!save) continue;
|
||||
}
|
||||
|
||||
string stringValue;
|
||||
if (value.GetType() == typeof(float))
|
||||
{
|
||||
//make sure the decimal point isn't converted to a comma or anything else
|
||||
stringValue = ((float)value).ToString("G", CultureInfo.InvariantCulture);
|
||||
}
|
||||
else if (value.GetType() == typeof(Vector2))
|
||||
{
|
||||
Vector2 vector = (Vector2)value;
|
||||
stringValue =
|
||||
vector.X.ToString("G", CultureInfo.InvariantCulture) + "," +
|
||||
vector.Y.ToString("G", CultureInfo.InvariantCulture);
|
||||
}
|
||||
else if (value.GetType() == typeof(Vector3))
|
||||
{
|
||||
Vector3 vector = (Vector3)value;
|
||||
stringValue =
|
||||
vector.X.ToString("G", CultureInfo.InvariantCulture) + "," +
|
||||
vector.Y.ToString("G", CultureInfo.InvariantCulture) + "," +
|
||||
vector.Z.ToString("G", CultureInfo.InvariantCulture);
|
||||
}
|
||||
else if (value.GetType() == typeof(Vector4))
|
||||
{
|
||||
Vector4 vector = (Vector4)value;
|
||||
stringValue =
|
||||
vector.X.ToString("G", CultureInfo.InvariantCulture) + "," +
|
||||
vector.Y.ToString("G", CultureInfo.InvariantCulture) + "," +
|
||||
vector.Z.ToString("G", CultureInfo.InvariantCulture) + "," +
|
||||
vector.W.ToString("G", CultureInfo.InvariantCulture);
|
||||
}
|
||||
else if (value.GetType() == typeof(Color))
|
||||
{
|
||||
Color color = (Color)value;
|
||||
stringValue =
|
||||
(color.R / 255.0f).ToString("G", CultureInfo.InvariantCulture) + "," +
|
||||
(color.G / 255.0f).ToString("G", CultureInfo.InvariantCulture) + "," +
|
||||
(color.B / 255.0f).ToString("G", CultureInfo.InvariantCulture) + "," +
|
||||
(color.A / 255.0f).ToString("G", CultureInfo.InvariantCulture);
|
||||
}
|
||||
else
|
||||
{
|
||||
stringValue = value.ToString();
|
||||
}
|
||||
|
||||
element.Add(new XAttribute(property.Name.ToLowerInvariant(), stringValue));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,336 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
using System.Xml.Linq;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
public static class XMLExtensions
|
||||
{
|
||||
public static XDocument TryLoadXml(string filePath)
|
||||
{
|
||||
XDocument doc;
|
||||
try
|
||||
{
|
||||
ToolBox.IsProperFilenameCase(filePath);
|
||||
doc = XDocument.Load(filePath);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugConsole.ThrowError("Couldn't load xml document \"" + filePath + "\"!", e);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (doc.Root == null) return null;
|
||||
|
||||
return doc;
|
||||
}
|
||||
|
||||
public static object GetAttributeObject(XAttribute attribute)
|
||||
{
|
||||
if (attribute == null) return null;
|
||||
|
||||
return ParseToObject(attribute.Value.ToString());
|
||||
}
|
||||
|
||||
public static object ParseToObject(string value)
|
||||
{
|
||||
float floatVal;
|
||||
int intVal;
|
||||
if (value.Contains(".") && Single.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out floatVal))
|
||||
{
|
||||
return floatVal;
|
||||
}
|
||||
if (Int32.TryParse(value, out intVal))
|
||||
{
|
||||
return intVal;
|
||||
}
|
||||
|
||||
string lowerTrimmedVal = value.ToLowerInvariant().Trim();
|
||||
if (lowerTrimmedVal == "true")
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (lowerTrimmedVal == "false")
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
public static string GetAttributeString(this XElement element, string name, string defaultValue)
|
||||
{
|
||||
if (element?.Attribute(name) == null) return defaultValue;
|
||||
return GetAttributeString(element.Attribute(name), defaultValue);
|
||||
}
|
||||
|
||||
private static string GetAttributeString(XAttribute attribute, string defaultValue)
|
||||
{
|
||||
string value = attribute.Value;
|
||||
return String.IsNullOrEmpty(value) ? defaultValue : value;
|
||||
}
|
||||
|
||||
public static float GetAttributeFloat(this XElement element, float defaultValue, params string[] matchingAttributeName)
|
||||
{
|
||||
if (element == null) return defaultValue;
|
||||
|
||||
foreach (string name in matchingAttributeName)
|
||||
{
|
||||
if (element.Attribute(name) == null) continue;
|
||||
|
||||
float val;
|
||||
|
||||
try
|
||||
{
|
||||
if (!Single.TryParse(element.Attribute(name).Value, NumberStyles.Float, CultureInfo.InvariantCulture, out val))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugConsole.ThrowError("Error in " + element + "!", e);
|
||||
continue;
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
public static float GetAttributeFloat(this XElement element, string name, float defaultValue)
|
||||
{
|
||||
if (element?.Attribute(name) == null) return defaultValue;
|
||||
|
||||
float val = defaultValue;
|
||||
|
||||
try
|
||||
{
|
||||
if (!Single.TryParse(element.Attribute(name).Value, NumberStyles.Float, CultureInfo.InvariantCulture, out val))
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugConsole.ThrowError("Error in " + element + "!", e);
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
public static float GetAttributeFloat(this XAttribute attribute, float defaultValue)
|
||||
{
|
||||
if (attribute == null) return defaultValue;
|
||||
|
||||
float val = defaultValue;
|
||||
|
||||
try
|
||||
{
|
||||
val = Single.Parse(attribute.Value, CultureInfo.InvariantCulture);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugConsole.ThrowError("Error in " + attribute + "! ", e);
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
public static int GetAttributeInt(this XElement element, string name, int defaultValue)
|
||||
{
|
||||
if (element?.Attribute(name) == null) return defaultValue;
|
||||
|
||||
int val = defaultValue;
|
||||
|
||||
try
|
||||
{
|
||||
val = Int32.Parse(element.Attribute(name).Value);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugConsole.ThrowError("Error in " + element + "! ", e);
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
public static bool GetAttributeBool(this XElement element, string name, bool defaultValue)
|
||||
{
|
||||
if (element?.Attribute(name) == null) return defaultValue;
|
||||
|
||||
return element.Attribute(name).GetAttributeBool(defaultValue);
|
||||
}
|
||||
|
||||
public static bool GetAttributeBool(this XAttribute attribute, bool defaultValue)
|
||||
{
|
||||
if (attribute == null) return defaultValue;
|
||||
|
||||
string val = attribute.Value.ToLowerInvariant().Trim();
|
||||
if (val == "true")
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (val == "false")
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
DebugConsole.ThrowError("Error in " + attribute.Value.ToString() + "! \"" + val + "\" is not a valid boolean value");
|
||||
return false;
|
||||
}
|
||||
|
||||
public static Vector2 GetAttributeVector2(this XElement element, string name, Vector2 defaultValue)
|
||||
{
|
||||
if (element?.Attribute(name) == null) return defaultValue;
|
||||
|
||||
string val = element.Attribute(name).Value;
|
||||
|
||||
return ParseToVector2(val);
|
||||
}
|
||||
|
||||
public static Vector3 GetAttributeVector3(this XElement element, string name, Vector3 defaultValue)
|
||||
{
|
||||
if (element == null || element.Attribute(name) == null) return defaultValue;
|
||||
|
||||
string val = element.Attribute(name).Value;
|
||||
|
||||
return ParseToVector3(val);
|
||||
}
|
||||
|
||||
public static Vector4 GetAttributeVector4(this XElement element, string name, Vector4 defaultValue)
|
||||
{
|
||||
if (element == null || element.Attribute(name) == null) return defaultValue;
|
||||
|
||||
string val = element.Attribute(name).Value;
|
||||
|
||||
return ParseToVector4(val);
|
||||
}
|
||||
|
||||
public static string ElementInnerText(this XElement el)
|
||||
{
|
||||
StringBuilder str = new StringBuilder();
|
||||
foreach (XNode element in el.DescendantNodes().Where(x => x.NodeType == XmlNodeType.Text))
|
||||
{
|
||||
str.Append(element.ToString());
|
||||
}
|
||||
return str.ToString();
|
||||
}
|
||||
|
||||
|
||||
public static Vector2 ParseToVector2(string stringVector2, bool errorMessages = true)
|
||||
{
|
||||
string[] components = stringVector2.Split(',');
|
||||
|
||||
Vector2 vector = Vector2.Zero;
|
||||
|
||||
if (components.Length != 2)
|
||||
{
|
||||
if (!errorMessages) return vector;
|
||||
DebugConsole.ThrowError("Failed to parse the string \"" + stringVector2 + "\" to Vector2");
|
||||
return vector;
|
||||
}
|
||||
|
||||
Single.TryParse(components[0], NumberStyles.Any, CultureInfo.InvariantCulture, out vector.X);
|
||||
Single.TryParse(components[1], NumberStyles.Any, CultureInfo.InvariantCulture, out vector.Y);
|
||||
|
||||
return vector;
|
||||
}
|
||||
|
||||
public static string Vector2ToString(Vector2 vector)
|
||||
{
|
||||
return vector.X.ToString("G", CultureInfo.InvariantCulture) + "," + vector.Y.ToString("G", CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
public static Vector3 ParseToVector3(string stringVector3, bool errorMessages = true)
|
||||
{
|
||||
string[] components = stringVector3.Split(',');
|
||||
|
||||
Vector3 vector = Vector3.Zero;
|
||||
|
||||
if (components.Length != 3)
|
||||
{
|
||||
if (!errorMessages) return vector;
|
||||
DebugConsole.ThrowError("Failed to parse the string \"" + stringVector3 + "\" to Vector3");
|
||||
return vector;
|
||||
}
|
||||
|
||||
Single.TryParse(components[0], NumberStyles.Any, CultureInfo.InvariantCulture, out vector.X);
|
||||
Single.TryParse(components[1], NumberStyles.Any, CultureInfo.InvariantCulture, out vector.Y);
|
||||
Single.TryParse(components[2], NumberStyles.Any, CultureInfo.InvariantCulture, out vector.Z);
|
||||
|
||||
return vector;
|
||||
}
|
||||
|
||||
public static Vector4 ParseToVector4(string stringVector4, bool errorMessages = true)
|
||||
{
|
||||
string[] components = stringVector4.Split(',');
|
||||
|
||||
Vector4 vector = Vector4.Zero;
|
||||
|
||||
if (components.Length < 3)
|
||||
{
|
||||
if (errorMessages) DebugConsole.ThrowError("Failed to parse the string \"" + stringVector4 + "\" to Vector4");
|
||||
return vector;
|
||||
}
|
||||
|
||||
Single.TryParse(components[0], NumberStyles.Float, CultureInfo.InvariantCulture, out vector.X);
|
||||
Single.TryParse(components[1], NumberStyles.Float, CultureInfo.InvariantCulture, out vector.Y);
|
||||
Single.TryParse(components[2], NumberStyles.Float, CultureInfo.InvariantCulture, out vector.Z);
|
||||
if (components.Length > 3)
|
||||
Single.TryParse(components[3], NumberStyles.Float, CultureInfo.InvariantCulture, out vector.W);
|
||||
|
||||
return vector;
|
||||
}
|
||||
|
||||
public static Color ParseToColor(string stringColor, bool errorMessages = true)
|
||||
{
|
||||
string[] strComponents = stringColor.Split(',');
|
||||
|
||||
Color color = Color.White;
|
||||
|
||||
if (strComponents.Length < 3)
|
||||
{
|
||||
if (errorMessages) DebugConsole.ThrowError("Failed to parse the string \"" + stringColor + "\" to Color");
|
||||
return Color.White;
|
||||
}
|
||||
|
||||
float[] components = new float[4] { 1.0f, 1.0f, 1.0f, 1.0f };
|
||||
|
||||
for (int i = 0; i < 4 && i < strComponents.Length; i++)
|
||||
{
|
||||
float.TryParse(strComponents[i], NumberStyles.Float, CultureInfo.InvariantCulture, out components[i]);
|
||||
}
|
||||
|
||||
return new Color(components[0], components[1], components[2], components[3]);
|
||||
}
|
||||
|
||||
public static string Vector4ToString(Vector4 vector, string format = "G")
|
||||
{
|
||||
return vector.X.ToString(format, CultureInfo.InvariantCulture) + "," +
|
||||
vector.Y.ToString(format, CultureInfo.InvariantCulture) + "," +
|
||||
vector.Z.ToString(format, CultureInfo.InvariantCulture) + "," +
|
||||
vector.W.ToString(format, CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
public static float[] ParseArrayToFloat(string[] stringArray)
|
||||
{
|
||||
if (stringArray == null || stringArray.Length == 0) return null;
|
||||
|
||||
float[] floatArray = new float[stringArray.Length];
|
||||
for (int i = 0; i < floatArray.Length; i++)
|
||||
{
|
||||
floatArray[i] = 0.0f;
|
||||
Single.TryParse(stringArray[i], NumberStyles.Float, CultureInfo.InvariantCulture, out floatArray[i]);
|
||||
}
|
||||
|
||||
return floatArray;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user