123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520 |
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Runtime.Serialization;
- namespace UniRx
- {
- public struct DictionaryAddEvent<TKey, TValue> : IEquatable<DictionaryAddEvent<TKey, TValue>>
- {
- public TKey Key { get; private set; }
- public TValue Value { get; private set; }
- public DictionaryAddEvent(TKey key, TValue value)
- : this()
- {
- Key = key;
- Value = value;
- }
- public override string ToString()
- {
- return string.Format("Key:{0} Value:{1}", Key, Value);
- }
- public override int GetHashCode()
- {
- return EqualityComparer<TKey>.Default.GetHashCode(Key) ^ EqualityComparer<TValue>.Default.GetHashCode(Value) << 2;
- }
- public bool Equals(DictionaryAddEvent<TKey, TValue> other)
- {
- return EqualityComparer<TKey>.Default.Equals(Key, other.Key) && EqualityComparer<TValue>.Default.Equals(Value, other.Value);
- }
- }
- public struct DictionaryRemoveEvent<TKey, TValue> : IEquatable<DictionaryRemoveEvent<TKey, TValue>>
- {
- public TKey Key { get; private set; }
- public TValue Value { get; private set; }
- public DictionaryRemoveEvent(TKey key, TValue value)
- : this()
- {
- Key = key;
- Value = value;
- }
- public override string ToString()
- {
- return string.Format("Key:{0} Value:{1}", Key, Value);
- }
- public override int GetHashCode()
- {
- return EqualityComparer<TKey>.Default.GetHashCode(Key) ^ EqualityComparer<TValue>.Default.GetHashCode(Value) << 2;
- }
- public bool Equals(DictionaryRemoveEvent<TKey, TValue> other)
- {
- return EqualityComparer<TKey>.Default.Equals(Key, other.Key) && EqualityComparer<TValue>.Default.Equals(Value, other.Value);
- }
- }
- public struct DictionaryReplaceEvent<TKey, TValue> : IEquatable<DictionaryReplaceEvent<TKey, TValue>>
- {
- public TKey Key { get; private set; }
- public TValue OldValue { get; private set; }
- public TValue NewValue { get; private set; }
- public DictionaryReplaceEvent(TKey key, TValue oldValue, TValue newValue)
- : this()
- {
- Key = key;
- OldValue = oldValue;
- NewValue = newValue;
- }
- public override string ToString()
- {
- return string.Format("Key:{0} OldValue:{1} NewValue:{2}", Key, OldValue, NewValue);
- }
- public override int GetHashCode()
- {
- return EqualityComparer<TKey>.Default.GetHashCode(Key) ^ EqualityComparer<TValue>.Default.GetHashCode(OldValue) << 2 ^ EqualityComparer<TValue>.Default.GetHashCode(NewValue) >> 2;
- }
- public bool Equals(DictionaryReplaceEvent<TKey, TValue> other)
- {
- return EqualityComparer<TKey>.Default.Equals(Key, other.Key) && EqualityComparer<TValue>.Default.Equals(OldValue, other.OldValue) && EqualityComparer<TValue>.Default.Equals(NewValue, other.NewValue);
- }
- }
- // IReadOnlyDictionary is from .NET 4.5
- public interface IReadOnlyReactiveDictionary<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>>
- {
- int Count { get; }
- TValue this[TKey index] { get; }
- bool ContainsKey(TKey key);
- bool TryGetValue(TKey key, out TValue value);
- IObservable<DictionaryAddEvent<TKey, TValue>> ObserveAdd();
- IObservable<int> ObserveCountChanged(bool notifyCurrentCount = false);
- IObservable<DictionaryRemoveEvent<TKey, TValue>> ObserveRemove();
- IObservable<DictionaryReplaceEvent<TKey, TValue>> ObserveReplace();
- IObservable<Unit> ObserveReset();
- }
- public interface IReactiveDictionary<TKey, TValue> : IReadOnlyReactiveDictionary<TKey, TValue>, IDictionary<TKey, TValue>
- {
- }
- [Serializable]
- public class ReactiveDictionary<TKey, TValue> : IReactiveDictionary<TKey, TValue>, IDictionary<TKey, TValue>, IEnumerable, ICollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>, IDictionary, IDisposable
- #if !UNITY_METRO
- , ISerializable, IDeserializationCallback
- #endif
- {
- [NonSerialized]
- bool isDisposed = false;
- #if !UniRxLibrary
- [UnityEngine.SerializeField]
- #endif
- readonly Dictionary<TKey, TValue> inner;
- public ReactiveDictionary()
- {
- inner = new Dictionary<TKey, TValue>();
- }
- public ReactiveDictionary(IEqualityComparer<TKey> comparer)
- {
- inner = new Dictionary<TKey, TValue>(comparer);
- }
- public ReactiveDictionary(Dictionary<TKey, TValue> innerDictionary)
- {
- inner = innerDictionary;
- }
- public TValue this[TKey key]
- {
- get
- {
- return inner[key];
- }
- set
- {
- TValue oldValue;
- if (TryGetValue(key, out oldValue))
- {
- inner[key] = value;
- if (dictionaryReplace != null) dictionaryReplace.OnNext(new DictionaryReplaceEvent<TKey, TValue>(key, oldValue, value));
- }
- else
- {
- inner[key] = value;
- if (dictionaryAdd != null) dictionaryAdd.OnNext(new DictionaryAddEvent<TKey, TValue>(key, value));
- if (countChanged != null) countChanged.OnNext(Count);
- }
- }
- }
- public int Count
- {
- get
- {
- return inner.Count;
- }
- }
- public Dictionary<TKey, TValue>.KeyCollection Keys
- {
- get
- {
- return inner.Keys;
- }
- }
- public Dictionary<TKey, TValue>.ValueCollection Values
- {
- get
- {
- return inner.Values;
- }
- }
- public void Add(TKey key, TValue value)
- {
- inner.Add(key, value);
- if (dictionaryAdd != null) dictionaryAdd.OnNext(new DictionaryAddEvent<TKey, TValue>(key, value));
- if (countChanged != null) countChanged.OnNext(Count);
- }
- public void Clear()
- {
- var beforeCount = Count;
- inner.Clear();
- if (collectionReset != null) collectionReset.OnNext(Unit.Default);
- if (beforeCount > 0)
- {
- if (countChanged != null) countChanged.OnNext(Count);
- }
- }
- public bool Remove(TKey key)
- {
- TValue oldValue;
- if (inner.TryGetValue(key, out oldValue))
- {
- var isSuccessRemove = inner.Remove(key);
- if (isSuccessRemove)
- {
- if (dictionaryRemove != null) dictionaryRemove.OnNext(new DictionaryRemoveEvent<TKey, TValue>(key, oldValue));
- if (countChanged != null) countChanged.OnNext(Count);
- }
- return isSuccessRemove;
- }
- else
- {
- return false;
- }
- }
- public bool ContainsKey(TKey key)
- {
- return inner.ContainsKey(key);
- }
- public bool TryGetValue(TKey key, out TValue value)
- {
- return inner.TryGetValue(key, out value);
- }
- public Dictionary<TKey, TValue>.Enumerator GetEnumerator()
- {
- return inner.GetEnumerator();
- }
- void DisposeSubject<TSubject>(ref Subject<TSubject> subject)
- {
- if (subject != null)
- {
- try
- {
- subject.OnCompleted();
- }
- finally
- {
- subject.Dispose();
- subject = null;
- }
- }
- }
- #region IDisposable Support
- private bool disposedValue = false;
- protected virtual void Dispose(bool disposing)
- {
- if (!disposedValue)
- {
- if (disposing)
- {
- DisposeSubject(ref countChanged);
- DisposeSubject(ref collectionReset);
- DisposeSubject(ref dictionaryAdd);
- DisposeSubject(ref dictionaryRemove);
- DisposeSubject(ref dictionaryReplace);
- }
- disposedValue = true;
- }
- }
- public void Dispose()
- {
- Dispose(true);
- }
- #endregion
- #region Observe
- [NonSerialized]
- Subject<int> countChanged = null;
- public IObservable<int> ObserveCountChanged(bool notifyCurrentCount = false)
- {
- if (isDisposed) return Observable.Empty<int>();
- var subject = countChanged ?? (countChanged = new Subject<int>());
- if (notifyCurrentCount)
- {
- return subject.StartWith(() => this.Count);
- }
- else
- {
- return subject;
- }
- }
- [NonSerialized]
- Subject<Unit> collectionReset = null;
- public IObservable<Unit> ObserveReset()
- {
- if (isDisposed) return Observable.Empty<Unit>();
- return collectionReset ?? (collectionReset = new Subject<Unit>());
- }
- [NonSerialized]
- Subject<DictionaryAddEvent<TKey, TValue>> dictionaryAdd = null;
- public IObservable<DictionaryAddEvent<TKey, TValue>> ObserveAdd()
- {
- if (isDisposed) return Observable.Empty<DictionaryAddEvent<TKey, TValue>>();
- return dictionaryAdd ?? (dictionaryAdd = new Subject<DictionaryAddEvent<TKey, TValue>>());
- }
- [NonSerialized]
- Subject<DictionaryRemoveEvent<TKey, TValue>> dictionaryRemove = null;
- public IObservable<DictionaryRemoveEvent<TKey, TValue>> ObserveRemove()
- {
- if (isDisposed) return Observable.Empty<DictionaryRemoveEvent<TKey, TValue>>();
- return dictionaryRemove ?? (dictionaryRemove = new Subject<DictionaryRemoveEvent<TKey, TValue>>());
- }
- [NonSerialized]
- Subject<DictionaryReplaceEvent<TKey, TValue>> dictionaryReplace = null;
- public IObservable<DictionaryReplaceEvent<TKey, TValue>> ObserveReplace()
- {
- if (isDisposed) return Observable.Empty<DictionaryReplaceEvent<TKey, TValue>>();
- return dictionaryReplace ?? (dictionaryReplace = new Subject<DictionaryReplaceEvent<TKey, TValue>>());
- }
- #endregion
- #region implement explicit
- object IDictionary.this[object key]
- {
- get
- {
- return this[(TKey)key];
- }
- set
- {
- this[(TKey)key] = (TValue)value;
- }
- }
- bool IDictionary.IsFixedSize
- {
- get
- {
- return ((IDictionary)inner).IsFixedSize;
- }
- }
- bool IDictionary.IsReadOnly
- {
- get
- {
- return ((IDictionary)inner).IsReadOnly;
- }
- }
- bool ICollection.IsSynchronized
- {
- get
- {
- return ((IDictionary)inner).IsSynchronized;
- }
- }
- ICollection IDictionary.Keys
- {
- get
- {
- return ((IDictionary)inner).Keys;
- }
- }
- object ICollection.SyncRoot
- {
- get
- {
- return ((IDictionary)inner).SyncRoot;
- }
- }
- ICollection IDictionary.Values
- {
- get
- {
- return ((IDictionary)inner).Values;
- }
- }
- bool ICollection<KeyValuePair<TKey, TValue>>.IsReadOnly
- {
- get
- {
- return ((ICollection<KeyValuePair<TKey, TValue>>)inner).IsReadOnly;
- }
- }
- ICollection<TKey> IDictionary<TKey, TValue>.Keys
- {
- get
- {
- return inner.Keys;
- }
- }
- ICollection<TValue> IDictionary<TKey, TValue>.Values
- {
- get
- {
- return inner.Values;
- }
- }
- void IDictionary.Add(object key, object value)
- {
- Add((TKey)key, (TValue)value);
- }
- bool IDictionary.Contains(object key)
- {
- return ((IDictionary)inner).Contains(key);
- }
- void ICollection.CopyTo(Array array, int index)
- {
- ((IDictionary)inner).CopyTo(array, index);
- }
- #if !UNITY_METRO
- public void GetObjectData(SerializationInfo info, StreamingContext context)
- {
- ((ISerializable)inner).GetObjectData(info, context);
- }
- public void OnDeserialization(object sender)
- {
- ((IDeserializationCallback)inner).OnDeserialization(sender);
- }
- #endif
- void IDictionary.Remove(object key)
- {
- Remove((TKey)key);
- }
- void ICollection<KeyValuePair<TKey, TValue>>.Add(KeyValuePair<TKey, TValue> item)
- {
- Add((TKey)item.Key, (TValue)item.Value);
- }
- bool ICollection<KeyValuePair<TKey, TValue>>.Contains(KeyValuePair<TKey, TValue> item)
- {
- return ((ICollection<KeyValuePair<TKey, TValue>>)inner).Contains(item);
- }
- void ICollection<KeyValuePair<TKey, TValue>>.CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
- {
- ((ICollection<KeyValuePair<TKey, TValue>>)inner).CopyTo(array, arrayIndex);
- }
- IEnumerator<KeyValuePair<TKey, TValue>> IEnumerable<KeyValuePair<TKey, TValue>>.GetEnumerator()
- {
- return ((ICollection<KeyValuePair<TKey, TValue>>)inner).GetEnumerator();
- }
- IEnumerator IEnumerable.GetEnumerator()
- {
- return inner.GetEnumerator();
- }
- bool ICollection<KeyValuePair<TKey, TValue>>.Remove(KeyValuePair<TKey, TValue> item)
- {
- TValue v;
- if (TryGetValue(item.Key, out v))
- {
- if (EqualityComparer<TValue>.Default.Equals(v, item.Value))
- {
- Remove(item.Key);
- return true;
- }
- }
- return false;
- }
- IDictionaryEnumerator IDictionary.GetEnumerator()
- {
- return ((IDictionary)inner).GetEnumerator();
- }
- #endregion
- }
- public static partial class ReactiveDictionaryExtensions
- {
- public static ReactiveDictionary<TKey, TValue> ToReactiveDictionary<TKey, TValue>(this Dictionary<TKey, TValue> dictionary)
- {
- return new ReactiveDictionary<TKey, TValue>(dictionary);
- }
- }
- }
|