您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 

248 行
6.7 KiB

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. using System.Reflection;
  5. using SUISS.Core;
  6. using SUISS.Storage;
  7. namespace SUISSEngine
  8. {
  9. public abstract class AbstractState<T> : SingletonMonobehaviour<T> where T : AbstractState<T>
  10. {
  11. public static FieldInfo GetFieldFromHandle(RuntimeFieldHandle handle)
  12. {
  13. return FieldInfo.GetFieldFromHandle(handle);
  14. }
  15. //[DebuggerBrowsable(DebuggerBrowsableState.Never)]
  16. public event AbstractState<T>.ValueChangedHandler ValueChangedEvent;
  17. //[DebuggerBrowsable(DebuggerBrowsableState.Never)]
  18. public event AbstractState<T>.AnyValueChangedHandler AnyValueChangedEvent;
  19. public void FireValueChangedHandler(string key, object oldValue, object newValue)
  20. {
  21. if (this.ValueChangedEvent != null)
  22. {
  23. this.ValueChangedEvent(key, oldValue, newValue);
  24. }
  25. if (this.AnyValueChangedEvent != null)
  26. {
  27. this.AnyValueChangedEvent();
  28. }
  29. }
  30. public void FireAnyValueChangedEvent()
  31. {
  32. if (this.AnyValueChangedEvent != null)
  33. {
  34. this.AnyValueChangedEvent();
  35. }
  36. }
  37. protected Dictionary<string, object> Persistent
  38. {
  39. get
  40. {
  41. if (this.persistentDictionary == null)
  42. {
  43. if (!this.persistent.ContainsKey("dictionary"))
  44. {
  45. this.persistent.Add("dictionary", new Dictionary<string, object>());
  46. }
  47. this.persistentDictionary = (Dictionary<string, object>)this.persistent["dictionary"];
  48. }
  49. return this.persistentDictionary;
  50. }
  51. }
  52. protected override void Awake()
  53. {
  54. base.Awake();
  55. this.storage = Storage.Get(this.GetLifecycle());
  56. this.loadState();
  57. }
  58. protected virtual void Start()
  59. {
  60. }
  61. protected override void OnDestroy()
  62. {
  63. base.OnDestroy();
  64. this.ValueChangedEvent = null;
  65. if (this.storage != null)
  66. {
  67. this.storage.OnSync -= this.syncToStorage;
  68. }
  69. }
  70. public virtual V GetValue<V>(string key, V defaultvalue)
  71. {
  72. V result = defaultvalue;
  73. object obj;
  74. if (this.Persistent.TryGetValue(key, out obj) && obj is V)
  75. {
  76. result = (V)((object)obj);
  77. }
  78. return result;
  79. }
  80. public virtual object GetValue(string key, object defaultValue)
  81. {
  82. object result;
  83. if (!this.Persistent.TryGetValue(key, out result))
  84. {
  85. result = defaultValue;
  86. }
  87. return result;
  88. }
  89. public virtual void SetValue(string key, object value)
  90. {
  91. if (this.isNewState)
  92. {
  93. this.Persistent[key] = value;
  94. }
  95. else
  96. {
  97. object obj;
  98. if (!this.Persistent.TryGetValue(key, out obj))
  99. {
  100. obj = null;
  101. }
  102. if (!object.Equals(obj, value))
  103. {
  104. this.Persistent[key] = value;
  105. this.OnValueChanged(key, obj, value);
  106. }
  107. }
  108. }
  109. protected virtual void OnValueChanged(string key, object oldValue, object newValue)
  110. {
  111. this.FireValueChangedHandler(key, oldValue, newValue);
  112. }
  113. private void loadState()
  114. {
  115. if (this.storage.Root.ContainsKey(this.GetStorageKey()))
  116. {
  117. this.persistent = (Dictionary<string, object>)this.storage.Root[this.GetStorageKey()];
  118. if (!this.persistent.ContainsKey("dictionary"))
  119. {
  120. this.persistent["dictionary"] = new Dictionary<string, object>();
  121. }
  122. this.persistentDictionary = (Dictionary<string, object>)this.persistent["dictionary"];
  123. if (!this.persistent.ContainsKey("fields"))
  124. {
  125. this.persistent["fields"] = new Dictionary<string, object>();
  126. }
  127. this.persistentFields = (Dictionary<string, object>)this.persistent["fields"];
  128. this.syncToFields();
  129. this.storage.OnSync += this.syncToStorage;
  130. }
  131. else
  132. {
  133. this.persistent = new Dictionary<string, object>();
  134. this.persistentFields = new Dictionary<string, object>();
  135. this.persistent["fields"] = this.persistentFields;
  136. this.persistentDictionary = new Dictionary<string, object>();
  137. this.persistent["dictionary"] = this.persistentDictionary;
  138. this.storage.Root[this.GetStorageKey()] = this.persistent;
  139. this.storage.OnSync += this.syncToStorage;
  140. this.isNewState = true;
  141. this.OnNewGameState();
  142. this.isNewState = false;
  143. }
  144. }
  145. private void reflectOnPersistentFields()
  146. {
  147. this.persistentFieldHandles = new List<RuntimeFieldHandle>();
  148. Type type = base.GetType();
  149. FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy);
  150. foreach (FieldInfo fieldInfo in fields)
  151. {
  152. if (fieldInfo.IsDefined(typeof(PersistentAttribute), false))
  153. {
  154. this.persistentFieldHandles.Add(fieldInfo.GetFieldHandle());
  155. }
  156. }
  157. }
  158. private Dictionary<string, object> getFieldsDictionary()
  159. {
  160. if (this.persistentFields == null && !this.persistent.ContainsKey("fields"))
  161. {
  162. this.persistent.Add("fields", new Dictionary<string, object>());
  163. this.persistentFields = (Dictionary<string, object>)this.persistent["fields"];
  164. }
  165. return this.persistentFields;
  166. }
  167. private void syncToStorage()
  168. {
  169. if (this.persistentFieldHandles == null)
  170. {
  171. this.reflectOnPersistentFields();
  172. }
  173. if (this.persistent != null)
  174. {
  175. Dictionary<string, object> fieldsDictionary = this.getFieldsDictionary();
  176. foreach (RuntimeFieldHandle handle in this.persistentFieldHandles)
  177. {
  178. FieldInfo fieldFromHandle = AbstractState<T>.GetFieldFromHandle(handle);
  179. fieldsDictionary[fieldFromHandle.Name] = fieldFromHandle.GetValue(this);
  180. }
  181. }
  182. }
  183. private void syncToFields()
  184. {
  185. if (this.persistentFieldHandles == null)
  186. {
  187. this.reflectOnPersistentFields();
  188. }
  189. if (this.persistent != null)
  190. {
  191. Dictionary<string, object> fieldsDictionary = this.getFieldsDictionary();
  192. foreach (RuntimeFieldHandle handle in this.persistentFieldHandles)
  193. {
  194. FieldInfo fieldFromHandle = AbstractState<T>.GetFieldFromHandle(handle);
  195. if (fieldsDictionary.ContainsKey(fieldFromHandle.Name))
  196. {
  197. fieldFromHandle.SetValue(this, fieldsDictionary[fieldFromHandle.Name]);
  198. }
  199. }
  200. }
  201. }
  202. protected abstract void OnNewGameState();
  203. protected abstract string GetStorageKey();
  204. protected abstract StorageLifecycle GetLifecycle();
  205. private const string DictionaryKey = "dictionary";
  206. private const string FieldsKey = "fields";
  207. private Dictionary<string, object> persistent;
  208. private Dictionary<string, object> persistentDictionary;
  209. private Dictionary<string, object> persistentFields;
  210. private List<RuntimeFieldHandle> persistentFieldHandles;
  211. private Storage storage;
  212. protected bool isNewState;
  213. public delegate void ValueChangedHandler(string key, object oldValue, object newValue);
  214. public delegate void AnyValueChangedHandler();
  215. }
  216. }