|
- using System;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.Reflection;
- using SUISS.Storage;
-
- namespace SUISSEngine
- {
- public abstract class StatefulSingleton<T> : Singleton<T> where T : StatefulSingleton<T>, new()
- {
- protected StatefulSingleton()
- {
- this._storage = Storage.Get(this.GetLifecycle());
- this.LoadState();
- }
-
- public static FieldInfo GetFieldFromHandle(RuntimeFieldHandle handle)
- {
- return FieldInfo.GetFieldFromHandle(handle);
- }
-
- //[DebuggerBrowsable(DebuggerBrowsableState.Never)]
- public event StatefulSingleton<T>.ValueChangedHandler ValueChangedEvent;
-
- //[DebuggerBrowsable(DebuggerBrowsableState.Never)]
- public event StatefulSingleton<T>.AnyValueChangedHandler AnyValueChangedEvent;
-
- public void FireValueChangedHandler(string key, object oldValue, object newValue)
- {
- if (this.ValueChangedEvent != null)
- {
- this.ValueChangedEvent(key, oldValue, newValue);
- }
- if (this.AnyValueChangedEvent != null)
- {
- this.AnyValueChangedEvent();
- }
- }
-
- public void FireAnyValueChangedEvent()
- {
- if (this.AnyValueChangedEvent != null)
- {
- this.AnyValueChangedEvent();
- }
- }
-
- public Dictionary<string, object> Persistent
- {
- get
- {
- if (this._persistentDictionary == null)
- {
- if (!this._persistent.ContainsKey("dictionary"))
- {
- this._persistent.Add("dictionary", new Dictionary<string, object>());
- }
- this._persistentDictionary = (Dictionary<string, object>)this._persistent["dictionary"];
- }
- return this._persistentDictionary;
- }
- }
-
- public virtual object GetValue(string key)
- {
- return this.GetValue(key, null);
- }
-
- public virtual object GetValue(string key, object defaultValue)
- {
- object result;
- if (!this.Persistent.TryGetValue(key, out result))
- {
- result = defaultValue;
- }
- return result;
- }
-
- public virtual void SetValue(string key, object value)
- {
- if (this._isNewState)
- {
- this.Persistent[key] = value;
- }
- else
- {
- object obj;
- if (!this.Persistent.TryGetValue(key, out obj))
- {
- obj = null;
- }
- if (!object.Equals(obj, value))
- {
- this.Persistent[key] = value;
- this.OnValueChanged(key, obj, value);
- }
- }
- }
-
- public virtual bool ContainsValue(string key)
- {
- return this.Persistent.ContainsKey(key);
- }
-
- protected virtual void OnValueChanged(string key, object oldValue, object newValue)
- {
- this.FireValueChangedHandler(key, oldValue, newValue);
- }
-
- private void LoadState()
- {
- if (this._storage.Root.ContainsKey(this.GetStorageKey()))
- {
- this._persistent = (Dictionary<string, object>)this._storage.Root[this.GetStorageKey()];
- if (!this._persistent.ContainsKey("dictionary"))
- {
- this._persistent["dictionary"] = new Dictionary<string, object>();
- }
- this._persistentDictionary = (Dictionary<string, object>)this._persistent["dictionary"];
- if (!this._persistent.ContainsKey("fields"))
- {
- this._persistent["fields"] = new Dictionary<string, object>();
- }
- this._persistentFields = (Dictionary<string, object>)this._persistent["fields"];
- this.SyncToFields();
- this._storage.OnSync += this.SyncToStorage;
- }
- else
- {
- this._persistent = new Dictionary<string, object>();
- this._persistentFields = new Dictionary<string, object>();
- this._persistent["fields"] = this._persistentFields;
- this._persistentDictionary = new Dictionary<string, object>();
- this._persistent["dictionary"] = this._persistentDictionary;
- this._storage.Root[this.GetStorageKey()] = this._persistent;
- this._storage.OnSync += this.SyncToStorage;
- this._isNewState = true;
- this.OnNewGameState();
- this._isNewState = false;
- }
- }
-
- protected abstract void OnNewGameState();
-
- protected abstract string GetStorageKey();
-
- protected abstract StorageLifecycle GetLifecycle();
-
- private void ReflectOnPersistentFields()
- {
- this._persistentFieldHandles = new List<RuntimeFieldHandle>();
- Type type = base.GetType();
- FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy);
- foreach (FieldInfo fieldInfo in fields)
- {
- if (fieldInfo.IsDefined(typeof(PersistentAttribute), false))
- {
- this._persistentFieldHandles.Add(fieldInfo.GetFieldHandle());
- }
- }
- }
-
- private Dictionary<string, object> GetFieldsDictionary()
- {
- if (this._persistentFields == null && !this._persistent.ContainsKey("fields"))
- {
- this._persistent.Add("fields", new Dictionary<string, object>());
- this._persistentFields = (Dictionary<string, object>)this._persistent["fields"];
- }
- return this._persistentFields;
- }
-
- private void SyncToStorage()
- {
- if (this._persistentFieldHandles == null)
- {
- this.ReflectOnPersistentFields();
- }
- if (this._persistent != null)
- {
- Dictionary<string, object> fieldsDictionary = this.GetFieldsDictionary();
- foreach (RuntimeFieldHandle handle in this._persistentFieldHandles)
- {
- FieldInfo fieldFromHandle = StatefulSingleton<T>.GetFieldFromHandle(handle);
- fieldsDictionary[fieldFromHandle.Name] = fieldFromHandle.GetValue(this);
- }
- }
- }
-
- private void SyncToFields()
- {
- if (this._persistentFieldHandles == null)
- {
- this.ReflectOnPersistentFields();
- }
- if (this._persistent != null)
- {
- Dictionary<string, object> fieldsDictionary = this.GetFieldsDictionary();
- foreach (RuntimeFieldHandle handle in this._persistentFieldHandles)
- {
- FieldInfo fieldFromHandle = StatefulSingleton<T>.GetFieldFromHandle(handle);
- if (fieldsDictionary.ContainsKey(fieldFromHandle.Name))
- {
- fieldFromHandle.SetValue(this, fieldsDictionary[fieldFromHandle.Name]);
- }
- }
- }
- }
-
- private const string DictionaryKey = "dictionary";
-
- private const string FieldsKey = "fields";
-
- private Dictionary<string, object> _persistent;
-
- private Dictionary<string, object> _persistentDictionary;
-
- private Dictionary<string, object> _persistentFields;
-
- private List<RuntimeFieldHandle> _persistentFieldHandles;
-
- private Storage _storage;
-
- protected bool _isNewState;
-
- public delegate void ValueChangedHandler(string key, object oldValue, object newValue);
-
- public delegate void AnyValueChangedHandler();
- }
- }
|