Elin Decompiled Documentation EA 23.315 Nightly
Loading...
Searching...
No Matches
ElinGameIOPropertyAttribute.cs
Go to the documentation of this file.
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Linq.Expressions;
5using System.Reflection;
6using UnityEngine;
7
8[AttributeUsage(AttributeTargets.Property)]
10{
11 private static bool _registered;
12
13 private static readonly Dictionary<string, (PropertyInfo property, Func<object> getter, Action<object> setter)> _contextVars = new Dictionary<string, (PropertyInfo, Func<object>, Action<object>)>();
14
15 public string ChunkName { get; }
16
17 public ElinGameIOPropertyAttribute(string chunkName)
18 {
19 ChunkName = chunkName;
20 }
21
22 public override void Register(PropertyInfo property)
23 {
24 if (!_registered)
25 {
26 BaseModManager.SubscribeEvent<GameIOContext>("elin.game.post_load", LoadGameIOProperty);
27 BaseModManager.SubscribeEvent<GameIOContext>("elin.game.post_save", SaveGameIOProperty);
28 _registered = true;
29 }
30 MethodInfo getMethod = property.GetMethod;
31 MethodInfo setMethod = property.SetMethod;
32 if (!(getMethod == null) && !(setMethod == null) && setMethod.IsStatic)
33 {
34 Func<object> item = getMethod.CreateDelegate<Func<object>>();
35 Action<object> item2 = CreateSetterDelegate(setMethod);
36 Type declaringType = property.DeclaringType;
37 _contextVars[declaringType.FullName + ":" + ChunkName] = (property, item, item2);
38 }
39 }
40
41 private static Action<object> CreateSetterDelegate(MethodInfo method)
42 {
43 Type parameterType = method.GetParameters()[0].ParameterType;
44 ParameterExpression parameterExpression = Expression.Parameter(typeof(object), "obj");
45 UnaryExpression arg = Expression.Convert(parameterExpression, parameterType);
46 return Expression.Lambda<Action<object>>(Expression.Call(method, arg), new ParameterExpression[1] { parameterExpression }).Compile();
47 }
48
49 private static void LoadGameIOProperty(GameIOContext context)
50 {
51 if (!context.Load<Dictionary<string, object>>("context_vars", out var data))
52 {
53 data = new Dictionary<string, object>();
54 }
55 KeyValuePair<string, (PropertyInfo, Func<object>, Action<object>)>[] array = _contextVars.ToArray();
56 foreach (KeyValuePair<string, (PropertyInfo, Func<object>, Action<object>)> keyValuePair in array)
57 {
58 keyValuePair.Deconstruct(out var key, out var value);
59 (PropertyInfo, Func<object>, Action<object>) tuple = value;
60 string text = key;
61 var (propertyInfo, _, action) = tuple;
62 try
63 {
64 string key2 = propertyInfo.DeclaringType.FullName + ":" + text;
65 object valueOrDefault = data.GetValueOrDefault(key2);
66 action(valueOrDefault);
67 }
68 catch (Exception arg)
69 {
70 Debug.LogError($"#io failed to populate context var {text}\n{arg}");
71 _contextVars.Remove(text);
72 }
73 }
74 }
75
76 private static void SaveGameIOProperty(GameIOContext context)
77 {
78 Dictionary<string, object> dictionary = new Dictionary<string, object>(StringComparer.Ordinal);
79 KeyValuePair<string, (PropertyInfo, Func<object>, Action<object>)>[] array = _contextVars.ToArray();
80 foreach (KeyValuePair<string, (PropertyInfo, Func<object>, Action<object>)> keyValuePair in array)
81 {
82 keyValuePair.Deconstruct(out var key, out var value);
83 (PropertyInfo, Func<object>, Action<object>) tuple = value;
84 string text = key;
85 var (propertyInfo, func, _) = tuple;
86 try
87 {
88 object value2 = func();
89 string key2 = propertyInfo.DeclaringType.FullName + ":" + text;
90 dictionary[key2] = value2;
91 }
92 catch (Exception arg)
93 {
94 Debug.LogError($"#io failed to save context var {text}\n{arg}");
95 _contextVars.Remove(text);
96 }
97 }
98 context.Save("context_vars", dictionary);
99 }
100}
static void SubscribeEvent(string eventId, Action< object > handler)
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)