-
-
Save DK013/cfefbadfeff0406a7e59d3f258c8ce82 to your computer and use it in GitHub Desktop.
Unity3D: Class that behaves like a Dictionary<K, V>, but can still be serialized and edited by the Unity Editor.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Copyright (c) 2012 Calvin Rien | |
// http://the.darktable.com | |
// | |
// This software is provided 'as-is', without any express or implied warranty. In | |
// no event will the authors be held liable for any damages arising from the use | |
// of this software. | |
// | |
// Permission is granted to anyone to use this software for any purpose, | |
// including commercial applications, and to alter it and redistribute it freely, | |
// subject to the following restrictions: | |
// | |
// 1. The origin of this software must not be misrepresented; you must not claim | |
// that you wrote the original software. If you use this software in a product, | |
// an acknowledgment in the product documentation would be appreciated but is not | |
// required. | |
// | |
// 2. Altered source versions must be plainly marked as such, and must not be | |
// misrepresented as being the original software. | |
// | |
// 3. This notice may not be removed or altered from any source distribution. | |
using UnityEngine; | |
using System.Collections.Generic; | |
[System.Serializable] | |
public sealed class ObjectKvp : UnityNameValuePair<Object> { | |
public Object value = null; | |
override public Object Value { | |
get { return this.value; } | |
set { this.value = value; } | |
} | |
public ObjectKvp(string key, Object value) : base(key, value) { | |
} | |
} | |
[System.Serializable] | |
public class ObjectDictionary : UnityDictionary<Object> { | |
public List<ObjectKvp> values; | |
override protected List<UnityKeyValuePair<string, Object>> KeyValuePairs { | |
get { | |
return values.ConvertAll<UnityKeyValuePair<string,Object>>(new System.Converter<ObjectKvp, UnityKeyValuePair<string,Object>>( | |
x => { | |
return x as UnityKeyValuePair<string,Object>; | |
})); | |
} | |
set { | |
if (value == null) { | |
values = new List<ObjectKvp>(); | |
return; | |
} | |
values = value.ConvertAll<ObjectKvp>(new System.Converter<UnityKeyValuePair<string,Object>, ObjectKvp>( | |
x => { | |
return new ObjectKvp(x.Key, x.Value as Object); | |
})); | |
} | |
} | |
override protected void SetKeyValuePair(string k, Object v) { | |
var index = values.FindIndex(x => { | |
return x.Key == k;}); | |
if (index != -1) { | |
if (v == null) { | |
values.RemoveAt(index); | |
return; | |
} | |
values[index] = new ObjectKvp(k, v); | |
return; | |
} | |
values.Add(new ObjectKvp(k, v)); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Copyright (c) 2012 Calvin Rien | |
// http://the.darktable.com | |
// | |
// This software is provided 'as-is', without any express or implied warranty. In | |
// no event will the authors be held liable for any damages arising from the use | |
// of this software. | |
// | |
// Permission is granted to anyone to use this software for any purpose, | |
// including commercial applications, and to alter it and redistribute it freely, | |
// subject to the following restrictions: | |
// | |
// 1. The origin of this software must not be misrepresented; you must not claim | |
// that you wrote the original software. If you use this software in a product, | |
// an acknowledgment in the product documentation would be appreciated but is not | |
// required. | |
// | |
// 2. Altered source versions must be plainly marked as such, and must not be | |
// misrepresented as being the original software. | |
// | |
// 3. This notice may not be removed or altered from any source distribution. | |
using System.Collections; | |
using System.Collections.Generic; | |
namespace UnityEngine { | |
public class UnityNameValuePair<V> : UnityKeyValuePair<string, V> { | |
public string name = null; | |
override public string Key { | |
get { return name; } | |
set { name = value; } | |
} | |
public UnityNameValuePair() : base() { | |
} | |
public UnityNameValuePair(string key, V value) : base(key, value) { | |
} | |
} | |
public class UnityKeyValuePair<K, V> { | |
virtual public K Key { | |
get; | |
set; | |
} | |
virtual public V Value { | |
get; | |
set; | |
} | |
public UnityKeyValuePair() { | |
Key = default(K); | |
Value = default(V); | |
} | |
public UnityKeyValuePair(K key, V value) { | |
Key = key; | |
Value = value; | |
} | |
} | |
public abstract class UnityDictionary<K,V> : IDictionary<K,V> { | |
abstract protected List<UnityKeyValuePair<K,V>> KeyValuePairs { | |
get; | |
set; | |
} | |
protected abstract void SetKeyValuePair(K k, V v); /* { | |
var index = Collection.FindIndex(x => {return x.Key == k;}); | |
if (index != -1) { | |
if (v == null) { | |
Collection.RemoveAt(index); | |
return; | |
} | |
values[index] = new UnityKeyValuePair(key, value); | |
return; | |
} | |
values.Add(new UnityKeyValuePair(key, value)); | |
} */ | |
virtual public V this[K key] { | |
get { | |
var result = KeyValuePairs.Find(x => { | |
return x.Key.Equals(key);}); | |
if (result == null) { | |
return default(V); | |
} | |
return result.Value; | |
} | |
set { | |
if (key == null) { | |
return; | |
} | |
SetKeyValuePair(key, value); | |
} | |
} | |
#region IDictionary interface | |
public void Add(K key, V value) { | |
this[key] = value; | |
} | |
public void Add(KeyValuePair<K, V> kvp) { | |
this[kvp.Key] = kvp.Value; | |
} | |
public bool TryGetValue(K key, out V value) { | |
if (!this.ContainsKey(key)) { | |
value = default(V); | |
return false; | |
} | |
value = this[key]; | |
return true; | |
} | |
public bool Remove(KeyValuePair<K, V> item) { | |
return Remove(item.Key); | |
} | |
public bool Remove(K key) { | |
var list = KeyValuePairs; | |
var index = list.FindIndex(x => { | |
return x.Key.Equals(key);}); | |
if (index == -1) { | |
return false; | |
} | |
list.RemoveAt(index); | |
KeyValuePairs = list; | |
return true; | |
} | |
public void Clear() { | |
var list = KeyValuePairs; | |
list.Clear(); | |
KeyValuePairs = list; | |
} | |
public bool ContainsKey(K key) { | |
return KeyValuePairs.FindIndex(x => { | |
return x.Key.Equals(key);}) != -1; | |
} | |
public bool Contains(KeyValuePair<K, V> kvp) { | |
return this[kvp.Key].Equals(kvp.Value); | |
} | |
public int Count { | |
get { | |
return KeyValuePairs.Count; | |
} | |
} | |
public void CopyTo(KeyValuePair<K, V>[] array, int index) { | |
var copy = KeyValuePairs.ConvertAll<KeyValuePair<K, V>>( | |
new System.Converter<UnityKeyValuePair<K, V>, KeyValuePair<K, V>>( | |
x => { | |
return new KeyValuePair<K, V>(x.Key, (V) x.Value); | |
})); | |
copy.CopyTo(array, index); | |
} | |
IEnumerator IEnumerable.GetEnumerator() { | |
return GetEnumerator() as IEnumerator; | |
} | |
public IEnumerator<KeyValuePair<K, V>> GetEnumerator() { | |
return new UnityDictionaryEnumerator(this); | |
} | |
public ICollection<K> Keys { | |
get { | |
return KeyValuePairs.ConvertAll(new System.Converter<UnityKeyValuePair<K,V>, K>(x => { | |
return x.Key;})); | |
} | |
} | |
public ICollection<V> Values { | |
get { | |
return KeyValuePairs.ConvertAll(new System.Converter<UnityKeyValuePair<K,V>, V>(x => { | |
return x.Value;})); | |
} | |
} | |
public ICollection<KeyValuePair<K, V>> Items { | |
get { | |
return KeyValuePairs.ConvertAll<KeyValuePair<K, V>>(new System.Converter<UnityKeyValuePair<K,V>, KeyValuePair<K, V>>(x => { | |
return new KeyValuePair<K, V>(x.Key, x.Value);})); | |
} | |
} | |
public V SyncRoot { | |
get { return default(V); } | |
} | |
public bool IsFixedSize { | |
get { return false; } | |
} | |
public bool IsReadOnly { | |
get { return false; } | |
} | |
public bool IsSynchronized { | |
get { return false; } | |
} | |
internal sealed class UnityDictionaryEnumerator : IEnumerator<KeyValuePair<K, V>> { | |
// A copy of the SimpleDictionary T's key/value pairs. | |
KeyValuePair<K, V>[] items; | |
int index = -1; | |
internal UnityDictionaryEnumerator() { | |
} | |
internal UnityDictionaryEnumerator(UnityDictionary<K,V> ud) { | |
// Make a copy of the dictionary entries currently in the SimpleDictionary T. | |
items = new KeyValuePair<K, V>[ud.Count]; | |
ud.CopyTo(items, 0); | |
} | |
object IEnumerator.Current { | |
get { return Current; } | |
} | |
public KeyValuePair<K, V> Current { | |
get { | |
ValidateIndex(); | |
return items[index]; | |
} | |
} | |
// Return the current dictionary entry. | |
public KeyValuePair<K, V> Entry { | |
get { return (KeyValuePair<K, V>) Current; } | |
} | |
public void Dispose() { | |
index = -1; | |
items = null; | |
} | |
// Return the key of the current item. | |
public K Key { | |
get { | |
ValidateIndex(); | |
return items[index].Key; | |
} | |
} | |
// Return the value of the current item. | |
public V Value { | |
get { | |
ValidateIndex(); | |
return items[index].Value; | |
} | |
} | |
// Advance to the next item. | |
public bool MoveNext() { | |
if (index < items.Length - 1) { | |
index++; | |
return true; | |
} | |
return false; | |
} | |
// Validate the enumeration index and throw an exception if the index is out of range. | |
private void ValidateIndex() { | |
if (index < 0 || index >= items.Length) { | |
throw new System.InvalidOperationException("Enumerator is before or after the collection."); | |
} | |
} | |
// Reset the index to restart the enumeration. | |
public void Reset() { | |
index = -1; | |
} | |
#endregion | |
} | |
} | |
public abstract class UnityDictionary<V> : UnityDictionary<string, V> { | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment