diff --git a/Assets/TEngine/Runtime/GameFramework/DataStruct/SerializableDictionary.cs b/Assets/TEngine/Runtime/GameFramework/DataStruct/SerializableDictionary.cs new file mode 100644 index 00000000..8d998057 --- /dev/null +++ b/Assets/TEngine/Runtime/GameFramework/DataStruct/SerializableDictionary.cs @@ -0,0 +1,259 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Runtime.Serialization; +using UnityEngine; + +public abstract class SerializableDictionaryBase +{ + public abstract class Storage {} + + protected class Dictionary : System.Collections.Generic.Dictionary + { + public Dictionary() {} + public Dictionary(IDictionary dict) : base(dict) {} + public Dictionary(SerializationInfo info, StreamingContext context) : base(info, context) {} + } +} + +[Serializable] +public abstract class SerializableDictionaryBase : SerializableDictionaryBase, IDictionary, IDictionary, ISerializationCallbackReceiver, IDeserializationCallback, ISerializable +{ + Dictionary m_dict; + [SerializeField] + TKey[] m_keys; + [SerializeField] + TValueStorage[] m_values; + + public SerializableDictionaryBase() + { + m_dict = new Dictionary(); + } + + public SerializableDictionaryBase(IDictionary dict) + { + m_dict = new Dictionary(dict); + } + + protected abstract void SetValue(TValueStorage[] storage, int i, TValue value); + protected abstract TValue GetValue(TValueStorage[] storage, int i); + + public void CopyFrom(IDictionary dict) + { + m_dict.Clear(); + foreach (var kvp in dict) + { + m_dict[kvp.Key] = kvp.Value; + } + } + + public void OnAfterDeserialize() + { + if(m_keys != null && m_values != null && m_keys.Length == m_values.Length) + { + m_dict.Clear(); + int n = m_keys.Length; + for(int i = 0; i < n; ++i) + { + m_dict[m_keys[i]] = GetValue(m_values, i); + } + + m_keys = null; + m_values = null; + } + } + + public void OnBeforeSerialize() + { + int n = m_dict.Count; + m_keys = new TKey[n]; + m_values = new TValueStorage[n]; + + int i = 0; + foreach(var kvp in m_dict) + { + m_keys[i] = kvp.Key; + SetValue(m_values, i, kvp.Value); + ++i; + } + } + + #region IDictionary + + public ICollection Keys { get { return ((IDictionary)m_dict).Keys; } } + public ICollection Values { get { return ((IDictionary)m_dict).Values; } } + public int Count { get { return ((IDictionary)m_dict).Count; } } + public bool IsReadOnly { get { return ((IDictionary)m_dict).IsReadOnly; } } + + public TValue this[TKey key] + { + get { return ((IDictionary)m_dict)[key]; } + set { ((IDictionary)m_dict)[key] = value; } + } + + public void Add(TKey key, TValue value) + { + ((IDictionary)m_dict).Add(key, value); + } + + public bool ContainsKey(TKey key) + { + return ((IDictionary)m_dict).ContainsKey(key); + } + + public bool Remove(TKey key) + { + return ((IDictionary)m_dict).Remove(key); + } + + public bool TryGetValue(TKey key, out TValue value) + { + return ((IDictionary)m_dict).TryGetValue(key, out value); + } + + public void Add(KeyValuePair item) + { + ((IDictionary)m_dict).Add(item); + } + + public void Clear() + { + ((IDictionary)m_dict).Clear(); + } + + public bool Contains(KeyValuePair item) + { + return ((IDictionary)m_dict).Contains(item); + } + + public void CopyTo(KeyValuePair[] array, int arrayIndex) + { + ((IDictionary)m_dict).CopyTo(array, arrayIndex); + } + + public bool Remove(KeyValuePair item) + { + return ((IDictionary)m_dict).Remove(item); + } + + public IEnumerator> GetEnumerator() + { + return ((IDictionary)m_dict).GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return ((IDictionary)m_dict).GetEnumerator(); + } + + #endregion + + #region IDictionary + + public bool IsFixedSize { get { return ((IDictionary)m_dict).IsFixedSize; } } + ICollection IDictionary.Keys { get { return ((IDictionary)m_dict).Keys; } } + ICollection IDictionary.Values { get { return ((IDictionary)m_dict).Values; } } + public bool IsSynchronized { get { return ((IDictionary)m_dict).IsSynchronized; } } + public object SyncRoot { get { return ((IDictionary)m_dict).SyncRoot; } } + + public object this[object key] + { + get { return ((IDictionary)m_dict)[key]; } + set { ((IDictionary)m_dict)[key] = value; } + } + + public void Add(object key, object value) + { + ((IDictionary)m_dict).Add(key, value); + } + + public bool Contains(object key) + { + return ((IDictionary)m_dict).Contains(key); + } + + IDictionaryEnumerator IDictionary.GetEnumerator() + { + return ((IDictionary)m_dict).GetEnumerator(); + } + + public void Remove(object key) + { + ((IDictionary)m_dict).Remove(key); + } + + public void CopyTo(Array array, int index) + { + ((IDictionary)m_dict).CopyTo(array, index); + } + + #endregion + + #region IDeserializationCallback + + public void OnDeserialization(object sender) + { + ((IDeserializationCallback)m_dict).OnDeserialization(sender); + } + + #endregion + + #region ISerializable + + protected SerializableDictionaryBase(SerializationInfo info, StreamingContext context) + { + m_dict = new Dictionary(info, context); + } + + public void GetObjectData(SerializationInfo info, StreamingContext context) + { + ((ISerializable)m_dict).GetObjectData(info, context); + } + + #endregion +} + +public static class SerializableDictionary +{ + public class Storage : SerializableDictionaryBase.Storage + { + public T data; + } +} + +[Serializable] +public class SerializableDictionary : SerializableDictionaryBase +{ + public SerializableDictionary() {} + public SerializableDictionary(IDictionary dict) : base(dict) {} + protected SerializableDictionary(SerializationInfo info, StreamingContext context) : base(info, context) {} + + protected override TValue GetValue(TValue[] storage, int i) + { + return storage[i]; + } + + protected override void SetValue(TValue[] storage, int i, TValue value) + { + storage[i] = value; + } +} + +[Serializable] +public class SerializableDictionary : SerializableDictionaryBase where TValueStorage : SerializableDictionary.Storage, new() +{ + public SerializableDictionary() {} + public SerializableDictionary(IDictionary dict) : base(dict) {} + protected SerializableDictionary(SerializationInfo info, StreamingContext context) : base(info, context) {} + + protected override TValue GetValue(TValueStorage[] storage, int i) + { + return storage[i].data; + } + + protected override void SetValue(TValueStorage[] storage, int i, TValue value) + { + storage[i] = new TValueStorage(); + storage[i].data = value; + } +} diff --git a/Assets/TEngine/Runtime/GameFramework/DataStruct/SerializableDictionary.cs.meta b/Assets/TEngine/Runtime/GameFramework/DataStruct/SerializableDictionary.cs.meta new file mode 100644 index 00000000..93209a3d --- /dev/null +++ b/Assets/TEngine/Runtime/GameFramework/DataStruct/SerializableDictionary.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: e7f040e158e24f699e3c71d1b522dc55 +timeCreated: 1683820865 \ No newline at end of file