From 68579941c5a57823a88e92aac3a736f16e9c8151 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 18 Mar 2016 00:30:31 -0700 Subject: [PATCH] files for first release --- .gitignore | 130 ++ Assets/Samples.meta | 9 + Assets/SerializableCollections.meta | 9 + .../SerializableDictionary.cs | 1398 +++++++++++++++++ .../SerializableDictionary.cs.meta | 12 + .../SerializableDictionaryPropertyDrawer.cs | 50 + ...rializableDictionaryPropertyDrawer.cs.meta | 12 + .../SerializableLookup.cs | 472 ++++++ .../SerializableLookup.cs.meta | 12 + .../SerializableLookupPropertyDrawer.cs | 60 + .../SerializableLookupPropertyDrawer.cs.meta | 12 + .../SerializableTuple.cs | 178 +++ .../SerializableTuple.cs.meta | 12 + ProjectSettings/AudioManager.asset | Bin 0 -> 4140 bytes ProjectSettings/ClusterInputManager.asset | Bin 0 -> 4104 bytes ProjectSettings/DynamicsManager.asset | Bin 0 -> 4276 bytes ProjectSettings/EditorBuildSettings.asset | Bin 0 -> 4104 bytes ProjectSettings/EditorSettings.asset | Bin 0 -> 4212 bytes ProjectSettings/GraphicsSettings.asset | Bin 0 -> 4332 bytes ProjectSettings/InputManager.asset | Bin 0 -> 5520 bytes ProjectSettings/NavMeshAreas.asset | Bin 0 -> 4384 bytes ProjectSettings/NetworkManager.asset | Bin 0 -> 4112 bytes ProjectSettings/Physics2DSettings.asset | Bin 0 -> 4364 bytes ProjectSettings/ProjectSettings.asset | Bin 0 -> 35953 bytes ProjectSettings/ProjectVersion.txt | 2 + ProjectSettings/QualitySettings.asset | Bin 0 -> 5004 bytes ProjectSettings/TagManager.asset | Bin 0 -> 4308 bytes ProjectSettings/TimeManager.asset | Bin 0 -> 4112 bytes ProjectSettings/UnityAdsSettings.asset | Bin 0 -> 4116 bytes ProjectSettings/UnityConnectSettings.asset | Bin 0 -> 4116 bytes SerializableDictionary.CSharp.csproj | 79 + SerializableDictionary.sln | 20 + 32 files changed, 2467 insertions(+) create mode 100644 .gitignore create mode 100644 Assets/Samples.meta create mode 100644 Assets/SerializableCollections.meta create mode 100644 Assets/SerializableCollections/SerializableDictionary.cs create mode 100644 Assets/SerializableCollections/SerializableDictionary.cs.meta create mode 100644 Assets/SerializableCollections/SerializableDictionaryPropertyDrawer.cs create mode 100644 Assets/SerializableCollections/SerializableDictionaryPropertyDrawer.cs.meta create mode 100644 Assets/SerializableCollections/SerializableLookup.cs create mode 100644 Assets/SerializableCollections/SerializableLookup.cs.meta create mode 100644 Assets/SerializableCollections/SerializableLookupPropertyDrawer.cs create mode 100644 Assets/SerializableCollections/SerializableLookupPropertyDrawer.cs.meta create mode 100644 Assets/SerializableCollections/SerializableTuple.cs create mode 100644 Assets/SerializableCollections/SerializableTuple.cs.meta create mode 100644 ProjectSettings/AudioManager.asset create mode 100644 ProjectSettings/ClusterInputManager.asset create mode 100644 ProjectSettings/DynamicsManager.asset create mode 100644 ProjectSettings/EditorBuildSettings.asset create mode 100644 ProjectSettings/EditorSettings.asset create mode 100644 ProjectSettings/GraphicsSettings.asset create mode 100644 ProjectSettings/InputManager.asset create mode 100644 ProjectSettings/NavMeshAreas.asset create mode 100644 ProjectSettings/NetworkManager.asset create mode 100644 ProjectSettings/Physics2DSettings.asset create mode 100644 ProjectSettings/ProjectSettings.asset create mode 100644 ProjectSettings/ProjectVersion.txt create mode 100644 ProjectSettings/QualitySettings.asset create mode 100644 ProjectSettings/TagManager.asset create mode 100644 ProjectSettings/TimeManager.asset create mode 100644 ProjectSettings/UnityAdsSettings.asset create mode 100644 ProjectSettings/UnityConnectSettings.asset create mode 100644 SerializableDictionary.CSharp.csproj create mode 100644 SerializableDictionary.sln diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..017e657 --- /dev/null +++ b/.gitignore @@ -0,0 +1,130 @@ +# Unity + +*.pidb +*.suo +*.userprefs +*.vsmdi +*.testsettings +*/bin +*/obj +*/publish +$tf +TestResults +!*.sln +!*.csproj +!*/*.csproj +[Ll]ibrary/ +[Tt]emp/ +[Oo]bj/ + +# VS2013 + +# Build Folders (you can keep bin if you'd like, to store dlls and pdbs) +[Bb]in/ +[Oo]bj/ + +# mstest test results +TestResults + +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# User-specific files +*.suo +*.user +*.sln.docstates + +# Build results +[Dd]ebug/ +[Rr]elease/ +x64/ +*_i.c +*_p.c +*.ilk +# *.meta # already ignored in Unity section +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.log +*.vspscc +*.vssscc +.builds + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opensdf +*.sdf + +# Visual Studio profiler +*.psess +*.vsp +*.vspx + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper* + +# NCrunch +*.ncrunch* +.*crunch*.local.xml + +# Installshield output folder +[Ee]xpress + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish + +# Publish Web Output +*.Publish.xml + +# NuGet Packages Directory +packages + +# Windows Azure Build Output +csx +*.build.csdef + +# Windows Store app package directory +AppPackages/ + +# Others +[Bb]in +[Oo]bj +sql +TestResults +[Tt]est[Rr]esult* +*.Cache +ClientBin +[Ss]tyle[Cc]op.* +~$* +*.dbmdl +Generated_Code #added for RIA/Silverlight projects + +# Backup & report files from converting an old project file to a newer +# Visual Studio version. Backup files are not needed, because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +Assets/WSATestCertificate.pfx \ No newline at end of file diff --git a/Assets/Samples.meta b/Assets/Samples.meta new file mode 100644 index 0000000..38bd6ef --- /dev/null +++ b/Assets/Samples.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 9d40e76a5f14aa14690a64eb43983652 +folderAsset: yes +timeCreated: 1458285883 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SerializableCollections.meta b/Assets/SerializableCollections.meta new file mode 100644 index 0000000..0dee7f1 --- /dev/null +++ b/Assets/SerializableCollections.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 0b3127608279770449a6324335c31c8a +folderAsset: yes +timeCreated: 1458285878 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SerializableCollections/SerializableDictionary.cs b/Assets/SerializableCollections/SerializableDictionary.cs new file mode 100644 index 0000000..4ee31f8 --- /dev/null +++ b/Assets/SerializableCollections/SerializableDictionary.cs @@ -0,0 +1,1398 @@ +using System; +using System.Collections.Generic; +using System.Collections; +using System.Diagnostics; +using UnityEngine; + +namespace SerializableCollections +{ + [Serializable] + public class SerializableDictionary : IDictionary, IDictionary + { + // can't serialize internal generic struct. + // extract to 4 arrays. + + //struct Entry + //{ + // public int hashCode; + // public int next; + // public TKey key; + // public TValue value; + //} + + // serializable state. + [SerializeField, HideInInspector] + int[] buckets; // link index of first entry. empty is -1. + [SerializeField, HideInInspector] + int count; + + // Entry[] entries; + [SerializeField, HideInInspector] + int[] entriesHashCode; + [SerializeField, HideInInspector] + int[] entriesNext; + [SerializeField, HideInInspector] + TKey[] entriesKey; + [SerializeField, HideInInspector] + TValue[] entriesValue; + + // when remove, mark slot to free + [SerializeField, HideInInspector] + int freeCount; + [SerializeField, HideInInspector] + int freeList; + + int version; // version does not serialize + + KeyCollection keys; + ValueCollection values; + object _syncRoot; + + // equality comparer is not serializable, use specified comparer. + public virtual IEqualityComparer Comparer + { + get + { + return EqualityComparer.Default; + } + } + + protected SerializableDictionary() + { + Initialize(0); + } + + protected SerializableDictionary(int initialCapacity) + { + Initialize(initialCapacity); + } + + SerializableDictionary(int staticCapacity, bool forceSize) + { + Initialize(staticCapacity, forceSize); + } + + public int Count + { + get { return count - freeCount; } + } + + public KeyCollection Keys + { + get + { + if (keys == null) keys = new KeyCollection(this); + return keys; + } + } + + ICollection IDictionary.Keys + { + get + { + if (keys == null) keys = new KeyCollection(this); + return keys; + } + } + + public ValueCollection Values + { + get + { + if (values == null) values = new ValueCollection(this); + return values; + } + } + + ICollection IDictionary.Values + { + get + { + if (values == null) values = new ValueCollection(this); + return values; + } + } + + public TValue this[TKey key] + { + get + { + int i = FindEntry(key); + if (i >= 0) return entriesValue[i]; + throw new KeyNotFoundException(); + } + set + { + Insert(key, value, false); + } + } + + public void Add(TKey key, TValue value) + { + Insert(key, value, true); + } + + void ICollection>.Add(KeyValuePair keyValuePair) + { + Add(keyValuePair.Key, keyValuePair.Value); + } + + bool ICollection>.Contains(KeyValuePair keyValuePair) + { + int i = FindEntry(keyValuePair.Key); + if (i >= 0 && EqualityComparer.Default.Equals(entriesValue[i], keyValuePair.Value)) + { + return true; + } + return false; + } + + bool ICollection>.Remove(KeyValuePair keyValuePair) + { + int i = FindEntry(keyValuePair.Key); + if (i >= 0 && EqualityComparer.Default.Equals(entriesValue[i], keyValuePair.Value)) + { + Remove(keyValuePair.Key); + return true; + } + return false; + } + + public void Clear() + { + if (count > 0) + { + for (int i = 0; i < buckets.Length; i++) buckets[i] = -1; + Array.Clear(entriesHashCode, 0, count); + Array.Clear(entriesKey, 0, count); + Array.Clear(entriesNext, 0, count); + Array.Clear(entriesValue, 0, count); + + freeList = -1; + count = 0; + freeCount = 0; + version++; + } + } + + public bool ContainsKey(TKey key) + { + return FindEntry(key) >= 0; + } + + public bool ContainsValue(TValue value) + { + if (value == null) + { + for (int i = 0; i < count; i++) + { + if (entriesHashCode[i] >= 0 && entriesValue[i] == null) return true; + } + } + else + { + EqualityComparer c = EqualityComparer.Default; + for (int i = 0; i < count; i++) + { + if (entriesHashCode[i] >= 0 && c.Equals(entriesValue[i], value)) return true; + } + } + return false; + } + + private void CopyTo(KeyValuePair[] array, int index) + { + if (array == null) + { + throw new ArgumentNullException("array"); + } + + if (index < 0 || index > array.Length) + { + throw new ArgumentOutOfRangeException("index", index, SR.ArgumentOutOfRange_Index); + } + + if (array.Length - index < Count) + { + throw new ArgumentException(SR.Arg_ArrayPlusOffTooSmall); + } + + int count = this.count; + for (int i = 0; i < count; i++) + { + if (entriesHashCode[i] >= 0) + { + array[index++] = new KeyValuePair(entriesKey[i], entriesValue[i]); + } + } + } + + public Enumerator GetEnumerator() + { + return new Enumerator(this, Enumerator.KeyValuePair); + } + + IEnumerator> IEnumerable>.GetEnumerator() + { + return new Enumerator(this, Enumerator.KeyValuePair); + } + + int FindEntry(TKey key) + { + if (key == null) throw new ArgumentNullException("key"); + + if (buckets != null) + { + int hashCode = Comparer.GetHashCode(key) & 0x7FFFFFFF; + for (int i = buckets[hashCode % buckets.Length]; i >= 0; i = entriesNext[i]) + { + if (entriesHashCode[i] == hashCode && Comparer.Equals(entriesKey[i], key)) return i; + } + } + + return -1; + } + + void Initialize(int capacity) + { + Initialize(capacity, false); + } + + void Initialize(int capacity, bool forceSize) + { + int size = forceSize ? capacity : HashHelpers.GetPrime(capacity); + buckets = new int[size]; + for (int i = 0; i < buckets.Length; i++) buckets[i] = -1; + entriesHashCode = new int[size]; + entriesKey = new TKey[size]; + entriesNext = new int[size]; + entriesValue = new TValue[size]; + + freeList = -1; + } + + void Insert(TKey key, TValue value, bool add) + { + if (key == null) throw new ArgumentNullException("key"); + if (buckets == null || buckets.Length == 0) Initialize(0); + + int hashCode = Comparer.GetHashCode(key) & 0x7FFFFFFF; + int targetBucket = hashCode % buckets.Length; + + for (int i = buckets[targetBucket]; i >= 0; i = entriesNext[i]) + { + if (entriesHashCode[i] == hashCode && Comparer.Equals(entriesKey[i], key)) + { + if (add) + { + throw new ArgumentException(SR.Format(SR.Argument_AddingDuplicate, key)); + } + entriesValue[i] = value; + version++; + return; + } + } + + int index; + + if (freeCount > 0) + { + index = freeList; + freeList = entriesNext[index]; + freeCount--; + } + else + { + if (count == entriesHashCode.Length) + { + Resize(); + targetBucket = hashCode % buckets.Length; + } + index = count; + count++; + } + + entriesHashCode[index] = hashCode; + entriesNext[index] = buckets[targetBucket]; + entriesKey[index] = key; + entriesValue[index] = value; + buckets[targetBucket] = index; + version++; + } + + void Resize() + { + Resize(HashHelpers.ExpandPrime(count), false); + } + + void Resize(int newSize, bool forceNewHashCodes) + { + int[] newBuckets = new int[newSize]; + for (int i = 0; i < newBuckets.Length; i++) newBuckets[i] = -1; + + var newEntriesKey = new TKey[newSize]; + var newEntriesValue = new TValue[newSize]; + var newEntriesHashCode = new int[newSize]; + var newEntriesNext = new int[newSize]; + Array.Copy(entriesKey, 0, newEntriesKey, 0, count); + Array.Copy(entriesValue, 0, newEntriesValue, 0, count); + Array.Copy(entriesHashCode, 0, newEntriesHashCode, 0, count); + Array.Copy(entriesNext, 0, newEntriesNext, 0, count); + + if (forceNewHashCodes) + { + for (int i = 0; i < count; i++) + { + if (newEntriesHashCode[i] != -1) + { + newEntriesHashCode[i] = (Comparer.GetHashCode(newEntriesKey[i]) & 0x7FFFFFFF); + } + } + } + + for (int i = 0; i < count; i++) + { + if (newEntriesHashCode[i] >= 0) + { + int bucket = newEntriesHashCode[i] % newSize; + newEntriesNext[i] = newBuckets[bucket]; + newBuckets[bucket] = i; + } + } + + buckets = newBuckets; + + entriesKey = newEntriesKey; + entriesValue = newEntriesValue; + entriesHashCode = newEntriesHashCode; + entriesNext = newEntriesNext; + } + + + public bool Remove(TKey key) + { + if (key == null) throw new ArgumentNullException("key"); + + if (buckets != null) + { + int hashCode = Comparer.GetHashCode(key) & 0x7FFFFFFF; + int bucket = hashCode % buckets.Length; + int last = -1; + for (int i = buckets[bucket]; i >= 0; last = i, i = entriesNext[i]) + { + if (entriesHashCode[i] == hashCode && Comparer.Equals(entriesKey[i], key)) + { + if (last < 0) + { + buckets[bucket] = entriesNext[i]; + } + else + { + entriesNext[last] = entriesNext[i]; + } + entriesHashCode[i] = -1; + entriesNext[i] = freeList; + entriesKey[i] = default(TKey); + entriesValue[i] = default(TValue); + freeList = i; + freeCount++; + version++; + return true; + } + } + } + return false; + } + + public bool TryGetValue(TKey key, out TValue value) + { + int i = FindEntry(key); + if (i >= 0) + { + value = entriesValue[i]; + return true; + } + value = default(TValue); + return false; + } + + bool ICollection>.IsReadOnly + { + get { return false; } + } + + void ICollection>.CopyTo(KeyValuePair[] array, int index) + { + CopyTo(array, index); + } + + void ICollection.CopyTo(Array array, int index) + { + if (array == null) + { + throw new ArgumentNullException("array"); + } + + if (array.Rank != 1) + { + throw new ArgumentException(SR.Arg_RankMultiDimNotSupported, "array"); + } + + if (array.GetLowerBound(0) != 0) + { + throw new ArgumentException(SR.Arg_NonZeroLowerBound, "array"); + } + + if (index < 0 || index > array.Length) + { + throw new ArgumentOutOfRangeException("index", index, SR.ArgumentOutOfRange_Index); + } + + if (array.Length - index < Count) + { + throw new ArgumentException(SR.Arg_ArrayPlusOffTooSmall); + } + + KeyValuePair[] pairs = array as KeyValuePair[]; + if (pairs != null) + { + CopyTo(pairs, index); + } + else if (array is DictionaryEntry[]) + { + DictionaryEntry[] dictEntryArray = array as DictionaryEntry[]; + for (int i = 0; i < count; i++) + { + if (entriesHashCode[i] >= 0) + { + dictEntryArray[index++] = new DictionaryEntry(entriesKey[i], entriesValue[i]); + } + } + } + else + { + object[] objects = array as object[]; + if (objects == null) + { + throw new ArgumentException(SR.Argument_InvalidArrayType, "array"); + } + + try + { + int count = this.count; + for (int i = 0; i < count; i++) + { + if (entriesHashCode[i] >= 0) + { + objects[index++] = new KeyValuePair(entriesKey[i], entriesValue[i]); + } + } + } + catch (ArrayTypeMismatchException) + { + throw new ArgumentException(SR.Argument_InvalidArrayType, "array"); + } + } + } + + IEnumerator IEnumerable.GetEnumerator() + { + return new Enumerator(this, Enumerator.KeyValuePair); + } + + bool ICollection.IsSynchronized + { + get { return false; } + } + + object ICollection.SyncRoot + { + get + { + if (_syncRoot == null) + { + System.Threading.Interlocked.CompareExchange(ref _syncRoot, new object(), null); + } + return _syncRoot; + } + } + + bool IDictionary.IsFixedSize + { + get { return false; } + } + + bool IDictionary.IsReadOnly + { + get { return false; } + } + + ICollection IDictionary.Keys + { + get { return (ICollection)Keys; } + } + + ICollection IDictionary.Values + { + get { return (ICollection)Values; } + } + + object IDictionary.this[object key] + { + get + { + if (IsCompatibleKey(key)) + { + int i = FindEntry((TKey)key); + if (i >= 0) + { + return entriesValue[i]; + } + } + return null; + } + set + { + if (key == null) + { + throw new ArgumentNullException("key"); + } + if (value == null && !(default(TValue) == null)) + throw new ArgumentNullException("value"); + + try + { + TKey tempKey = (TKey)key; + try + { + this[tempKey] = (TValue)value; + } + catch (InvalidCastException) + { + throw new ArgumentException(SR.Format(SR.Arg_WrongType, value, typeof(TValue)), "value"); + } + } + catch (InvalidCastException) + { + throw new ArgumentException(SR.Format(SR.Arg_WrongType, key, typeof(TKey)), "key"); + } + } + } + + private static bool IsCompatibleKey(object key) + { + if (key == null) + { + throw new ArgumentNullException("key"); + } + return (key is TKey); + } + + void IDictionary.Add(object key, object value) + { + if (key == null) + { + throw new ArgumentNullException("key"); + } + + if (value == null && !(default(TValue) == null)) + throw new ArgumentNullException("value"); + + try + { + TKey tempKey = (TKey)key; + + try + { + Add(tempKey, (TValue)value); + } + catch (InvalidCastException) + { + throw new ArgumentException(SR.Format(SR.Arg_WrongType, value, typeof(TValue)), "value"); + } + } + catch (InvalidCastException) + { + throw new ArgumentException(SR.Format(SR.Arg_WrongType, key, typeof(TKey)), "key"); + } + } + + bool IDictionary.Contains(object key) + { + if (IsCompatibleKey(key)) + { + return ContainsKey((TKey)key); + } + + return false; + } + + IDictionaryEnumerator IDictionary.GetEnumerator() + { + return new Enumerator(this, Enumerator.DictEntry); + } + + void IDictionary.Remove(object key) + { + if (IsCompatibleKey(key)) + { + Remove((TKey)key); + } + } + + public void TrimExcess() + { + var newDict = new SerializableDictionary(Count, true); + + // fast copy + for (int i = 0; i < count; i++) + { + if (entriesHashCode[i] >= 0) + { + newDict.Add(entriesKey[i], entriesValue[i]); + } + } + + // copy internal field to this + this.buckets = newDict.buckets; + this.count = newDict.count; + this.entriesHashCode = newDict.entriesHashCode; + this.entriesKey = newDict.entriesKey; + this.entriesNext = newDict.entriesNext; + this.entriesValue = newDict.entriesValue; + this.freeCount = newDict.freeCount; + this.freeList = newDict.freeList; + } + + public struct Enumerator : IEnumerator>, + IDictionaryEnumerator + { + private SerializableDictionary dictionary; + private int version; + private int index; + private KeyValuePair current; + private int getEnumeratorRetType; // What should Enumerator.Current return? + + internal const int DictEntry = 1; + internal const int KeyValuePair = 2; + + internal Enumerator(SerializableDictionary dictionary, int getEnumeratorRetType) + { + this.dictionary = dictionary; + version = dictionary.version; + index = 0; + this.getEnumeratorRetType = getEnumeratorRetType; + current = new KeyValuePair(); + } + + public bool MoveNext() + { + if (version != dictionary.version) + { + throw new InvalidOperationException(SR.InvalidOperation_EnumFailedVersion); + } + + // Use unsigned comparison since we set index to dictionary.count+1 when the enumeration ends. + // dictionary.count+1 could be negative if dictionary.count is Int32.MaxValue + while ((uint)index < (uint)dictionary.count) + { + if (dictionary.entriesHashCode[index] >= 0) + { + current = new KeyValuePair(dictionary.entriesKey[index], dictionary.entriesValue[index]); + index++; + return true; + } + index++; + } + + index = dictionary.count + 1; + current = new KeyValuePair(); + return false; + } + + public KeyValuePair Current + { + get { return current; } + } + + public void Dispose() + { + } + + object IEnumerator.Current + { + get + { + if (index == 0 || (index == dictionary.count + 1)) + { + throw new InvalidOperationException(SR.InvalidOperation_EnumOpCantHappen); + } + + if (getEnumeratorRetType == DictEntry) + { + return new System.Collections.DictionaryEntry(current.Key, current.Value); + } + else + { + return new KeyValuePair(current.Key, current.Value); + } + } + } + + void IEnumerator.Reset() + { + if (version != dictionary.version) + { + throw new InvalidOperationException(SR.InvalidOperation_EnumFailedVersion); + } + + index = 0; + current = new KeyValuePair(); + } + + DictionaryEntry IDictionaryEnumerator.Entry + { + get + { + if (index == 0 || (index == dictionary.count + 1)) + { + throw new InvalidOperationException(SR.InvalidOperation_EnumOpCantHappen); + } + + return new DictionaryEntry(current.Key, current.Value); + } + } + + object IDictionaryEnumerator.Key + { + get + { + if (index == 0 || (index == dictionary.count + 1)) + { + throw new InvalidOperationException(SR.InvalidOperation_EnumOpCantHappen); + } + + return current.Key; + } + } + + object IDictionaryEnumerator.Value + { + get + { + if (index == 0 || (index == dictionary.count + 1)) + { + throw new InvalidOperationException(SR.InvalidOperation_EnumOpCantHappen); + } + + return current.Value; + } + } + } + + [DebuggerTypeProxy(typeof(DictionaryKeyCollectionDebugView<,>))] + [DebuggerDisplay("Count = {Count}")] + public sealed class KeyCollection : ICollection, ICollection + { + private SerializableDictionary dictionary; + + public KeyCollection(SerializableDictionary dictionary) + { + if (dictionary == null) + { + throw new ArgumentNullException("dictionary"); + } + this.dictionary = dictionary; + } + + public Enumerator GetEnumerator() + { + return new Enumerator(dictionary); + } + + public void CopyTo(TKey[] array, int index) + { + if (array == null) + { + throw new ArgumentNullException("array"); + } + + if (index < 0 || index > array.Length) + { + throw new ArgumentOutOfRangeException("index", index, SR.ArgumentOutOfRange_Index); + } + + if (array.Length - index < dictionary.Count) + { + throw new ArgumentException(SR.Arg_ArrayPlusOffTooSmall); + } + + int count = dictionary.count; + + for (int i = 0; i < count; i++) + { + if (dictionary.entriesHashCode[i] >= 0) array[index++] = dictionary.entriesKey[i]; + } + } + + public int Count + { + get { return dictionary.Count; } + } + + bool ICollection.IsReadOnly + { + get { return true; } + } + + void ICollection.Add(TKey item) + { + throw new NotSupportedException(SR.NotSupported_KeyCollectionSet); + } + + void ICollection.Clear() + { + throw new NotSupportedException(SR.NotSupported_KeyCollectionSet); + } + + bool ICollection.Contains(TKey item) + { + return dictionary.ContainsKey(item); + } + + bool ICollection.Remove(TKey item) + { + throw new NotSupportedException(SR.NotSupported_KeyCollectionSet); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return new Enumerator(dictionary); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return new Enumerator(dictionary); + } + + void ICollection.CopyTo(Array array, int index) + { + if (array == null) + { + throw new ArgumentNullException("array"); + } + + if (array.Rank != 1) + { + throw new ArgumentException(SR.Arg_RankMultiDimNotSupported, "array"); + } + + if (array.GetLowerBound(0) != 0) + { + throw new ArgumentException(SR.Arg_NonZeroLowerBound, "array"); + } + + if (index < 0 || index > array.Length) + { + throw new ArgumentOutOfRangeException("index", index, SR.ArgumentOutOfRange_Index); + } + + if (array.Length - index < dictionary.Count) + { + throw new ArgumentException(SR.Arg_ArrayPlusOffTooSmall); + } + + TKey[] keys = array as TKey[]; + if (keys != null) + { + CopyTo(keys, index); + } + else + { + object[] objects = array as object[]; + if (objects == null) + { + throw new ArgumentException(SR.Argument_InvalidArrayType, "array"); + } + + int count = dictionary.count; + try + { + for (int i = 0; i < count; i++) + { + if (dictionary.entriesHashCode[i] >= 0) objects[index++] = (object)dictionary.entriesKey[i]; + } + } + catch (ArrayTypeMismatchException) + { + throw new ArgumentException(SR.Argument_InvalidArrayType, "array"); + } + } + } + + bool ICollection.IsSynchronized + { + get { return false; } + } + + object ICollection.SyncRoot + { + get { return ((ICollection)dictionary).SyncRoot; } + } + + public struct Enumerator : IEnumerator, System.Collections.IEnumerator + { + private SerializableDictionary dictionary; + private int index; + private int version; + private TKey currentKey; + + internal Enumerator(SerializableDictionary dictionary) + { + this.dictionary = dictionary; + version = dictionary.version; + index = 0; + currentKey = default(TKey); + } + + public void Dispose() + { + } + + public bool MoveNext() + { + if (version != dictionary.version) + { + throw new InvalidOperationException(SR.InvalidOperation_EnumFailedVersion); + } + + while ((uint)index < (uint)dictionary.count) + { + if (dictionary.entriesHashCode[index] >= 0) + { + currentKey = dictionary.entriesKey[index]; + index++; + return true; + } + index++; + } + + index = dictionary.count + 1; + currentKey = default(TKey); + return false; + } + + public TKey Current + { + get + { + return currentKey; + } + } + + object System.Collections.IEnumerator.Current + { + get + { + if (index == 0 || (index == dictionary.count + 1)) + { + throw new InvalidOperationException(SR.InvalidOperation_EnumOpCantHappen); + } + + return currentKey; + } + } + + void System.Collections.IEnumerator.Reset() + { + if (version != dictionary.version) + { + throw new InvalidOperationException(SR.InvalidOperation_EnumFailedVersion); + } + + index = 0; + currentKey = default(TKey); + } + } + } + + [DebuggerTypeProxy(typeof(DictionaryValueCollectionDebugView<,>))] + [DebuggerDisplay("Count = {Count}")] + public sealed class ValueCollection : ICollection, ICollection + { + private SerializableDictionary dictionary; + + public ValueCollection(SerializableDictionary dictionary) + { + if (dictionary == null) + { + throw new ArgumentNullException("dictionary"); + } + this.dictionary = dictionary; + } + + public Enumerator GetEnumerator() + { + return new Enumerator(dictionary); + } + + public void CopyTo(TValue[] array, int index) + { + if (array == null) + { + throw new ArgumentNullException("array"); + } + + if (index < 0 || index > array.Length) + { + throw new ArgumentOutOfRangeException("index", index, SR.ArgumentOutOfRange_Index); + } + + if (array.Length - index < dictionary.Count) + { + throw new ArgumentException(SR.Arg_ArrayPlusOffTooSmall); + } + + int count = dictionary.count; + + for (int i = 0; i < count; i++) + { + if (dictionary.entriesHashCode[i] >= 0) array[index++] = dictionary.entriesValue[i]; + } + } + + public int Count + { + get { return dictionary.Count; } + } + + bool ICollection.IsReadOnly + { + get { return true; } + } + + void ICollection.Add(TValue item) + { + throw new NotSupportedException(SR.NotSupported_ValueCollectionSet); + } + + bool ICollection.Remove(TValue item) + { + throw new NotSupportedException(SR.NotSupported_ValueCollectionSet); + } + + void ICollection.Clear() + { + throw new NotSupportedException(SR.NotSupported_ValueCollectionSet); + } + + bool ICollection.Contains(TValue item) + { + return dictionary.ContainsValue(item); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return new Enumerator(dictionary); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return new Enumerator(dictionary); + } + + void ICollection.CopyTo(Array array, int index) + { + if (array == null) + { + throw new ArgumentNullException("array"); + } + + if (array.Rank != 1) + { + throw new ArgumentException(SR.Arg_RankMultiDimNotSupported, "array"); + } + + if (array.GetLowerBound(0) != 0) + { + throw new ArgumentException(SR.Arg_NonZeroLowerBound, "array"); + } + + if (index < 0 || index > array.Length) + { + throw new ArgumentOutOfRangeException("index", index, SR.ArgumentOutOfRange_Index); + } + + if (array.Length - index < dictionary.Count) + throw new ArgumentException(SR.Arg_ArrayPlusOffTooSmall); + + TValue[] values = array as TValue[]; + if (values != null) + { + CopyTo(values, index); + } + else + { + object[] objects = array as object[]; + if (objects == null) + { + throw new ArgumentException(SR.Argument_InvalidArrayType, "array"); + } + + int count = dictionary.count; + try + { + for (int i = 0; i < count; i++) + { + if (dictionary.entriesHashCode[i] >= 0) objects[index++] = dictionary.entriesValue[i]; + } + } + catch (ArrayTypeMismatchException) + { + throw new ArgumentException(SR.Argument_InvalidArrayType, "array"); + } + } + } + + bool ICollection.IsSynchronized + { + get { return false; } + } + + object ICollection.SyncRoot + { + get { return ((ICollection)dictionary).SyncRoot; } + } + + public struct Enumerator : IEnumerator, System.Collections.IEnumerator + { + private SerializableDictionary dictionary; + private int index; + private int version; + private TValue currentValue; + + internal Enumerator(SerializableDictionary dictionary) + { + this.dictionary = dictionary; + version = dictionary.version; + index = 0; + currentValue = default(TValue); + } + + public void Dispose() + { + } + + public bool MoveNext() + { + if (version != dictionary.version) + { + throw new InvalidOperationException(SR.InvalidOperation_EnumFailedVersion); + } + + while ((uint)index < (uint)dictionary.count) + { + if (dictionary.entriesHashCode[index] >= 0) + { + currentValue = dictionary.entriesValue[index]; + index++; + return true; + } + index++; + } + index = dictionary.count + 1; + currentValue = default(TValue); + return false; + } + + public TValue Current + { + get + { + return currentValue; + } + } + + object System.Collections.IEnumerator.Current + { + get + { + if (index == 0 || (index == dictionary.count + 1)) + { + throw new InvalidOperationException(SR.InvalidOperation_EnumOpCantHappen); + } + + return currentValue; + } + } + + void System.Collections.IEnumerator.Reset() + { + if (version != dictionary.version) + { + throw new InvalidOperationException(SR.InvalidOperation_EnumFailedVersion); + } + index = 0; + currentValue = default(TValue); + } + } + } + + static class SR + { + public const string InvalidOperation_EnumFailedVersion = "InvalidOperation_EnumFailedVersion"; + public const string InvalidOperation_EnumOpCantHappen = "InvalidOperation_EnumOpCantHappen"; + public const string ArgumentOutOfRange_Index = "ArgumentOutOfRange_Index"; + public const string Argument_InvalidArrayType = "Argument_InvalidArrayType"; + public const string NotSupported_ValueCollectionSet = "NotSupported_ValueCollectionSet"; + public const string Arg_RankMultiDimNotSupported = "Arg_RankMultiDimNotSupported"; + public const string Arg_ArrayPlusOffTooSmall = "Arg_ArrayPlusOffTooSmall"; + public const string Arg_NonZeroLowerBound = "Arg_NonZeroLowerBound"; + public const string NotSupported_KeyCollectionSet = "NotSupported_KeyCollectionSet"; + public const string Arg_WrongType = "Arg_WrongType"; + public const string ArgumentOutOfRange_NeedNonNegNum = "ArgumentOutOfRange_NeedNonNegNum"; + public const string Arg_HTCapacityOverflow = "Arg_HTCapacityOverflow"; + public const string Argument_AddingDuplicate = "Argument_AddingDuplicate"; + + public static string Format(string f, params object[] args) + { + return string.Format(f, args); + } + } + + static class HashHelpers + { + // Table of prime numbers to use as hash table sizes. + // A typical resize algorithm would pick the smallest prime number in this array + // that is larger than twice the previous capacity. + // Suppose our Hashtable currently has capacity x and enough elements are added + // such that a resize needs to occur. Resizing first computes 2x then finds the + // first prime in the table greater than 2x, i.e. if primes are ordered + // p_1, p_2, ..., p_i, ..., it finds p_n such that p_n-1 < 2x < p_n. + // Doubling is important for preserving the asymptotic complexity of the + // hashtable operations such as add. Having a prime guarantees that double + // hashing does not lead to infinite loops. IE, your hash function will be + // h1(key) + i*h2(key), 0 <= i < size. h2 and the size must be relatively prime. + public static readonly int[] primes = { + 3, 7, 11, 17, 23, 29, 37, 47, 59, 71, 89, 107, 131, 163, 197, 239, 293, 353, 431, 521, 631, 761, 919, + 1103, 1327, 1597, 1931, 2333, 2801, 3371, 4049, 4861, 5839, 7013, 8419, 10103, 12143, 14591, + 17519, 21023, 25229, 30293, 36353, 43627, 52361, 62851, 75431, 90523, 108631, 130363, 156437, + 187751, 225307, 270371, 324449, 389357, 467237, 560689, 672827, 807403, 968897, 1162687, 1395263, + 1674319, 2009191, 2411033, 2893249, 3471899, 4166287, 4999559, 5999471, 7199369, 8639249, 10367101, + 12440537, 14928671, 17914409, 21497293, 25796759, 30956117, 37147349, 44576837, 53492207, 64190669, + 77028803, 92434613, 110921543, 133105859, 159727031, 191672443, 230006941, 276008387, 331210079, + 397452101, 476942527, 572331049, 686797261, 824156741, 988988137, 1186785773, 1424142949, 1708971541, + 2050765853, MaxPrimeArrayLength }; + + public static int GetPrime(int min) + { + if (min < 0) + throw new ArgumentException(SR.Arg_HTCapacityOverflow); + + for (int i = 0; i < primes.Length; i++) + { + int prime = primes[i]; + if (prime >= min) return prime; + } + + return min; + } + + public static int GetMinPrime() + { + return primes[0]; + } + + // Returns size of hashtable to grow to. + public static int ExpandPrime(int oldSize) + { + int newSize = 2 * oldSize; + + // Allow the hashtables to grow to maximum possible size (~2G elements) before encoutering capacity overflow. + // Note that this check works even when _items.Length overflowed thanks to the (uint) cast + if ((uint)newSize > MaxPrimeArrayLength && MaxPrimeArrayLength > oldSize) + { + return MaxPrimeArrayLength; + } + + return GetPrime(newSize); + } + + + // This is the maximum prime smaller than Array.MaxArrayLength + public const int MaxPrimeArrayLength = 0x7FEFFFFD; + } + } + + internal sealed class IDictionaryDebugView + { + private readonly IDictionary _dict; + + public IDictionaryDebugView(IDictionary dictionary) + { + if (dictionary == null) + throw new ArgumentNullException("dictionary"); + + _dict = dictionary; + } + + [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)] + public KeyValuePair[] Items + { + get + { + KeyValuePair[] items = new KeyValuePair[_dict.Count]; + _dict.CopyTo(items, 0); + return items; + } + } + } + + internal sealed class DictionaryKeyCollectionDebugView + { + private readonly ICollection _collection; + + public DictionaryKeyCollectionDebugView(ICollection collection) + { + if (collection == null) + throw new ArgumentNullException("collection"); + + _collection = collection; + } + + [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)] + public TKey[] Items + { + get + { + TKey[] items = new TKey[_collection.Count]; + _collection.CopyTo(items, 0); + return items; + } + } + } + + internal sealed class DictionaryValueCollectionDebugView + { + private readonly ICollection _collection; + + public DictionaryValueCollectionDebugView(ICollection collection) + { + if (collection == null) + throw new ArgumentNullException("collection"); + + _collection = collection; + } + + [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)] + public TValue[] Items + { + get + { + TValue[] items = new TValue[_collection.Count]; + _collection.CopyTo(items, 0); + return items; + } + } + } +} \ No newline at end of file diff --git a/Assets/SerializableCollections/SerializableDictionary.cs.meta b/Assets/SerializableCollections/SerializableDictionary.cs.meta new file mode 100644 index 0000000..5c3e94f --- /dev/null +++ b/Assets/SerializableCollections/SerializableDictionary.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 697d2c6e5395af74d9f65782cd352ef7 +timeCreated: 1458285944 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SerializableCollections/SerializableDictionaryPropertyDrawer.cs b/Assets/SerializableCollections/SerializableDictionaryPropertyDrawer.cs new file mode 100644 index 0000000..597429a --- /dev/null +++ b/Assets/SerializableCollections/SerializableDictionaryPropertyDrawer.cs @@ -0,0 +1,50 @@ +#if UNITY_EDITOR + +using System; +using System.Collections; +using System.Collections.Generic; +using UnityEditor; +using UnityEngine; +using UnityObject = UnityEngine.Object; + +namespace SerializableCollections +{ + public abstract class SerializableDictionaryPropertyDrawer : PropertyDrawer + { + bool foldout; + + public override float GetPropertyHeight(SerializedProperty property, GUIContent label) + { + var height = base.GetPropertyHeight(property, label); + + var target = property.serializedObject.targetObject; + var dictionary = fieldInfo.GetValue(target) as IDictionary; + if (dictionary == null) return height; + + return (foldout) + ? (dictionary.Count + 1) * 17f + : 17f; + } + + public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) + { + var target = property.serializedObject.targetObject; + var dictionary = fieldInfo.GetValue(target) as IDictionary; + if (dictionary == null) return; + + foldout = EditorGUI.Foldout(position, foldout, label, true); + EditorGUI.LabelField(position, label, new GUIContent() { text = "Count:" + dictionary.Count }); + if (foldout) + { + // only dump:) + foreach (DictionaryEntry item in dictionary) + { + position = new Rect(position.x, position.y + 17f, position.width, position.height); + EditorGUI.LabelField(position, item.Key.ToString(), (item.Value == null) ? "null" : item.Value.ToString()); + } + } + } + } +} + +#endif \ No newline at end of file diff --git a/Assets/SerializableCollections/SerializableDictionaryPropertyDrawer.cs.meta b/Assets/SerializableCollections/SerializableDictionaryPropertyDrawer.cs.meta new file mode 100644 index 0000000..4cc2a5c --- /dev/null +++ b/Assets/SerializableCollections/SerializableDictionaryPropertyDrawer.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 9c1f44a947e46ad44b6c7fd3036d2b43 +timeCreated: 1458285944 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SerializableCollections/SerializableLookup.cs b/Assets/SerializableCollections/SerializableLookup.cs new file mode 100644 index 0000000..2c840b3 --- /dev/null +++ b/Assets/SerializableCollections/SerializableLookup.cs @@ -0,0 +1,472 @@ +using System; +using System.Collections.Generic; +using System.Collections; +using UnityEngine; +using System.Linq; + +namespace SerializableCollections +{ + // Mutable(Buildable) Serializable Lookup. Does not support remove. + + [Serializable] + public class SerializableLookup : ILookup + { + // can't serialize internal generic struct. + // extract to 4 arrays. + + //struct Entry + //{ + // public int hashCode; + // public int next; + // public TKey key; + // public TValue value; + //} + + // serializable state. + [SerializeField, HideInInspector] + int[] buckets; // link index of first entry. empty is -1. + [SerializeField, HideInInspector] + int count; + + // Entry[] entries; + [SerializeField, HideInInspector] + int[] entriesHashCode; + [SerializeField, HideInInspector] + int[] entriesNext; + [SerializeField, HideInInspector] + TKey[] entriesKey; + [SerializeField, HideInInspector] + TElement[] entriesValue; + + int version; // version does not serialize + + // equality comparer is not serializable, use specified comparer. + public virtual IEqualityComparer Comparer + { + get + { + return EqualityComparer.Default; + } + } + + protected SerializableLookup() + { + Initialize(0); + } + + protected SerializableLookup(int initialCapacity) + { + Initialize(initialCapacity); + } + + SerializableLookup(int staticCapacity, bool forceSize) + { + Initialize(staticCapacity, forceSize); + } + + public int Count + { + get { return count; } + } + + public IEnumerable this[TKey key] + { + get + { + return new LookupCollection(this, key); + } + } + + public void Add(TKey key, TElement value) + { + Insert(key, value); + } + + public void Clear() + { + if (count > 0) + { + for (int i = 0; i < buckets.Length; i++) buckets[i] = -1; + Array.Clear(entriesHashCode, 0, count); + Array.Clear(entriesKey, 0, count); + Array.Clear(entriesNext, 0, count); + Array.Clear(entriesValue, 0, count); + + count = 0; + version++; + } + } + + public bool Contains(TKey key) + { + return FindEntry(key) >= 0; + } + + int FindEntry(TKey key) + { + if (key == null) throw new ArgumentNullException("key"); + + if (buckets != null) + { + int hashCode = Comparer.GetHashCode(key) & 0x7FFFFFFF; + for (int i = buckets[hashCode % buckets.Length]; i >= 0; i = entriesNext[i]) + { + if (entriesHashCode[i] == hashCode && Comparer.Equals(entriesKey[i], key)) return i; + } + } + + return -1; + } + + IEnumerable FindEntries(TKey key) + { + if (key == null) throw new ArgumentNullException("key"); + + if (buckets != null) + { + int hashCode = Comparer.GetHashCode(key) & 0x7FFFFFFF; + for (int i = buckets[hashCode % buckets.Length]; i >= 0; i = entriesNext[i]) + { + if (entriesHashCode[i] == hashCode && Comparer.Equals(entriesKey[i], key)) + { + yield return i; + } + } + } + } + + void Initialize(int capacity) + { + Initialize(capacity, false); + } + + void Initialize(int capacity, bool forceSize) + { + int size = forceSize ? capacity : HashHelpers.GetPrime(capacity); + buckets = new int[size]; + entriesHashCode = new int[size]; + entriesKey = new TKey[size]; + entriesNext = new int[size]; + entriesValue = new TElement[size]; + for (int i = 0; i < buckets.Length; i++) + { + buckets[i] = -1; + entriesNext[i] = -1; + } + } + + void Insert(TKey key, TElement value) // add only. + { + if (key == null) throw new ArgumentNullException("key"); + if (buckets == null || buckets.Length == 0) Initialize(0); + + int hashCode = Comparer.GetHashCode(key) & 0x7FFFFFFF; + int targetBucket = hashCode % buckets.Length; + + int index; + if (count == entriesHashCode.Length) + { + Resize(); + targetBucket = hashCode % buckets.Length; + } + index = count; + count++; + + entriesHashCode[index] = hashCode; + entriesKey[index] = key; + entriesValue[index] = value; + entriesNext[index] = buckets[targetBucket]; + buckets[targetBucket] = index; + version++; + } + + void Resize() + { + Resize(HashHelpers.ExpandPrime(count), false); + } + + void Resize(int newSize, bool forceNewHashCodes) + { + int[] newBuckets = new int[newSize]; + for (int i = 0; i < newBuckets.Length; i++) newBuckets[i] = -1; + + var newEntriesKey = new TKey[newSize]; + var newEntriesValue = new TElement[newSize]; + var newEntriesHashCode = new int[newSize]; + var newEntriesNext = new int[newSize]; + Array.Copy(entriesKey, 0, newEntriesKey, 0, count); + Array.Copy(entriesValue, 0, newEntriesValue, 0, count); + Array.Copy(entriesHashCode, 0, newEntriesHashCode, 0, count); + Array.Copy(entriesNext, 0, newEntriesNext, 0, count); + + if (forceNewHashCodes) + { + for (int i = 0; i < count; i++) + { + if (newEntriesHashCode[i] != -1) + { + newEntriesHashCode[i] = (Comparer.GetHashCode(newEntriesKey[i]) & 0x7FFFFFFF); + } + } + } + + for (int i = 0; i < count; i++) + { + if (newEntriesHashCode[i] >= 0) + { + int bucket = newEntriesHashCode[i] % newSize; + newEntriesNext[i] = newBuckets[bucket]; + newBuckets[bucket] = i; + } + } + + buckets = newBuckets; + + entriesKey = newEntriesKey; + entriesValue = newEntriesValue; + entriesHashCode = newEntriesHashCode; + entriesNext = newEntriesNext; + } + + public bool TryGetValue(TKey key, out TElement value) + { + int i = FindEntry(key); + if (i >= 0) + { + value = entriesValue[i]; + return true; + } + value = default(TElement); + return false; + } + + public IEnumerator> GetEnumerator() + { + foreach (var key in entriesKey.Distinct(Comparer)) + { + yield return new Grouping(this, key); + } + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + public void TrimExcess() + { + var newLookup = new SerializableLookup(Count, true); + foreach (var g in this) + { + foreach (var item in g) + { + newLookup.Add(g.Key, item); + } + } + + // copy internal field to this + this.buckets = newLookup.buckets; + this.count = newLookup.count; + this.entriesHashCode = newLookup.entriesHashCode; + this.entriesKey = newLookup.entriesKey; + this.entriesNext = newLookup.entriesNext; + this.entriesValue = newLookup.entriesValue; + } + + class Grouping : IGrouping + { + readonly SerializableLookup lookup; + public TKey Key { get; private set; } + + public Grouping(SerializableLookup lookup, TKey key) + { + this.lookup = lookup; + this.Key = key; + } + + public IEnumerator GetEnumerator() + { + return lookup[Key].GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + } + + class LookupCollection : ICollection + { + readonly SerializableLookup lookup; + readonly int version; + readonly List indexes; + + public LookupCollection(SerializableLookup lookup, TKey key) + { + var indexes = new List(); + foreach (var i in lookup.FindEntries(key)) + { + indexes.Add(i); + } + indexes.Reverse(); + + this.version = lookup.version; + this.indexes = indexes; + this.lookup = lookup; + } + + public int Count + { + get + { + return indexes.Count; + } + } + + public bool IsReadOnly + { + get + { + return true; + } + } + + public void Add(TElement item) + { + throw new NotSupportedException(); + } + + public void Clear() + { + throw new NotSupportedException(); + } + + public bool Contains(TElement item) + { + var comparer = EqualityComparer.Default; + using (var e = this.GetEnumerator()) + { + while (e.MoveNext()) + { + if (comparer.Equals(e.Current, item)) return true; + } + } + return false; + } + + public void CopyTo(TElement[] array, int arrayIndex) + { + if (version != lookup.version) throw new InvalidOperationException(SR.InvalidOperation_EnumFailedVersion); + + for (int i = arrayIndex; i < indexes.Count; i++) + { + array[i] = lookup.entriesValue[indexes[i]]; + } + } + + public IEnumerator GetEnumerator() + { + for (int i = 0; i < indexes.Count; i++) + { + if (version != lookup.version) throw new InvalidOperationException(SR.InvalidOperation_EnumFailedVersion); + yield return lookup.entriesValue[indexes[i]]; + } + } + + public bool Remove(TElement item) + { + throw new NotSupportedException(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + } + + static class SR + { + public const string InvalidOperation_EnumFailedVersion = "InvalidOperation_EnumFailedVersion"; + public const string InvalidOperation_EnumOpCantHappen = "InvalidOperation_EnumOpCantHappen"; + public const string ArgumentOutOfRange_Index = "ArgumentOutOfRange_Index"; + public const string Argument_InvalidArrayType = "Argument_InvalidArrayType"; + public const string NotSupported_ValueCollectionSet = "NotSupported_ValueCollectionSet"; + public const string Arg_RankMultiDimNotSupported = "Arg_RankMultiDimNotSupported"; + public const string Arg_ArrayPlusOffTooSmall = "Arg_ArrayPlusOffTooSmall"; + public const string Arg_NonZeroLowerBound = "Arg_NonZeroLowerBound"; + public const string NotSupported_KeyCollectionSet = "NotSupported_KeyCollectionSet"; + public const string Arg_WrongType = "Arg_WrongType"; + public const string ArgumentOutOfRange_NeedNonNegNum = "ArgumentOutOfRange_NeedNonNegNum"; + public const string Arg_HTCapacityOverflow = "Arg_HTCapacityOverflow"; + public const string Argument_AddingDuplicate = "Argument_AddingDuplicate"; + + public static string Format(string f, params object[] args) + { + return string.Format(f, args); + } + } + + static class HashHelpers + { + // Table of prime numbers to use as hash table sizes. + // A typical resize algorithm would pick the smallest prime number in this array + // that is larger than twice the previous capacity. + // Suppose our Hashtable currently has capacity x and enough elements are added + // such that a resize needs to occur. Resizing first computes 2x then finds the + // first prime in the table greater than 2x, i.e. if primes are ordered + // p_1, p_2, ..., p_i, ..., it finds p_n such that p_n-1 < 2x < p_n. + // Doubling is important for preserving the asymptotic complexity of the + // hashtable operations such as add. Having a prime guarantees that double + // hashing does not lead to infinite loops. IE, your hash function will be + // h1(key) + i*h2(key), 0 <= i < size. h2 and the size must be relatively prime. + public static readonly int[] primes = { + 3, 7, 11, 17, 23, 29, 37, 47, 59, 71, 89, 107, 131, 163, 197, 239, 293, 353, 431, 521, 631, 761, 919, + 1103, 1327, 1597, 1931, 2333, 2801, 3371, 4049, 4861, 5839, 7013, 8419, 10103, 12143, 14591, + 17519, 21023, 25229, 30293, 36353, 43627, 52361, 62851, 75431, 90523, 108631, 130363, 156437, + 187751, 225307, 270371, 324449, 389357, 467237, 560689, 672827, 807403, 968897, 1162687, 1395263, + 1674319, 2009191, 2411033, 2893249, 3471899, 4166287, 4999559, 5999471, 7199369, 8639249, 10367101, + 12440537, 14928671, 17914409, 21497293, 25796759, 30956117, 37147349, 44576837, 53492207, 64190669, + 77028803, 92434613, 110921543, 133105859, 159727031, 191672443, 230006941, 276008387, 331210079, + 397452101, 476942527, 572331049, 686797261, 824156741, 988988137, 1186785773, 1424142949, 1708971541, + 2050765853, MaxPrimeArrayLength }; + + public static int GetPrime(int min) + { + if (min < 0) + throw new ArgumentException(SR.Arg_HTCapacityOverflow); + + for (int i = 0; i < primes.Length; i++) + { + int prime = primes[i]; + if (prime >= min) return prime; + } + + return min; + } + + public static int GetMinPrime() + { + return primes[0]; + } + + // Returns size of hashtable to grow to. + public static int ExpandPrime(int oldSize) + { + int newSize = 2 * oldSize; + + // Allow the hashtables to grow to maximum possible size (~2G elements) before encoutering capacity overflow. + // Note that this check works even when _items.Length overflowed thanks to the (uint) cast + if ((uint)newSize > MaxPrimeArrayLength && MaxPrimeArrayLength > oldSize) + { + return MaxPrimeArrayLength; + } + + return GetPrime(newSize); + } + + + // This is the maximum prime smaller than Array.MaxArrayLength + public const int MaxPrimeArrayLength = 0x7FEFFFFD; + } + } +} \ No newline at end of file diff --git a/Assets/SerializableCollections/SerializableLookup.cs.meta b/Assets/SerializableCollections/SerializableLookup.cs.meta new file mode 100644 index 0000000..201580c --- /dev/null +++ b/Assets/SerializableCollections/SerializableLookup.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 6d5905c210f79bf48a02be9a6860a92f +timeCreated: 1458285944 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SerializableCollections/SerializableLookupPropertyDrawer.cs b/Assets/SerializableCollections/SerializableLookupPropertyDrawer.cs new file mode 100644 index 0000000..72477e3 --- /dev/null +++ b/Assets/SerializableCollections/SerializableLookupPropertyDrawer.cs @@ -0,0 +1,60 @@ +#if UNITY_EDITOR + +using System; +using System.Collections; +using System.Collections.Generic; +using UnityEditor; +using UnityEngine; +using UnityObject = UnityEngine.Object; + +namespace SerializableCollections +{ + public abstract class SerializableLookupPropertyDrawer : PropertyDrawer + { + bool foldout; + System.Reflection.BindingFlags reflectionFlags = System.Reflection.BindingFlags.GetProperty | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance; + + public override float GetPropertyHeight(SerializedProperty property, GUIContent label) + { + var height = base.GetPropertyHeight(property, label); + + var target = property.serializedObject.targetObject; + var lookup = fieldInfo.GetValue(target) as IEnumerable; // ILookup + if (lookup == null) return height; + + var count = (int)lookup.GetType().GetProperty("Count", reflectionFlags).GetValue(lookup, null); + return (foldout) + ? (count + 1) * 17f + : 17f; + } + + public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) + { + var target = property.serializedObject.targetObject; + var lookup = fieldInfo.GetValue(target) as IEnumerable; // ILookup + if (lookup == null) return; + + var count = lookup.GetType().GetProperty("Count", reflectionFlags).GetValue(lookup, null); + + foldout = EditorGUI.Foldout(position, foldout, label, true); + EditorGUI.LabelField(position, label, new GUIContent() { text = "Count:" + count }); + if (foldout) + { + // only dump:) + foreach (IEnumerable item in lookup) // IGrouping + { + var key = item.GetType().GetProperty("Key", reflectionFlags).GetValue(item, null); + + foreach (var subItem in item) + { + position = new Rect(position.x, position.y + 17f, position.width, position.height); + EditorGUI.LabelField(position, key.ToString(), (subItem == null) ? "null" : subItem.ToString()); + } + + } + } + } + } +} + +#endif \ No newline at end of file diff --git a/Assets/SerializableCollections/SerializableLookupPropertyDrawer.cs.meta b/Assets/SerializableCollections/SerializableLookupPropertyDrawer.cs.meta new file mode 100644 index 0000000..fbba774 --- /dev/null +++ b/Assets/SerializableCollections/SerializableLookupPropertyDrawer.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 680ceaa7eeb6980479c842b1600b09c0 +timeCreated: 1458285944 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SerializableCollections/SerializableTuple.cs b/Assets/SerializableCollections/SerializableTuple.cs new file mode 100644 index 0000000..8702cd7 --- /dev/null +++ b/Assets/SerializableCollections/SerializableTuple.cs @@ -0,0 +1,178 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace SerializableCollections +{ + [Serializable] + public abstract class SerializableTuple : IEquatable> + { + [SerializeField] + T1 item1; + public T1 Item1 { get { return item1; } } + + [SerializeField] + T2 item2; + public T2 Item2 { get { return item2; } } + + public SerializableTuple() + { + + } + + public SerializableTuple(T1 item1, T2 item2) + { + this.item1 = item1; + this.item2 = item2; + } + + public bool Equals(SerializableTuple other) + { + var comparer1 = EqualityComparer.Default; + var comparer2 = EqualityComparer.Default; + + return comparer1.Equals(item1, other.item1) && + comparer2.Equals(item2, other.item2); + } + + public override int GetHashCode() + { + var comparer1 = EqualityComparer.Default; + var comparer2 = EqualityComparer.Default; + + int h0; + h0 = comparer1.GetHashCode(item1); + h0 = (h0 << 5) + h0 ^ comparer2.GetHashCode(item2); + return h0; + } + + public override string ToString() + { + return String.Format("({0}, {1})", item1, item2); + } + } + + [Serializable] + public abstract class SerializableTuple : IEquatable> + { + [SerializeField] + T1 item1; + public T1 Item1 { get { return item1; } } + + [SerializeField] + T2 item2; + public T2 Item2 { get { return item2; } } + + [SerializeField] + T3 item3; + public T3 Item3 { get { return item3; } } + + public SerializableTuple() + { + + } + + public SerializableTuple(T1 item1, T2 item2, T3 item3) + { + this.item1 = item1; + this.item2 = item2; + this.item3 = item3; + } + + public bool Equals(SerializableTuple other) + { + var comparer1 = EqualityComparer.Default; + var comparer2 = EqualityComparer.Default; + var comparer3 = EqualityComparer.Default; + + return comparer1.Equals(item1, other.item1) && + comparer2.Equals(item2, other.item2) && + comparer3.Equals(item3, other.item3); + } + + public override int GetHashCode() + { + var comparer1 = EqualityComparer.Default; + var comparer2 = EqualityComparer.Default; + var comparer3 = EqualityComparer.Default; + + int h0; + h0 = comparer1.GetHashCode(item1); + h0 = (h0 << 5) + h0 ^ comparer2.GetHashCode(item2); + h0 = (h0 << 5) + h0 ^ comparer3.GetHashCode(item3); + return h0; + } + + public override string ToString() + { + return String.Format("({0}, {1}, {2})", item1, item2, item3); + } + } + + [Serializable] + public abstract class SerializableTuple : IEquatable> + { + [SerializeField] + T1 item1; + public T1 Item1 { get { return item1; } } + + [SerializeField] + T2 item2; + public T2 Item2 { get { return item2; } } + + [SerializeField] + T3 item3; + public T3 Item3 { get { return item3; } } + + [SerializeField] + T4 item4; + public T4 Item4 { get { return item4; } } + + public SerializableTuple() + { + + } + + public SerializableTuple(T1 item1, T2 item2, T3 item3, T4 item4) + { + this.item1 = item1; + this.item2 = item2; + this.item3 = item3; + this.item4 = item4; + } + + public bool Equals(SerializableTuple other) + { + var comparer1 = EqualityComparer.Default; + var comparer2 = EqualityComparer.Default; + var comparer3 = EqualityComparer.Default; + var comparer4 = EqualityComparer.Default; + + return comparer1.Equals(item1, other.item1) && + comparer2.Equals(item2, other.item2) && + comparer3.Equals(item3, other.item3) && + comparer4.Equals(item4, other.item4); + } + + public override int GetHashCode() + { + var comparer1 = EqualityComparer.Default; + var comparer2 = EqualityComparer.Default; + var comparer3 = EqualityComparer.Default; + var comparer4 = EqualityComparer.Default; + + int h0, h1; + h0 = comparer1.GetHashCode(item1); + h0 = (h0 << 5) + h0 ^ comparer2.GetHashCode(item2); + h1 = comparer3.GetHashCode(item3); + h1 = (h1 << 5) + h1 ^ comparer4.GetHashCode(item4); + h0 = (h0 << 5) + h0 ^ h1; + return h0; + } + + public override string ToString() + { + return String.Format("({0}, {1}, {2}, {3})", item1, item2, item3, item4); + } + } +} diff --git a/Assets/SerializableCollections/SerializableTuple.cs.meta b/Assets/SerializableCollections/SerializableTuple.cs.meta new file mode 100644 index 0000000..47c0cb8 --- /dev/null +++ b/Assets/SerializableCollections/SerializableTuple.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 5c49fbdc5b36ab6438845bc4343d2a6b +timeCreated: 1458285944 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/ProjectSettings/AudioManager.asset b/ProjectSettings/AudioManager.asset new file mode 100644 index 0000000000000000000000000000000000000000..069db4cfe94792e2d41142ae83fba953f08aedc5 GIT binary patch literal 4140 zcmeH~y>1gh6ov2FAwUw6R5UbOAgag$fkjDvOk_n^GG5^}Og6L8CS#Aa*)5W4>pTD@ zC{4OFX;b9^5O2U6@Cq#F%zA~CI^|sHYVP@b=W6Dxn-OV!6ItI7ku|JXM7o`Ko!19l z`CC<05CAMAUwyqeiI4ZfKR;Hczs&7Vw%#H6JLA1biT=uol01;Bwv;!4lna3Dt22;G z^ge?oZz1JL-B12}&fDY&&LMw^n*B@$`ET&IsL37?A{yRDO}HYgfCkC9)~9RUD>vpr-0bXENCzTT@K5jI1#>Nx~>rMoZ7mW=3b> zu8MP;Nlz!LFnJiwv^oJE*h7u2k(!`uq;iU0G~6zdL}yWYPCZVuyijIr(^&7=Vw!`E z^gR&GRGun>9of(nN9mM<(o=O{v^(biIcWKa>2ZGQE?r-p*JSX|Nc)yyFtrcwfOo(< o;2rP|cn7=#-U07`cfdQ~9e5}Q$`5#1x^&O+W-LV5)Oefz11?N~8~^|S literal 0 HcmV?d00001 diff --git a/ProjectSettings/ClusterInputManager.asset b/ProjectSettings/ClusterInputManager.asset new file mode 100644 index 0000000000000000000000000000000000000000..5322ee0c7b1a66944d90241ad5649fa6ddef90c8 GIT binary patch literal 4104 zcmeH_yGjE=6o$|2=HmTsCBA?~P%zjAVxfhCNNgp_AW9NsbEyZkw)G86VduMu5X45y zJcH~1?<^~esjbey;mrBw%s;dLtVl2rS(*}&MPwwAYGt>weNmO~IF5}07$b(C>%+6) zZS+36e{hYj$2G7zg6kZ6A`bm=QaExWPocOMBd!3*J|9M2!MUIP0kSx*1!e~`26>qA zP(Hvmu!lMf4kMv#BHyI_MM6hjkOTBS<6P>LGG5H-m%&Yq{iU2fo$&W8$q5vx&w4uJ zUVjTU^=FX%xq1Cr_SgRE&ygpQ*PqY0*N2~p{sQtOeZ1C0eLmqN{pE}olJC7s-(>}y zgTB${a^QVl^;qhyez#|%!_IBLchu}OuWTgk^Q7$N7D4yz;QG=YH`^A)sf`9UYDBH{ pI;kEKE#@yZ#s~gVov8!rfI6TKr~~SNI-m}y1L}Y}pbq?p13w7jdy)VE literal 0 HcmV?d00001 diff --git a/ProjectSettings/DynamicsManager.asset b/ProjectSettings/DynamicsManager.asset new file mode 100644 index 0000000000000000000000000000000000000000..1fde1ca8d188c80aadd789fb7b997e84744050df GIT binary patch literal 4276 zcmeH~ziSjh6vyA*`Sbh{e_$a|4A>tE2`LN`z2rt!?O2_6vSb}ww-c>5M}be%$Wo_TZl&GMwPReC^t4?>Ips{2 zHjs$;Ru}bkzF^#{H5=$Q2b@pUTB5J5t4(Kmx|!LQ23=BpZ5vsVm>dbvrZrn$9-P|` z{`~yKry=Yf3v*B)C=e6~3Iqj$0zrYGKu{nk5ES@d75K1w?)_iRHe1_yexel#5)=iAkTya>qM$)J07_UZED8aUrN%7{2gm`aXy7ii zT!1^U%$TJ}Px)+(p5OTWNFU&yfz4F_Ek*{Q*E#HT$31*kRplIwb_)2#+vKZN9`&CV z`Ro28Ht2V$2Bp&n0_&@o1ibQ}`wFkbUd^-Y;Ueu^``cA08tMq%*lpK`_?Q`N7?5AvH!dqu(x|>p86bjqw*@ws#_W2(Q2V? ir!~gfw_pT}fDtePM!*Od0V7}pjDQg^0!HA!2>bv8lT0lD literal 0 HcmV?d00001 diff --git a/ProjectSettings/EditorSettings.asset b/ProjectSettings/EditorSettings.asset new file mode 100644 index 0000000000000000000000000000000000000000..ad7765aeba4ffe3bbb3cfc77e2df4b6fb0c13dcf GIT binary patch literal 4212 zcmeHKJ#Q015S@$pO!)pRpa@M$8w3#&ZX$xgDS{j-Xxnx0dPW zXfz4}0rthS&84+(2M4!)+}t=kvvg3U{^CM)bdQ6crCa#Iim^7~Mu;!{AyF#*9d z_JG=g%V~uAIa#SdZZ5bZ5ga&pgB9R4`YPBBc?LYcxoWf__?|d;kE6cypsa69YEQ@t zLqFhIl^7f+0g3@fKT2YpdkWxZ;MIOk3p}fzdElj2`&l@`$LGG4JUC`Fgt6NbGVZAG z70-e?DvG4vj_I=%j*c~Z9J(j0*_MZ|=`hJ7j&K=`Yv5*oRXsDtJyj`ZJr#1P()drL zf#KuBC$=xbWADu?;1%!+cm=!yUIDLwSHLUa74QoDF9k3fw&N&by|~U!Ek2GD&i*)T zN#b4SdJh_ne!pK&hmlEDtm~mk8|iRI2Ag`WWhA>BjUU2Dk5Le#s~foHAWfRv+BL&T F{ujBM;{pHx literal 0 HcmV?d00001 diff --git a/ProjectSettings/GraphicsSettings.asset b/ProjectSettings/GraphicsSettings.asset new file mode 100644 index 0000000000000000000000000000000000000000..a3c08f2b3810316271a90163464a93a10fefe3b8 GIT binary patch literal 4332 zcmeI0O;a327{_}E#Hjcd-%Ugfz8eV;FrpEM*MLCWu!x!qHoFZw)a=aG%xnR-EwAP) zc=P4r$-7!s`4v)D<=`ja>d7kc|L>k2W@fkaY!y$cYoGr0)6etoo^EzFLJWQ&#G^+- zh)3{=4HOy?z*gzU+*3C$++jVa^3R=ch!A7UlZi zMLn;8o9Esy@_Js)xFi0AKZqcnao#`C(R#!xykT(8f1Mo0=S4o1@;3-w!+GyE!MSg5 zlEZAgpT@ssaK`VX{4%-Ac%$cgaO!!RymOMr>KP%2+5A?|6++kWyq-~Vn2oo3@cgw| zZuRi*Osh+Fkos&FP&jdNl=COJv3Egfz?~uc6yw!uhm)b11dfp{<8E^LIZmNf8 zvX`Fs$YC~*)$=}~+pXt1In2geJ@^*TX1UcfP3jswykAGq!}I(hc}M3doM(ilym+2x z$YDI^=laZfW}aEX4tc*=LjFq_BcIFoKq3D;xZ^VZtiF%-{w|Q~c2?X%M&1|p`MqJd zxi6#0-w$>JjmEmX7uUdf4wnc!;kH&Mtx{Z`q4Az|YcR$U8J<-N^@~=|9UgF=TyjtSF zqI5AH5(q_bI%$c2!bbs($RfM+&o$gPYP-0br(`giV=vHTbLEZX;>RRyB#dR?944 zG2G2}ZODpJEj$k|$W0@g_oBJ5x$On|$mOFkQdKP($wZas90s!K)q18gL;sRB3&8p);a?N&dvFK gIsbh6TY~wAQXj6ahqnpA|BK+*fBBqa&9MgX4^sLRQvd(} literal 0 HcmV?d00001 diff --git a/ProjectSettings/InputManager.asset b/ProjectSettings/InputManager.asset new file mode 100644 index 0000000000000000000000000000000000000000..ea15a1093484c05c6c11e6db80c0ed7146c55a68 GIT binary patch literal 5520 zcmeI0Noy2A6vtniiF@4R7Nc=r4#5>caEno*Xi&rr1nJC_NynM)p}Qv=9s*u+QZIf0 z5poePxp?yvL_B#F!J8k#`2SZgGu_n0yL1iR)$d>RepUVIbx4&+=L(VTw<5ApWD_cp zbNy%gPmY|EKTAtXmIa{;*W9nyFF#!0{_SV!_wL>uJM9zDzTkqlF6TvN(SJ!BvmzFL z^Bpp~V99I=B014z$#>{vvcLA9W7`Vr6d1gycc5Lg-XTAr^}vT5Ub0%G1HWx}9FO~V zQrG=UGK9V#F)lePQ@u08Uj^M7;+S+qbP9`XBOlfMDAiI3GX^0|a2{^nGV_%~pazXi34zm@$B^JmOW{O(kb_zz%{ zza6!Szk~e^{GHSd@!6H?5x)YP{N1Qc{2ul<@b^$R@Ox7|;!nUPpX+Sm?_+-hzmK|s zzdzMW@*X)g2b;Nk02lMwf<>KQBK3ng{avgdYSC|_KYZXTayX~Y$NCZKdY&bn=bvDb zf0TMWF2ApZSU;B2KgaswMUgNwP#nSR3KWrI^_gXQ9;>v>Y+2ChV7cl z*lN^HbvHH!8e!mP<9R1(CGjwVxjIrhgW6pC;Y-Muv_Dsg?R-=Y!H4En* z)a|lrN_c9|;Qa6Ccs$N{n2fKBix;W4u4mK#iOD6SwfZLv9zjIo-!J=KwfbmGsbsA( z&N-u%l^i#<%h#N%HlMy3xP%?^B1>{foX4 zy~EWR*yOffqlB5yMH4eS?!TG&d^9n$AG2*V4VN0>Fw9v}N2k=o0 zX(i$#*t?!PDF$j_;xJW zBt-Xk4ySu~r?$d7;v<1+srRtV?b&aAAiAsf(PZr^Q}GE$dNAQXMcp*TC!Fx7HH`BQ zaYS$Nm%e94x{qgSYs{sWS%&n}vNwludb)QN+Z5K#W759OEG}#(#z{BL_){6>?6!!Q z2<9G}E)|`XfD%vwN@LnZ`KTc6x#!aMj99>uB3c z^aAw`MZ2KsJ2TTHK0%9f;mkSrHy`($`^^wpYeeZZ5zQha5fw7|Otw~_Z_o3T0_Y=d zlfBowkLU8^&C=k@{!}b&BKSS8RU#L9FW50x^bjNWNs$`|WL*%7-k?P{Vs0ULv3>wP zkD7UmAr|v@@I};o{@+=a%7Jq*PxxBa$Ncl>(3`bmLwvy^_Y8XOF&^4+!%`42+<%n;8&dyGBL$o{dP zJI1;0*yr22tsBOsi=&dMT{X5$&$O`FGwr&q9fPvi?HXslQ?bp7u2Ee(`Y>A!axTov zVP2_1ztL=&atTF6JEthPSVxk`Opb7DUdh_f75 zH=S*fO%;*ZEh2Ka$X0xb9H_idd2acD{IkBk?s)*)FdC=+-1XaE?_L`GxOnc|@SBhJ zfhAKSxN><>WCZ{9+!%>?`1^EPMxT2!x&@GN%<$wY_&u<1$1v;XF*haW5n~RF{?iyD zH~6El$T8aay@J zKI0i~j_`*6oaM76|CcT2IZ#}jBbM{bDUQEw`Mn0`d`V<<1{{~%SK?CXM4f_82Bt2jkRHav2$F%?F6U)BPG7u za`s)(e~;ylmH1xE=f~U==Biq;j;9l1h%|e{H0Y%J>n)vSLDWs9fBZxbY~ z*C*9#m^lb?I0$v44yCEGUalO|VcbEe1{SI;h$Dt?#%Vx(19YD4UZT@p9G-yVQMI-d zL|P@aI7xJeYYeSM-PQ1B+)h-KhIyXWiqZni`K|AQ{*G@M2E2@*ZNwRj_3bkH=tJ!I8wc`-C8+91LZuKVq`YKAP(^rD5 zodn&kPFNWWTN(Dyh-z^d1}Dr+t*4@{Ze{UGT2o=TtU9N;pc)R;Fm3hXLD9KryX_TO zEsiqW2Lo8Onk4bS-Iohh9jMb9Mx00@U0D{DFEE>`ro3-6%P@x8a1Jl2p~m51F2&iQ zQ<7jU?>h5=_M>b;AM&xd4Go@y$;YGulL|~KFsZ<#0+R|%D)2w9z}MI3E*H1Y*I@Gs zKJtI~e(4a*s>pYXB45-t|GeX%VGBOEPaEG09{xYVC7k>4gIWLjwakD2?2Lc;s|CMk ae|hmD;*Gc#GV(8cw$Go3#@B=YQvL;&I``lJ literal 0 HcmV?d00001 diff --git a/ProjectSettings/ProjectSettings.asset b/ProjectSettings/ProjectSettings.asset new file mode 100644 index 0000000000000000000000000000000000000000..e4f8a538185113eb87955faacdbcf76e79087212 GIT binary patch literal 35953 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 raee$gCkS?l_}Nc-F2Gu zfXoF2DF?V96%LRKhr+2+PaJ?FQhG$303pP+rT+loeP_lS@0J7HIM~T#XFl`h``)~r zadwAjaFu9emxvxDI?flOsj<>R~Gj%L3Z-hKPzUgbu9;`kJ^ zV|_#ee8uN2qBh$f=ti3;!#`j4Q~O4S+F6FsF(pI4uq|AHvjowQvHy|nPjeGG{op&` zeVI4d9t9j@4DZ)Er+5sQj)QgjsGsuOzHIG}#P(TQV%q|@p)(lsfrLIwP-Y2!k0kW( z1Lscg^Q;Yh%;#v#v)X=<+lc2F7c(!z*DN1S@k^H9pW;o+A4u`{E$6!x>+f+aA6c$% zp^h_4;GbLmP|E(Ma2qj>XrANw4rra9xs7=}lH$Kw{%DH-X8DPjn>_q( z`D2EW!S)I(FF!HIdVU^! zr;YoSSkEuSJh`4<1RsL^5xp-u`{kwBelVf)GV{z5?1vKj;uUbMGnCjDuf{w>cR3Gt zY@Dw_zYU$_zJ5LC$$dQrPO$H%(LS^9FkgHp86C5)KjRkoc+8V|;O`I0%s?lZhY4`4 zpWN5@4l&%^_oJNaEVD^2i06DuxGLH%%P3ObdPt2+bFCndUSvBMq)n1-@ge!bo^EY0b|`5tLlv z$>n-IlpS?DW}@8W8CXlpCJo!7ZMsTTS9;ExL~tQRaw}>DvNJp3snCxCzo}{!(-V^L zA~owO5pqH(^y^Vc1d*z_h>lyUa$QD3#~w)GMyerKWZgB>;fYn*uBu$O>Wjb$7er0Y zafSj>@MQqnZ7!_I$`y>(azza>+ z7fyw}mR-de>Vkz4d!am5E$_|Xmf=TPH|fApb` z3AzW^`mOza?E|m9-99j%vT8J4X`aoXkI%pL)3NW2$>;O$pgzN;+Yjcl==%;BN=F}c zqFjOh+>H|sfpuN)o6Ft^Vs zFXA^3KbM~`V{Kx-rE*>$@tFE#SN&aGNBpI7X#)BE zkFgaG01X8XLP7ZdF|n}ZnueLko}4eoC;$1!%@N7Giu68;NDp>wBE_lMsp-E(d22SC zjsviX>-PTa|M;_>yxzK*I9YfY8u{QE>|ApqA@Z9h2t^!xp0W~l0FbkeT#;v-8RYUJ zH_scMl^3v4Jd;Cemia%JpOtm6vyXiK7S+im>g0i)b>`<2bqeIBPF}WAgLSB-E#{F< zwoW}rP1X4`=1HCH&3 z=LGhapT7u0@|^K`9wF=Z$2_0#c>vs5Vtygv^B}po3JITwVxE&boZ}*5o+10-;{R?y z!J7FlGEBG>%AWH6D6Kr#mq2+nDXWI-*Q9c^TlIre?QKNy=V(O-enYgXxKh`rmvy(a zEamF)x%*1l4ve8mj>F6D ziK>?a;V8Q2D_y%#zN>@PL&O|IOP;R!?%0lM9IILYfW@)B-~a#r85w~BtU$c@RmvB^9M=<_(`^;r zz8Aa#5_14zkUR*OGcYtjv_treK$&IC3=NwY85&rCLLhYz%*e11sFnxF2Z=KQF#`uk z4k9iM6=y~hH-U?5*=+2UBq8Rn-md50s#tv3L!@}$SAQ%GYHkv2oO+w;AHo~zHJLEk(R#oKP*Z+X~mgx(+uyu9Yivm=-U6EB}v sTv7S;jW+CR9k32q2do3u0qcNuz&cFUEWa=eJQ( ze}p_BPpegA4Du|nDw1d99c%&b@QkD6QDo#0{1U->tjkkEeT|wr@~Rh>576aTCr7rg_Zw$++_LFf^|p4Zeox0P z1RbmH+}I_ztSwKsni9XaeQmqC;?qo?PudUWq<6jm literal 0 HcmV?d00001 diff --git a/SerializableDictionary.CSharp.csproj b/SerializableDictionary.CSharp.csproj new file mode 100644 index 0000000..b66a04d --- /dev/null +++ b/SerializableDictionary.CSharp.csproj @@ -0,0 +1,79 @@ + + + + Debug + AnyCPU + 10.0.20506 + 2.0 + {4A4AA6FC-D28B-5802-C301-5E01F3EB8438} + Library + Assembly-CSharp + 512 + {E097FAD1-6243-4DAD-9C02-E9B9EFC3FFC1};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + .NETFramework + v3.5 + Unity Subset v3.5 + + Game:1 + StandaloneWindows:5 + 5.4.0b5 + + 4 + + + pdbonly + false + Temp\UnityVS_bin\Debug\ + Temp\UnityVS_obj\Debug\ + prompt + 4 + DEBUG;TRACE;UNITY_5_4_0;UNITY_5_4;UNITY_5;ENABLE_NEW_BUGREPORTER;ENABLE_AUDIO;ENABLE_CACHING;ENABLE_CLOTH;ENABLE_DUCK_TYPING;ENABLE_EDITOR_RETINA;ENABLE_RETINA_GUISTYLES;ENABLE_FRAME_DEBUGGER;ENABLE_GENERICS;ENABLE_HOME_SCREEN;ENABLE_IMAGEEFFECTS;ENABLE_LIGHT_PROBES_LEGACY;ENABLE_MICROPHONE;ENABLE_MULTIPLE_DISPLAYS;ENABLE_PHYSICS;ENABLE_PLUGIN_INSPECTOR;ENABLE_SHADOWS;ENABLE_SPRITERENDERER_FLIPPING;ENABLE_SPRITES;ENABLE_SPRITE_POLYGON;ENABLE_TERRAIN;ENABLE_RAKNET;ENABLE_UNET;ENABLE_UNITYEVENTS;ENABLE_VR;ENABLE_WEBCAM;ENABLE_WWW;ENABLE_CLOUD_SERVICES;ENABLE_CLOUD_SERVICES_COLLAB;ENABLE_CLOUD_SERVICES_ADS;ENABLE_CLOUD_HUB;ENABLE_CLOUD_PROJECT_ID;ENABLE_CLOUD_SERVICES_PURCHASING;ENABLE_CLOUD_SERVICES_ANALYTICS;ENABLE_CLOUD_SERVICES_UNET;ENABLE_CLOUD_SERVICES_BUILD;ENABLE_CLOUD_LICENSE;ENABLE_EDITOR_METRICS;ENABLE_EDITOR_METRICS_CACHING;INCLUDE_DYNAMIC_GI;INCLUDE_GI;INCLUDE_IL2CPP;INCLUDE_DIRECTX12;PLATFORM_SUPPORTS_MONO;RENDER_SOFTWARE_CURSOR;INCLUDE_PUBNUB;ENABLE_LOCALIZATION;ENABLE_ANDROID_ATLAS_ETC1_COMPRESSION;ENABLE_EDITOR_TESTS_RUNNER;UNITY_STANDALONE_WIN;UNITY_STANDALONE;ENABLE_SUBSTANCE;ENABLE_TEXTUREID_MAP;ENABLE_RUNTIME_GI;ENABLE_MOVIES;ENABLE_NETWORK;ENABLE_CRUNCH_TEXTURE_COMPRESSION;ENABLE_UNITYWEBREQUEST;ENABLE_EVENT_QUEUE;ENABLE_CLUSTERINPUT;ENABLE_WEBSOCKET_HOST;ENABLE_MONO;ENABLE_PROFILER;DEBUG;TRACE;UNITY_ASSERTIONS;UNITY_EDITOR;UNITY_EDITOR_64;UNITY_EDITOR_WIN;UNITY_TEAM_LICENSE;ENABLE_VSTU;UNITY_PRO_LICENSE + false + + + pdbonly + false + Temp\UnityVS_bin\Release\ + Temp\UnityVS_obj\Release\ + prompt + 4 + TRACE;UNITY_5_4_0;UNITY_5_4;UNITY_5;ENABLE_NEW_BUGREPORTER;ENABLE_AUDIO;ENABLE_CACHING;ENABLE_CLOTH;ENABLE_DUCK_TYPING;ENABLE_EDITOR_RETINA;ENABLE_RETINA_GUISTYLES;ENABLE_FRAME_DEBUGGER;ENABLE_GENERICS;ENABLE_HOME_SCREEN;ENABLE_IMAGEEFFECTS;ENABLE_LIGHT_PROBES_LEGACY;ENABLE_MICROPHONE;ENABLE_MULTIPLE_DISPLAYS;ENABLE_PHYSICS;ENABLE_PLUGIN_INSPECTOR;ENABLE_SHADOWS;ENABLE_SPRITERENDERER_FLIPPING;ENABLE_SPRITES;ENABLE_SPRITE_POLYGON;ENABLE_TERRAIN;ENABLE_RAKNET;ENABLE_UNET;ENABLE_UNITYEVENTS;ENABLE_VR;ENABLE_WEBCAM;ENABLE_WWW;ENABLE_CLOUD_SERVICES;ENABLE_CLOUD_SERVICES_COLLAB;ENABLE_CLOUD_SERVICES_ADS;ENABLE_CLOUD_HUB;ENABLE_CLOUD_PROJECT_ID;ENABLE_CLOUD_SERVICES_PURCHASING;ENABLE_CLOUD_SERVICES_ANALYTICS;ENABLE_CLOUD_SERVICES_UNET;ENABLE_CLOUD_SERVICES_BUILD;ENABLE_CLOUD_LICENSE;ENABLE_EDITOR_METRICS;ENABLE_EDITOR_METRICS_CACHING;INCLUDE_DYNAMIC_GI;INCLUDE_GI;INCLUDE_IL2CPP;INCLUDE_DIRECTX12;PLATFORM_SUPPORTS_MONO;RENDER_SOFTWARE_CURSOR;INCLUDE_PUBNUB;ENABLE_LOCALIZATION;ENABLE_ANDROID_ATLAS_ETC1_COMPRESSION;ENABLE_EDITOR_TESTS_RUNNER;UNITY_STANDALONE_WIN;UNITY_STANDALONE;ENABLE_SUBSTANCE;ENABLE_TEXTUREID_MAP;ENABLE_RUNTIME_GI;ENABLE_MOVIES;ENABLE_NETWORK;ENABLE_CRUNCH_TEXTURE_COMPRESSION;ENABLE_UNITYWEBREQUEST;ENABLE_EVENT_QUEUE;ENABLE_CLUSTERINPUT;ENABLE_WEBSOCKET_HOST;ENABLE_MONO;ENABLE_PROFILER;DEBUG;TRACE;UNITY_ASSERTIONS;UNITY_EDITOR;UNITY_EDITOR_64;UNITY_EDITOR_WIN;UNITY_TEAM_LICENSE;ENABLE_VSTU;UNITY_PRO_LICENSE + false + + + + + + + + + + + + Library\UnityAssemblies\UnityEngine.dll + + + Library\UnityAssemblies\UnityEngine.UI.dll + + + Library\UnityAssemblies\UnityEngine.Networking.dll + + + Library\UnityAssemblies\UnityEditor.dll + + + Library\UnityAssemblies\UnityEditor.iOS.Extensions.Xcode.dll + + + Library\UnityAssemblies\UnityEditor.iOS.Extensions.Common.dll + + + + + + + + + + + diff --git a/SerializableDictionary.sln b/SerializableDictionary.sln new file mode 100644 index 0000000..758b97a --- /dev/null +++ b/SerializableDictionary.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2015 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SerializableDictionary.CSharp", "SerializableDictionary.CSharp.csproj", "{4A4AA6FC-D28B-5802-C301-5E01F3EB8438}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4A4AA6FC-D28B-5802-C301-5E01F3EB8438}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4A4AA6FC-D28B-5802-C301-5E01F3EB8438}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4A4AA6FC-D28B-5802-C301-5E01F3EB8438}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4A4AA6FC-D28B-5802-C301-5E01F3EB8438}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal