2using System.Collections.Generic;
4using System.Linq.Expressions;
5using System.Reflection;
6using Newtonsoft.Json.Linq;
9[AttributeUsage(AttributeTargets.Property)]
14 private static readonly Dictionary<string, (PropertyInfo property, Func<object> getter, Action<object> setter)>
_contextVars =
new Dictionary<
string, (PropertyInfo, Func<object>, Action<object>)>();
23 public override void Register(PropertyInfo property)
31 MethodInfo getMethod =
property.GetMethod;
32 MethodInfo setMethod =
property.SetMethod;
33 if (!(getMethod ==
null) && !(setMethod ==
null) && getMethod.IsStatic && setMethod.IsStatic)
37 Type declaringType =
property.DeclaringType;
44 return Expression.Lambda<Func<object>>(Expression.Convert(Expression.Call(method), typeof(
object)), Array.Empty<ParameterExpression>()).Compile();
49 Type parameterType = method.GetParameters()[0].ParameterType;
50 ParameterExpression parameterExpression = Expression.Parameter(typeof(
object),
"obj");
51 UnaryExpression arg = Expression.Convert(parameterExpression, parameterType);
52 return Expression.Lambda<Action<object>>(Expression.Call(method, arg),
new ParameterExpression[1] { parameterExpression }).Compile();
57 if (!context.Load<Dictionary<string, object>>(
"context_vars", out var data))
59 data =
new Dictionary<string, object>();
61 KeyValuePair<string, (PropertyInfo, Func<object>, Action<object>)>[] array =
_contextVars.ToArray();
62 foreach (KeyValuePair<
string, (PropertyInfo, Func<object>, Action<object>)> keyValuePair in array)
64 keyValuePair.Deconstruct(out var key, out var value);
65 (PropertyInfo, Func<object>, Action<object>) tuple = value;
67 var (propertyInfo, _, action) = tuple;
70 string key2 = propertyInfo.DeclaringType.FullName +
":" + text;
71 object valueOrDefault = data.GetValueOrDefault(key2);
72 action(CoerceValue(valueOrDefault, propertyInfo.PropertyType));
76 Debug.LogError(
$"#io failed to populate context var {text}\n{arg}");
79 static object CoerceValue(
object obj, Type type)
81 if (obj is JToken jToken)
83 return jToken.ToObject(type);
87 return type.IsValueType ? Activator.CreateInstance(type) :
null;
90 return DynamicReflection.TryCoerce(obj, type, out result) ? result : obj;
96 Dictionary<string, object> dictionary =
new Dictionary<string, object>(StringComparer.Ordinal);
97 KeyValuePair<string, (PropertyInfo, Func<object>, Action<object>)>[] array =
_contextVars.ToArray();
98 foreach (KeyValuePair<
string, (PropertyInfo, Func<object>, Action<object>)> keyValuePair in array)
100 keyValuePair.Deconstruct(out var key, out var value);
101 (PropertyInfo, Func<object>, Action<object>) tuple = value;
103 var (propertyInfo, func, _) = tuple;
106 object value2 = func();
107 string key2 = propertyInfo.DeclaringType.FullName +
":" + text;
108 dictionary[key2] = value2;
110 catch (Exception arg)
112 Debug.LogError(
$"#io failed to save context var {text}\n{arg}");
115 context.Save(
"context_vars", dictionary);
static void SubscribeEvent(string eventId, Action< object > handler)
static Func< object > CreateGetterDelegate(MethodInfo method)
override void Register(PropertyInfo property)
static readonly Dictionary< string,(PropertyInfo property, Func< object > getter, Action< object > setter)> _contextVars
static void SaveGameIOProperty(GameIOContext context)
static Action< object > CreateSetterDelegate(MethodInfo method)
static void LoadGameIOProperty(GameIOContext context)
ElinGameIOPropertyAttribute(string chunkName)