| using System; |
| using System.Collections.Generic; |
| using System.Reflection; |
|
|
| namespace UnityEngine.InputSystem.Utilities |
| { |
| |
| |
| |
| public struct NamedValue : IEquatable<NamedValue> |
| { |
| public const string Separator = ","; |
|
|
| |
| |
| |
| public string name { get; set; } |
|
|
| |
| |
| |
| public PrimitiveValue value { get; set; } |
|
|
| public TypeCode type => value.type; |
|
|
| public NamedValue ConvertTo(TypeCode type) |
| { |
| return new NamedValue |
| { |
| name = name, |
| value = value.ConvertTo(type) |
| }; |
| } |
|
|
| public static NamedValue From<TValue>(string name, TValue value) |
| where TValue : struct |
| { |
| return new NamedValue |
| { |
| name = name, |
| value = PrimitiveValue.From(value) |
| }; |
| } |
|
|
| public override string ToString() |
| { |
| return $"{name}={value}"; |
| } |
|
|
| public bool Equals(NamedValue other) |
| { |
| return string.Equals(name, other.name, StringComparison.InvariantCultureIgnoreCase) |
| && value == other.value; |
| } |
|
|
| public override bool Equals(object obj) |
| { |
| if (ReferenceEquals(null, obj)) |
| return false; |
| return obj is NamedValue parameterValue && Equals(parameterValue); |
| } |
|
|
| public override int GetHashCode() |
| { |
| unchecked |
| { |
| var hashCode = (name != null ? name.GetHashCode() : 0); |
| hashCode = (hashCode * 397) ^ value.GetHashCode(); |
| return hashCode; |
| } |
| } |
|
|
| public static bool operator==(NamedValue left, NamedValue right) |
| { |
| return left.Equals(right); |
| } |
|
|
| public static bool operator!=(NamedValue left, NamedValue right) |
| { |
| return !left.Equals(right); |
| } |
|
|
| public static NamedValue[] ParseMultiple(string parameterString) |
| { |
| if (parameterString == null) |
| throw new ArgumentNullException(nameof(parameterString)); |
|
|
| parameterString = parameterString.Trim(); |
| if (string.IsNullOrEmpty(parameterString)) |
| return null; |
|
|
| var parameterCount = parameterString.CountOccurrences(Separator[0]) + 1; |
| var parameters = new NamedValue[parameterCount]; |
|
|
| var index = 0; |
| for (var i = 0; i < parameterCount; ++i) |
| { |
| var parameter = ParseParameter(parameterString, ref index); |
| parameters[i] = parameter; |
| } |
|
|
| return parameters; |
| } |
|
|
| public static NamedValue Parse(string str) |
| { |
| var index = 0; |
| return ParseParameter(str, ref index); |
| } |
|
|
| private static NamedValue ParseParameter(string parameterString, ref int index) |
| { |
| var parameter = new NamedValue(); |
| var parameterStringLength = parameterString.Length; |
|
|
| |
| while (index < parameterStringLength && char.IsWhiteSpace(parameterString[index])) |
| ++index; |
|
|
| |
| var nameStart = index; |
| while (index < parameterStringLength) |
| { |
| var nextChar = parameterString[index]; |
| if (nextChar == '=' || nextChar == Separator[0] || char.IsWhiteSpace(nextChar)) |
| break; |
| ++index; |
| } |
| parameter.name = parameterString.Substring(nameStart, index - nameStart); |
|
|
| |
| while (index < parameterStringLength && char.IsWhiteSpace(parameterString[index])) |
| ++index; |
|
|
| if (index == parameterStringLength || parameterString[index] != '=') |
| { |
| |
| parameter.value = true; |
| } |
| else |
| { |
| ++index; |
|
|
| |
| while (index < parameterStringLength && char.IsWhiteSpace(parameterString[index])) |
| ++index; |
|
|
| |
| var valueStart = index; |
| while (index < parameterStringLength && |
| !(parameterString[index] == Separator[0] || char.IsWhiteSpace(parameterString[index]))) |
| ++index; |
|
|
| |
|
|
| var value = parameterString.Substring(valueStart, index - valueStart); |
| parameter.value = PrimitiveValue.FromString(value); |
| } |
|
|
| if (index < parameterStringLength && parameterString[index] == Separator[0]) |
| ++index; |
|
|
| return parameter; |
| } |
|
|
| public void ApplyToObject(object instance) |
| { |
| if (instance == null) |
| throw new System.ArgumentNullException(nameof(instance)); |
|
|
| var instanceType = instance.GetType(); |
|
|
| |
| var field = instanceType.GetField(name, |
| BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); |
| if (field == null) |
| throw new ArgumentException( |
| $"Cannot find public field '{name}' in '{instanceType.Name}' (while trying to apply parameter)", nameof(instance)); |
|
|
| |
| var fieldTypeCode = Type.GetTypeCode(field.FieldType); |
| field.SetValue(instance, value.ConvertTo(fieldTypeCode).ToObject()); |
| } |
|
|
| public static void ApplyAllToObject<TParameterList>(object instance, TParameterList parameters) |
| where TParameterList : IEnumerable<NamedValue> |
| { |
| foreach (var parameter in parameters) |
| parameter.ApplyToObject(instance); |
| } |
| } |
| } |
|
|