test
This commit is contained in:
@@ -0,0 +1,192 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
|
||||
namespace UnityEngine.InputSystem.Utilities
|
||||
{
|
||||
/// <summary>
|
||||
/// A combination of a name and a value assignment for it.
|
||||
/// </summary>
|
||||
public struct NamedValue : IEquatable<NamedValue>
|
||||
{
|
||||
public const string Separator = ",";
|
||||
|
||||
/// <summary>
|
||||
/// Name of the parameter.
|
||||
/// </summary>
|
||||
public string name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Value of the parameter.
|
||||
/// </summary>
|
||||
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;
|
||||
|
||||
// Skip whitespace.
|
||||
while (index < parameterStringLength && char.IsWhiteSpace(parameterString[index]))
|
||||
++index;
|
||||
|
||||
// Parse name.
|
||||
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);
|
||||
|
||||
// Skip whitespace.
|
||||
while (index < parameterStringLength && char.IsWhiteSpace(parameterString[index]))
|
||||
++index;
|
||||
|
||||
if (index == parameterStringLength || parameterString[index] != '=')
|
||||
{
|
||||
// No value given so take "=true" as implied.
|
||||
parameter.value = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
++index; // Skip over '='.
|
||||
|
||||
// Skip whitespace.
|
||||
while (index < parameterStringLength && char.IsWhiteSpace(parameterString[index]))
|
||||
++index;
|
||||
|
||||
// Parse value.
|
||||
var valueStart = index;
|
||||
while (index < parameterStringLength &&
|
||||
!(parameterString[index] == Separator[0] || char.IsWhiteSpace(parameterString[index])))
|
||||
++index;
|
||||
|
||||
////TODO: use Substring struct here so that we don't allocate lots of useless strings
|
||||
|
||||
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();
|
||||
|
||||
////REVIEW: what about properties?
|
||||
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));
|
||||
|
||||
////REVIEW: would be awesome to be able to do this without boxing
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user