選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。
 
 
 

231 行
6.4 KiB

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