diff --git a/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/Internal/FreezedView.cs b/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/Internal/FreezedView.cs index 1c5f909..710428c 100644 --- a/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/Internal/FreezedView.cs +++ b/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/Internal/FreezedView.cs @@ -67,13 +67,28 @@ namespace ObservableCollections.Internal public IEnumerator<(T, TView)> GetEnumerator() { - if (!reverse) + lock (SyncRoot) { - return new SynchronizedViewEnumerator(SyncRoot, list.GetEnumerator(), filter); - } - else - { - return new SynchronizedViewEnumerator(SyncRoot, list.AsEnumerable().Reverse().GetEnumerator(), filter); + if (!reverse) + { + foreach (var item in list) + { + if (filter.IsMatch(item.Item1, item.Item2)) + { + yield return item; + } + } + } + else + { + foreach (var item in list.AsEnumerable().Reverse()) + { + if (filter.IsMatch(item.Item1, item.Item2)) + { + yield return item; + } + } + } } } @@ -147,7 +162,16 @@ namespace ObservableCollections.Internal public IEnumerator<(T, TView)> GetEnumerator() { - return new SynchronizedViewEnumerator(SyncRoot, array.AsEnumerable().GetEnumerator(), filter); + lock (SyncRoot) + { + foreach (var item in array) + { + if (filter.IsMatch(item.Item1, item.Item2)) + { + yield return item; + } + } + } } IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); diff --git a/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/Internal/SortedView.cs b/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/Internal/SortedView.cs index 1d4a0c0..d0ca75c 100644 --- a/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/Internal/SortedView.cs +++ b/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/Internal/SortedView.cs @@ -88,7 +88,16 @@ namespace ObservableCollections.Internal public IEnumerator<(T, TView)> GetEnumerator() { - return new SynchronizedViewEnumerator(SyncRoot, dict.Select(x => x.Value).GetEnumerator(), filter); + lock (SyncRoot) + { + foreach (var item in dict) + { + if (filter.IsMatch(item.Value.Value, item.Value.View)) + { + yield return item.Value; + } + } + } } IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); diff --git a/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/Internal/SortedViewViewComparer.cs b/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/Internal/SortedViewViewComparer.cs index 105edb6..c543490 100644 --- a/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/Internal/SortedViewViewComparer.cs +++ b/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/Internal/SortedViewViewComparer.cs @@ -13,7 +13,7 @@ namespace ObservableCollections.Internal readonly Func transform; readonly Func identitySelector; readonly Dictionary viewMap; // view-map needs to use in remove. - readonly SortedDictionary<(TView View, TKey Key), (T Value, TView View)> list; + readonly SortedDictionary<(TView View, TKey Key), (T Value, TView View)> dict; ISynchronizedViewFilter filter; @@ -39,7 +39,7 @@ namespace ObservableCollections.Internal dict.Add((view, id), (value, view)); viewMap.Add(id, view); } - this.list = dict; + this.dict = dict; this.source.CollectionChanged += SourceCollectionChanged; } } @@ -50,7 +50,7 @@ namespace ObservableCollections.Internal { lock (SyncRoot) { - return list.Count; + return dict.Count; } } } @@ -60,7 +60,7 @@ namespace ObservableCollections.Internal lock (SyncRoot) { this.filter = filter; - foreach (var (_, (value, view)) in list) + foreach (var (_, (value, view)) in dict) { filter.InvokeOnAttach(value, view); } @@ -74,7 +74,7 @@ namespace ObservableCollections.Internal this.filter = SynchronizedViewFilter.Null; if (resetAction != null) { - foreach (var (_, (value, view)) in list) + foreach (var (_, (value, view)) in dict) { resetAction(value, view); } @@ -92,7 +92,17 @@ namespace ObservableCollections.Internal public IEnumerator<(T, TView)> GetEnumerator() { - return new SynchronizedViewEnumerator(SyncRoot, list.Select(x => x.Value).GetEnumerator(), filter); + + lock (SyncRoot) + { + foreach (var item in dict) + { + if (filter.IsMatch(item.Value.Value, item.Value.View)) + { + yield return item.Value; + } + } + } } IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); @@ -116,7 +126,7 @@ namespace ObservableCollections.Internal var value = e.NewItem; var view = transform(value); var id = identitySelector(value); - list.Add((view, id), (value, view)); + dict.Add((view, id), (value, view)); viewMap.Add(id, view); filter.InvokeOnAdd(value, view); } @@ -126,7 +136,7 @@ namespace ObservableCollections.Internal { var view = transform(value); var id = identitySelector(value); - list.Add((view, id), (value, view)); + dict.Add((view, id), (value, view)); viewMap.Add(id, view); filter.InvokeOnAdd(value, view); } @@ -141,7 +151,7 @@ namespace ObservableCollections.Internal var id = identitySelector(value); if (viewMap.Remove(id, out var view)) { - list.Remove((view, id), out var v); + dict.Remove((view, id), out var v); filter.InvokeOnRemove(v); } } @@ -152,7 +162,7 @@ namespace ObservableCollections.Internal var id = identitySelector(value); if (viewMap.Remove(id, out var view)) { - list.Remove((view, id), out var v); + dict.Remove((view, id), out var v); filter.InvokeOnRemove(v); } } @@ -166,14 +176,14 @@ namespace ObservableCollections.Internal var oldKey = identitySelector(oldValue); if (viewMap.Remove(oldKey, out var oldView)) { - list.Remove((oldView, oldKey)); + dict.Remove((oldView, oldKey)); filter.InvokeOnRemove(oldValue, oldView); } var value = e.NewItem; var view = transform(value); var id = identitySelector(value); - list.Add((view, id), (value, view)); + dict.Add((view, id), (value, view)); viewMap.Add(id, view); filter.InvokeOnAdd(value, view); @@ -193,12 +203,12 @@ namespace ObservableCollections.Internal case NotifyCollectionChangedAction.Reset: if (!filter.IsNullFilter()) { - foreach (var item in list) + foreach (var item in dict) { filter.InvokeOnRemove(item.Value); } } - list.Clear(); + dict.Clear(); viewMap.Clear(); break; default: diff --git a/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/Internal/SynchronizedEnumerator.cs b/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/Internal/SynchronizedEnumerator.cs deleted file mode 100644 index 79948a4..0000000 --- a/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/Internal/SynchronizedEnumerator.cs +++ /dev/null @@ -1,46 +0,0 @@ -using System.Collections; -using System.Collections.Generic; -using System.Threading; - -namespace ObservableCollections.Internal -{ - internal class SynchronizedEnumerator : IEnumerator - { - bool isDisposed; - readonly object gate; - readonly bool lockTaken; - readonly IEnumerator enumerator; - - public SynchronizedEnumerator(object gate, IEnumerator enumerator) - { - this.gate = gate; - this.enumerator = enumerator; - Monitor.Enter(gate, ref lockTaken); - } - - public T Current => enumerator.Current; - - object IEnumerator.Current => Current; - public bool MoveNext() => enumerator.MoveNext(); - public void Reset() => enumerator.Reset(); - - public void Dispose() - { - if (!isDisposed) - { - isDisposed = true; - try - { - enumerator.Dispose(); - } - finally - { - if (lockTaken) - { - Monitor.Exit(gate); - } - } - } - } - } -} diff --git a/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/Internal/SynchronizedEnumerator.cs.meta b/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/Internal/SynchronizedEnumerator.cs.meta deleted file mode 100644 index edc4c63..0000000 --- a/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/Internal/SynchronizedEnumerator.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 08405416bc7c7e04e9bcaa4fa13c875f -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/Internal/SynchronizedViewEnumerator.cs b/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/Internal/SynchronizedViewEnumerator.cs deleted file mode 100644 index fe0072e..0000000 --- a/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/Internal/SynchronizedViewEnumerator.cs +++ /dev/null @@ -1,63 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Threading; - -namespace ObservableCollections.Internal -{ - internal class SynchronizedViewEnumerator : IEnumerator<(T, TView)>, IDisposable - { - bool isDisposed; - readonly bool lockTaken; - readonly object gate; - readonly IEnumerator<(T, TView)> enumerator; - readonly ISynchronizedViewFilter filter; - (T, TView) current; - - public SynchronizedViewEnumerator(object gate, IEnumerator<(T, TView)> enumerator, ISynchronizedViewFilter filter) - { - this.gate = gate; - this.enumerator = enumerator; - this.filter = filter; - this.current = default; - this.isDisposed = false; - Monitor.Enter(gate, ref lockTaken); - } - - public (T, TView) Current => current; - object IEnumerator.Current => Current; - - public bool MoveNext() - { - while (enumerator.MoveNext()) - { - current = enumerator.Current; - if (filter.IsMatch(current.Item1, current.Item2)) - { - return true; - } - } - return false; - } - public void Reset() => throw new NotSupportedException(); - - public void Dispose() - { - if (!isDisposed) - { - isDisposed = true; - try - { - enumerator.Dispose(); - } - finally - { - if (lockTaken) - { - Monitor.Exit(gate); - } - } - } - } - } -} \ No newline at end of file diff --git a/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/Internal/SynchronizedViewEnumerator.cs.meta b/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/Internal/SynchronizedViewEnumerator.cs.meta deleted file mode 100644 index f902998..0000000 --- a/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/Internal/SynchronizedViewEnumerator.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 98be7e821cfba26469f0911671fb24b6 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/ObservableDictionary.Views.cs b/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/ObservableDictionary.Views.cs index 0416c1b..37b9fa2 100644 --- a/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/ObservableDictionary.Views.cs +++ b/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/ObservableDictionary.Views.cs @@ -103,9 +103,17 @@ namespace ObservableCollections public IEnumerator<(KeyValuePair, TView)> GetEnumerator() { - return new SynchronizedViewEnumerator, TView>(SyncRoot, - dict.Select(x => (new KeyValuePair(x.Key, x.Value.Item1), x.Value.Item2)).GetEnumerator(), - filter); + lock (SyncRoot) + { + foreach (var item in dict) + { + var v = (new KeyValuePair(item.Key, item.Value.Item1), item.Value.Item2); + if (filter.IsMatch(v.Item1, v.Item2)) + { + yield return v; + } + } + } } IEnumerator IEnumerable.GetEnumerator() diff --git a/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/ObservableDictionary.cs b/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/ObservableDictionary.cs index 6740dbd..5222fd8 100644 --- a/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/ObservableDictionary.cs +++ b/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/ObservableDictionary.cs @@ -211,7 +211,13 @@ namespace ObservableCollections public IEnumerator> GetEnumerator() { - return new SynchronizedEnumerator>(SyncRoot, dictionary.GetEnumerator()); + lock (SyncRoot) + { + foreach (var item in dictionary) + { + yield return item; + } + } } IEnumerator IEnumerable.GetEnumerator() diff --git a/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/ObservableFixedSizeRingBuffer.cs b/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/ObservableFixedSizeRingBuffer.cs index f696896..02ef0b2 100644 --- a/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/ObservableFixedSizeRingBuffer.cs +++ b/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/ObservableFixedSizeRingBuffer.cs @@ -280,7 +280,13 @@ namespace ObservableCollections public IEnumerator GetEnumerator() { - return new SynchronizedEnumerator(SyncRoot, buffer.GetEnumerator()); + lock (SyncRoot) + { + foreach (var item in buffer) + { + yield return item; + } + } } IEnumerator IEnumerable.GetEnumerator() diff --git a/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/ObservableHashSet.Views.cs b/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/ObservableHashSet.Views.cs index c6448dc..cc215b2 100644 --- a/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/ObservableHashSet.Views.cs +++ b/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/ObservableHashSet.Views.cs @@ -88,7 +88,16 @@ namespace ObservableCollections public IEnumerator<(T, TView)> GetEnumerator() { - return new SynchronizedViewEnumerator(SyncRoot, dict.Select(x => x.Value).GetEnumerator(), filter); + lock (SyncRoot) + { + foreach (var item in dict) + { + if (filter.IsMatch(item.Value.Item1, item.Value.Item2)) + { + yield return item.Value; + } + } + } } IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); diff --git a/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/ObservableHashSet.cs b/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/ObservableHashSet.cs index 25a78b2..328dfdb 100644 --- a/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/ObservableHashSet.cs +++ b/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/ObservableHashSet.cs @@ -247,7 +247,13 @@ namespace ObservableCollections public IEnumerator GetEnumerator() { - return new SynchronizedEnumerator(SyncRoot, set.GetEnumerator()); + lock (SyncRoot) + { + foreach (var item in set) + { + yield return item; + } + } } IEnumerator IEnumerable.GetEnumerator() diff --git a/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/ObservableList.Views.cs b/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/ObservableList.Views.cs index 5f46579..28e005c 100644 --- a/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/ObservableList.Views.cs +++ b/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/ObservableList.Views.cs @@ -90,13 +90,28 @@ namespace ObservableCollections public IEnumerator<(T, TView)> GetEnumerator() { - if (!reverse) + lock (SyncRoot) { - return new SynchronizedViewEnumerator(SyncRoot, list.GetEnumerator(), filter); - } - else - { - return new SynchronizedViewEnumerator(SyncRoot, list.AsEnumerable().Reverse().GetEnumerator(), filter); + if (!reverse) + { + foreach (var item in list) + { + if (filter.IsMatch(item.Item1, item.Item2)) + { + yield return item; + } + } + } + else + { + foreach (var item in list.AsEnumerable().Reverse()) + { + if (filter.IsMatch(item.Item1, item.Item2)) + { + yield return item; + } + } + } } } diff --git a/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/ObservableList.cs b/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/ObservableList.cs index d3e6ba5..01bb71c 100644 --- a/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/ObservableList.cs +++ b/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/ObservableList.cs @@ -139,7 +139,13 @@ namespace ObservableCollections public IEnumerator GetEnumerator() { - return new SynchronizedEnumerator(SyncRoot, list.GetEnumerator()); + lock (SyncRoot) + { + foreach (var item in list) + { + yield return item; + } + } } IEnumerator IEnumerable.GetEnumerator() diff --git a/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/ObservableQueue.Views.cs b/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/ObservableQueue.Views.cs index d1c5aa8..0939e0a 100644 --- a/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/ObservableQueue.Views.cs +++ b/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/ObservableQueue.Views.cs @@ -90,13 +90,28 @@ namespace ObservableCollections public IEnumerator<(T, TView)> GetEnumerator() { - if (!reverse) + lock (SyncRoot) { - return new SynchronizedViewEnumerator(SyncRoot, queue.GetEnumerator(), filter); - } - else - { - return new SynchronizedViewEnumerator(SyncRoot, queue.AsEnumerable().Reverse().GetEnumerator(), filter); + if (!reverse) + { + foreach (var item in queue) + { + if (filter.IsMatch(item.Item1, item.Item2)) + { + yield return item; + } + } + } + else + { + foreach (var item in queue.AsEnumerable().Reverse()) + { + if (filter.IsMatch(item.Item1, item.Item2)) + { + yield return item; + } + } + } } } diff --git a/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/ObservableQueue.cs b/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/ObservableQueue.cs index 010078e..f60d5d4 100644 --- a/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/ObservableQueue.cs +++ b/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/ObservableQueue.cs @@ -203,7 +203,13 @@ namespace ObservableCollections public IEnumerator GetEnumerator() { - return new SynchronizedEnumerator(SyncRoot, queue.GetEnumerator()); + lock (SyncRoot) + { + foreach (var item in queue) + { + yield return item; + } + } } IEnumerator IEnumerable.GetEnumerator() diff --git a/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/ObservableRingBuffer.Views.cs b/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/ObservableRingBuffer.Views.cs index 539b601..af5f857 100644 --- a/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/ObservableRingBuffer.Views.cs +++ b/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/ObservableRingBuffer.Views.cs @@ -91,13 +91,28 @@ namespace ObservableCollections public IEnumerator<(T, TView)> GetEnumerator() { - if (!reverse) + lock (SyncRoot) { - return new SynchronizedViewEnumerator(SyncRoot, ringBuffer.AsEnumerable().GetEnumerator(), filter); - } - else - { - return new SynchronizedViewEnumerator(SyncRoot, ringBuffer.AsEnumerable().Reverse().GetEnumerator(), filter); + if (!reverse) + { + foreach (var item in ringBuffer) + { + if (filter.IsMatch(item.Item1, item.Item2)) + { + yield return item; + } + } + } + else + { + foreach (var item in ringBuffer.AsEnumerable().Reverse()) + { + if (filter.IsMatch(item.Item1, item.Item2)) + { + yield return item; + } + } + } } } diff --git a/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/ObservableRingBuffer.cs b/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/ObservableRingBuffer.cs index 1301c75..4bd8c81 100644 --- a/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/ObservableRingBuffer.cs +++ b/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/ObservableRingBuffer.cs @@ -195,7 +195,13 @@ namespace ObservableCollections public IEnumerator GetEnumerator() { - return new SynchronizedEnumerator(SyncRoot, buffer.GetEnumerator()); + lock (SyncRoot) + { + foreach (var item in buffer) + { + yield return item; + } + } } IEnumerator IEnumerable.GetEnumerator() diff --git a/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/ObservableStack.Views.cs b/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/ObservableStack.Views.cs index 5e94caf..98157b6 100644 --- a/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/ObservableStack.Views.cs +++ b/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/ObservableStack.Views.cs @@ -90,13 +90,28 @@ namespace ObservableCollections public IEnumerator<(T, TView)> GetEnumerator() { - if (!reverse) + lock (SyncRoot) { - return new SynchronizedViewEnumerator(SyncRoot, stack.GetEnumerator(), filter); - } - else - { - return new SynchronizedViewEnumerator(SyncRoot, stack.AsEnumerable().Reverse().GetEnumerator(), filter); + if (!reverse) + { + foreach (var item in stack) + { + if (filter.IsMatch(item.Item1, item.Item2)) + { + yield return item; + } + } + } + else + { + foreach (var item in stack.AsEnumerable().Reverse()) + { + if (filter.IsMatch(item.Item1, item.Item2)) + { + yield return item; + } + } + } } } diff --git a/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/ObservableStack.cs b/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/ObservableStack.cs index 6f6748a..8d2dd60 100644 --- a/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/ObservableStack.cs +++ b/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/ObservableStack.cs @@ -199,7 +199,13 @@ namespace ObservableCollections public IEnumerator GetEnumerator() { - return new SynchronizedEnumerator(SyncRoot, stack.GetEnumerator()); + lock (SyncRoot) + { + foreach (var item in stack) + { + yield return item; + } + } } IEnumerator IEnumerable.GetEnumerator() diff --git a/src/ObservableCollections/Internal/FreezedView.cs b/src/ObservableCollections/Internal/FreezedView.cs index 0051081..95f7748 100644 --- a/src/ObservableCollections/Internal/FreezedView.cs +++ b/src/ObservableCollections/Internal/FreezedView.cs @@ -67,13 +67,28 @@ namespace ObservableCollections.Internal public IEnumerator<(T, TView)> GetEnumerator() { - if (!reverse) + lock (SyncRoot) { - return new SynchronizedViewEnumerator(SyncRoot, list.GetEnumerator(), filter); - } - else - { - return new SynchronizedViewEnumerator(SyncRoot, list.AsEnumerable().Reverse().GetEnumerator(), filter); + if (!reverse) + { + foreach (var item in list) + { + if (filter.IsMatch(item.Item1, item.Item2)) + { + yield return item; + } + } + } + else + { + foreach (var item in list.AsEnumerable().Reverse()) + { + if (filter.IsMatch(item.Item1, item.Item2)) + { + yield return item; + } + } + } } } @@ -147,7 +162,16 @@ namespace ObservableCollections.Internal public IEnumerator<(T, TView)> GetEnumerator() { - return new SynchronizedViewEnumerator(SyncRoot, array.AsEnumerable().GetEnumerator(), filter); + lock (SyncRoot) + { + foreach (var item in array) + { + if (filter.IsMatch(item.Item1, item.Item2)) + { + yield return item; + } + } + } } IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); diff --git a/src/ObservableCollections/Internal/SortedView.cs b/src/ObservableCollections/Internal/SortedView.cs index 7aaa6c8..9dce18a 100644 --- a/src/ObservableCollections/Internal/SortedView.cs +++ b/src/ObservableCollections/Internal/SortedView.cs @@ -88,7 +88,16 @@ namespace ObservableCollections.Internal public IEnumerator<(T, TView)> GetEnumerator() { - return new SynchronizedViewEnumerator(SyncRoot, dict.Select(x => x.Value).GetEnumerator(), filter); + lock (SyncRoot) + { + foreach (var item in dict) + { + if (filter.IsMatch(item.Value.Value, item.Value.View)) + { + yield return item.Value; + } + } + } } IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); diff --git a/src/ObservableCollections/Internal/SortedViewViewComparer.cs b/src/ObservableCollections/Internal/SortedViewViewComparer.cs index b8aad3e..3bf75b4 100644 --- a/src/ObservableCollections/Internal/SortedViewViewComparer.cs +++ b/src/ObservableCollections/Internal/SortedViewViewComparer.cs @@ -13,7 +13,7 @@ namespace ObservableCollections.Internal readonly Func transform; readonly Func identitySelector; readonly Dictionary viewMap; // view-map needs to use in remove. - readonly SortedDictionary<(TView View, TKey Key), (T Value, TView View)> list; + readonly SortedDictionary<(TView View, TKey Key), (T Value, TView View)> dict; ISynchronizedViewFilter filter; @@ -39,7 +39,7 @@ namespace ObservableCollections.Internal dict.Add((view, id), (value, view)); viewMap.Add(id, view); } - this.list = dict; + this.dict = dict; this.source.CollectionChanged += SourceCollectionChanged; } } @@ -50,7 +50,7 @@ namespace ObservableCollections.Internal { lock (SyncRoot) { - return list.Count; + return dict.Count; } } } @@ -60,7 +60,7 @@ namespace ObservableCollections.Internal lock (SyncRoot) { this.filter = filter; - foreach (var (_, (value, view)) in list) + foreach (var (_, (value, view)) in dict) { filter.InvokeOnAttach(value, view); } @@ -74,7 +74,7 @@ namespace ObservableCollections.Internal this.filter = SynchronizedViewFilter.Null; if (resetAction != null) { - foreach (var (_, (value, view)) in list) + foreach (var (_, (value, view)) in dict) { resetAction(value, view); } @@ -92,7 +92,17 @@ namespace ObservableCollections.Internal public IEnumerator<(T, TView)> GetEnumerator() { - return new SynchronizedViewEnumerator(SyncRoot, list.Select(x => x.Value).GetEnumerator(), filter); + + lock (SyncRoot) + { + foreach (var item in dict) + { + if (filter.IsMatch(item.Value.Value, item.Value.View)) + { + yield return item.Value; + } + } + } } IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); @@ -116,7 +126,7 @@ namespace ObservableCollections.Internal var value = e.NewItem; var view = transform(value); var id = identitySelector(value); - list.Add((view, id), (value, view)); + dict.Add((view, id), (value, view)); viewMap.Add(id, view); filter.InvokeOnAdd(value, view); } @@ -126,7 +136,7 @@ namespace ObservableCollections.Internal { var view = transform(value); var id = identitySelector(value); - list.Add((view, id), (value, view)); + dict.Add((view, id), (value, view)); viewMap.Add(id, view); filter.InvokeOnAdd(value, view); } @@ -141,7 +151,7 @@ namespace ObservableCollections.Internal var id = identitySelector(value); if (viewMap.Remove(id, out var view)) { - list.Remove((view, id), out var v); + dict.Remove((view, id), out var v); filter.InvokeOnRemove(v); } } @@ -152,7 +162,7 @@ namespace ObservableCollections.Internal var id = identitySelector(value); if (viewMap.Remove(id, out var view)) { - list.Remove((view, id), out var v); + dict.Remove((view, id), out var v); filter.InvokeOnRemove(v); } } @@ -166,14 +176,14 @@ namespace ObservableCollections.Internal var oldKey = identitySelector(oldValue); if (viewMap.Remove(oldKey, out var oldView)) { - list.Remove((oldView, oldKey)); + dict.Remove((oldView, oldKey)); filter.InvokeOnRemove(oldValue, oldView); } var value = e.NewItem; var view = transform(value); var id = identitySelector(value); - list.Add((view, id), (value, view)); + dict.Add((view, id), (value, view)); viewMap.Add(id, view); filter.InvokeOnAdd(value, view); @@ -193,12 +203,12 @@ namespace ObservableCollections.Internal case NotifyCollectionChangedAction.Reset: if (!filter.IsNullFilter()) { - foreach (var item in list) + foreach (var item in dict) { filter.InvokeOnRemove(item.Value); } } - list.Clear(); + dict.Clear(); viewMap.Clear(); break; default: diff --git a/src/ObservableCollections/Internal/SynchronizedViewEnumerator.cs b/src/ObservableCollections/Internal/SynchronizedViewEnumerator.cs deleted file mode 100644 index 57fd267..0000000 --- a/src/ObservableCollections/Internal/SynchronizedViewEnumerator.cs +++ /dev/null @@ -1,63 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Threading; - -namespace ObservableCollections.Internal -{ - internal class SynchronizedViewEnumerator : IEnumerator<(T, TView)>, IDisposable - { - bool isDisposed; - readonly bool lockTaken; - readonly object gate; - readonly IEnumerator<(T, TView)> enumerator; - readonly ISynchronizedViewFilter filter; - (T, TView) current; - - public SynchronizedViewEnumerator(object gate, IEnumerator<(T, TView)> enumerator, ISynchronizedViewFilter filter) - { - this.gate = gate; - this.enumerator = enumerator; - this.filter = filter; - this.current = default; - this.isDisposed = false; - Monitor.Enter(gate, ref lockTaken); - } - - public (T, TView) Current => current; - object IEnumerator.Current => Current!; - - public bool MoveNext() - { - while (enumerator.MoveNext()) - { - current = enumerator.Current; - if (filter.IsMatch(current.Item1, current.Item2)) - { - return true; - } - } - return false; - } - public void Reset() => throw new NotSupportedException(); - - public void Dispose() - { - if (!isDisposed) - { - isDisposed = true; - try - { - enumerator.Dispose(); - } - finally - { - if (lockTaken) - { - Monitor.Exit(gate); - } - } - } - } - } -} \ No newline at end of file diff --git a/src/ObservableCollections/ObservableDictionary.Views.cs b/src/ObservableCollections/ObservableDictionary.Views.cs index 2bee71e..c8c00ea 100644 --- a/src/ObservableCollections/ObservableDictionary.Views.cs +++ b/src/ObservableCollections/ObservableDictionary.Views.cs @@ -103,9 +103,17 @@ namespace ObservableCollections public IEnumerator<(KeyValuePair, TView)> GetEnumerator() { - return new SynchronizedViewEnumerator, TView>(SyncRoot, - dict.Select(x => (new KeyValuePair(x.Key, x.Value.Item1), x.Value.Item2)).GetEnumerator(), - filter); + lock (SyncRoot) + { + foreach (var item in dict) + { + var v = (new KeyValuePair(item.Key, item.Value.Item1), item.Value.Item2); + if (filter.IsMatch(v.Item1, v.Item2)) + { + yield return v; + } + } + } } IEnumerator IEnumerable.GetEnumerator() diff --git a/src/ObservableCollections/ObservableHashSet.Views.cs b/src/ObservableCollections/ObservableHashSet.Views.cs index 49450af..c054052 100644 --- a/src/ObservableCollections/ObservableHashSet.Views.cs +++ b/src/ObservableCollections/ObservableHashSet.Views.cs @@ -88,7 +88,16 @@ namespace ObservableCollections public IEnumerator<(T, TView)> GetEnumerator() { - return new SynchronizedViewEnumerator(SyncRoot, dict.Select(x => x.Value).GetEnumerator(), filter); + lock (SyncRoot) + { + foreach (var item in dict) + { + if (filter.IsMatch(item.Value.Item1, item.Value.Item2)) + { + yield return item.Value; + } + } + } } IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); diff --git a/src/ObservableCollections/ObservableHashSet.cs b/src/ObservableCollections/ObservableHashSet.cs index 5ad41c6..b409515 100644 --- a/src/ObservableCollections/ObservableHashSet.cs +++ b/src/ObservableCollections/ObservableHashSet.cs @@ -247,7 +247,13 @@ namespace ObservableCollections public IEnumerator GetEnumerator() { - return new SynchronizedEnumerator(SyncRoot, set.GetEnumerator()); + lock (SyncRoot) + { + foreach (var item in set) + { + yield return item; + } + } } IEnumerator IEnumerable.GetEnumerator() diff --git a/src/ObservableCollections/ObservableList.Views.cs b/src/ObservableCollections/ObservableList.Views.cs index 0a503b6..282c390 100644 --- a/src/ObservableCollections/ObservableList.Views.cs +++ b/src/ObservableCollections/ObservableList.Views.cs @@ -90,13 +90,28 @@ namespace ObservableCollections public IEnumerator<(T, TView)> GetEnumerator() { - if (!reverse) + lock (SyncRoot) { - return new SynchronizedViewEnumerator(SyncRoot, list.GetEnumerator(), filter); - } - else - { - return new SynchronizedViewEnumerator(SyncRoot, list.AsEnumerable().Reverse().GetEnumerator(), filter); + if (!reverse) + { + foreach (var item in list) + { + if (filter.IsMatch(item.Item1, item.Item2)) + { + yield return item; + } + } + } + else + { + foreach (var item in list.AsEnumerable().Reverse()) + { + if (filter.IsMatch(item.Item1, item.Item2)) + { + yield return item; + } + } + } } } diff --git a/src/ObservableCollections/ObservableQueue.Views.cs b/src/ObservableCollections/ObservableQueue.Views.cs index 82fc720..31db2f8 100644 --- a/src/ObservableCollections/ObservableQueue.Views.cs +++ b/src/ObservableCollections/ObservableQueue.Views.cs @@ -90,13 +90,28 @@ namespace ObservableCollections public IEnumerator<(T, TView)> GetEnumerator() { - if (!reverse) + lock (SyncRoot) { - return new SynchronizedViewEnumerator(SyncRoot, queue.GetEnumerator(), filter); - } - else - { - return new SynchronizedViewEnumerator(SyncRoot, queue.AsEnumerable().Reverse().GetEnumerator(), filter); + if (!reverse) + { + foreach (var item in queue) + { + if (filter.IsMatch(item.Item1, item.Item2)) + { + yield return item; + } + } + } + else + { + foreach (var item in queue.AsEnumerable().Reverse()) + { + if (filter.IsMatch(item.Item1, item.Item2)) + { + yield return item; + } + } + } } } diff --git a/src/ObservableCollections/ObservableRingBuffer.Views.cs b/src/ObservableCollections/ObservableRingBuffer.Views.cs index 50df81e..b20a7b4 100644 --- a/src/ObservableCollections/ObservableRingBuffer.Views.cs +++ b/src/ObservableCollections/ObservableRingBuffer.Views.cs @@ -91,13 +91,28 @@ namespace ObservableCollections public IEnumerator<(T, TView)> GetEnumerator() { - if (!reverse) + lock (SyncRoot) { - return new SynchronizedViewEnumerator(SyncRoot, ringBuffer.AsEnumerable().GetEnumerator(), filter); - } - else - { - return new SynchronizedViewEnumerator(SyncRoot, ringBuffer.AsEnumerable().Reverse().GetEnumerator(), filter); + if (!reverse) + { + foreach (var item in ringBuffer) + { + if (filter.IsMatch(item.Item1, item.Item2)) + { + yield return item; + } + } + } + else + { + foreach (var item in ringBuffer.AsEnumerable().Reverse()) + { + if (filter.IsMatch(item.Item1, item.Item2)) + { + yield return item; + } + } + } } } diff --git a/src/ObservableCollections/ObservableStack.Views.cs b/src/ObservableCollections/ObservableStack.Views.cs index 81cbf97..77ec33c 100644 --- a/src/ObservableCollections/ObservableStack.Views.cs +++ b/src/ObservableCollections/ObservableStack.Views.cs @@ -90,13 +90,28 @@ namespace ObservableCollections public IEnumerator<(T, TView)> GetEnumerator() { - if (!reverse) + lock (SyncRoot) { - return new SynchronizedViewEnumerator(SyncRoot, stack.GetEnumerator(), filter); - } - else - { - return new SynchronizedViewEnumerator(SyncRoot, stack.AsEnumerable().Reverse().GetEnumerator(), filter); + if (!reverse) + { + foreach (var item in stack) + { + if (filter.IsMatch(item.Item1, item.Item2)) + { + yield return item; + } + } + } + else + { + foreach (var item in stack.AsEnumerable().Reverse()) + { + if (filter.IsMatch(item.Item1, item.Item2)) + { + yield return item; + } + } + } } } diff --git a/src/ObservableCollections/ObservableStack.cs b/src/ObservableCollections/ObservableStack.cs index e1d56e7..1847f3d 100644 --- a/src/ObservableCollections/ObservableStack.cs +++ b/src/ObservableCollections/ObservableStack.cs @@ -199,7 +199,13 @@ namespace ObservableCollections public IEnumerator GetEnumerator() { - return new SynchronizedEnumerator(SyncRoot, stack.GetEnumerator()); + lock (SyncRoot) + { + foreach (var item in stack) + { + yield return item; + } + } } IEnumerator IEnumerable.GetEnumerator()