|
- using System;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.Reflection;
- using SUISS.Core;
- using SUISS.Storage;
-
- namespace SUISSEngine
- {
- public abstract class AbstractState<T> : SingletonMonobehaviour<T> where T : AbstractState<T>
- {
- public static FieldInfo GetFieldFromHandle(RuntimeFieldHandle handle)
- {
- return FieldInfo.GetFieldFromHandle(handle);
- }
-
- //[DebuggerBrowsable(DebuggerBrowsableState.Never)]
- public event AbstractState<T>.ValueChangedHandler ValueChangedEvent;
-
- //[DebuggerBrowsable(DebuggerBrowsableState.Never)]
- public event AbstractState<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();
- }
- }
-
- protected 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;
- }
- }
-
- protected override void Awake()
- {
- base.Awake();
- this.storage = Storage.Get(this.GetLifecycle());
- this.loadState();
- }
-
- protected virtual void Start()
- {
- }
-
- protected override void OnDestroy()
- {
- base.OnDestroy();
- this.ValueChangedEvent = null;
- if (this.storage != null)
- {
- this.storage.OnSync -= this.syncToStorage;
- }
- }
-
- public virtual V GetValue<V>(string key, V defaultvalue)
- {
- V result = defaultvalue;
- object obj;
- if (this.Persistent.TryGetValue(key, out obj) && obj is V)
- {
- result = (V)((object)obj);
- }
- return result;
- }
-
- 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);
- }
- }
- }
-
- 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;
- }
- }
-
- 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 = AbstractState<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 = AbstractState<T>.GetFieldFromHandle(handle);
- if (fieldsDictionary.ContainsKey(fieldFromHandle.Name))
- {
- fieldFromHandle.SetValue(this, fieldsDictionary[fieldFromHandle.Name]);
- }
- }
- }
- }
-
- protected abstract void OnNewGameState();
-
- protected abstract string GetStorageKey();
-
- protected abstract StorageLifecycle GetLifecycle();
-
- 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();
- }
- }
|