From 73c5b8e83eb23dc98bd0386b23923c53b22a5038 Mon Sep 17 00:00:00 2001 From: neuecc Date: Fri, 18 Oct 2024 21:07:20 +0900 Subject: [PATCH] breaking changes, ISynchronizedView -> ISynchronizedView --- .../IObservableCollection.cs | 4 +-- .../ISynchronizedViewFilter.cs | 28 ++++++++++++++----- .../ObservableDictionary.Views.cs | 16 +++++------ .../ObservableHashSet.Views.cs | 16 +++++------ .../ObservableList.Views.cs | 20 ++++++------- .../ObservableQueue.Views.cs | 16 +++++------ .../ObservableRingBuffer.Views.cs | 16 +++++------ .../ObservableStack.Views.cs | 16 +++++------ .../SynchronizedViewChangedEventArgs.cs | 26 +++++++++++------ .../SynchronizedViewList.cs | 2 +- 10 files changed, 92 insertions(+), 68 deletions(-) diff --git a/src/ObservableCollections/IObservableCollection.cs b/src/ObservableCollections/IObservableCollection.cs index 8dd232a..757c1d4 100644 --- a/src/ObservableCollections/IObservableCollection.cs +++ b/src/ObservableCollections/IObservableCollection.cs @@ -35,7 +35,7 @@ public enum RejectedViewChangedAction public interface ISynchronizedView : IReadOnlyCollection, IDisposable { object SyncRoot { get; } - ISynchronizedViewFilter Filter { get; } + ISynchronizedViewFilter Filter { get; } IEnumerable<(T Value, TView View)> Filtered { get; } IEnumerable<(T Value, TView View)> Unfiltered { get; } int UnfilteredCount { get; } @@ -44,7 +44,7 @@ public interface ISynchronizedView : IReadOnlyCollection, IDisp event Action? RejectedViewChanged; event Action? CollectionStateChanged; - void AttachFilter(ISynchronizedViewFilter filter); + void AttachFilter(ISynchronizedViewFilter filter); void ResetFilter(); ISynchronizedViewList ToViewList(); NotifyCollectionChangedSynchronizedViewList ToNotifyCollectionChanged(); diff --git a/src/ObservableCollections/ISynchronizedViewFilter.cs b/src/ObservableCollections/ISynchronizedViewFilter.cs index de267e6..97ee183 100644 --- a/src/ObservableCollections/ISynchronizedViewFilter.cs +++ b/src/ObservableCollections/ISynchronizedViewFilter.cs @@ -1,24 +1,38 @@ using System; -using System.Collections.Specialized; namespace ObservableCollections { + // Obsolete... + [Obsolete("this interface is obsoleted. Use ISynchronizedViewFilter instead.")] public interface ISynchronizedViewFilter { bool IsMatch(T value); } - public class SynchronizedViewFilter(Func isMatch) : ISynchronizedViewFilter + public interface ISynchronizedViewFilter { - public static readonly ISynchronizedViewFilter Null = new NullViewFilter(); + bool IsMatch(T value, TView view); + } - public bool IsMatch(T value) => isMatch(value); + internal class SynchronizedViewValueOnlyFilter(Func isMatch) : ISynchronizedViewFilter + { + public bool IsMatch(T value, TView view) => isMatch(value); - class NullViewFilter : ISynchronizedViewFilter + class NullViewFilter : ISynchronizedViewFilter { - public bool IsMatch(T value) => true; + public bool IsMatch(T value, TView view) => true; } } - + public class SynchronizedViewFilter(Func isMatch) : ISynchronizedViewFilter + { + public static readonly ISynchronizedViewFilter Null = new NullViewFilter(); + + public bool IsMatch(T value, TView view) => isMatch(value, view); + + class NullViewFilter : ISynchronizedViewFilter + { + public bool IsMatch(T value, TView view) => true; + } + } } diff --git a/src/ObservableCollections/ObservableDictionary.Views.cs b/src/ObservableCollections/ObservableDictionary.Views.cs index 9ee370c..4c0d450 100644 --- a/src/ObservableCollections/ObservableDictionary.Views.cs +++ b/src/ObservableCollections/ObservableDictionary.Views.cs @@ -19,7 +19,7 @@ class View : ISynchronizedView, TView> { readonly ObservableDictionary source; readonly Func, TView> selector; - ISynchronizedViewFilter> filter; + ISynchronizedViewFilter, TView> filter; readonly Dictionary dict; int filteredCount; @@ -27,7 +27,7 @@ public View(ObservableDictionary source, Func>.Null; + this.filter = SynchronizedViewFilter, TView>.Null; this.SyncRoot = new object(); lock (source.SyncRoot) { @@ -42,7 +42,7 @@ public View(ObservableDictionary source, Func? RejectedViewChanged; public event Action? CollectionStateChanged; - public ISynchronizedViewFilter> Filter + public ISynchronizedViewFilter, TView> Filter { get { lock (SyncRoot) return filter; } } @@ -74,7 +74,7 @@ public void Dispose() this.source.CollectionChanged -= SourceCollectionChanged; } - public void AttachFilter(ISynchronizedViewFilter> filter) + public void AttachFilter(ISynchronizedViewFilter, TView> filter) { if (filter.IsNullFilter()) { @@ -89,7 +89,7 @@ public void AttachFilter(ISynchronizedViewFilter> fil foreach (var v in dict) { var value = new KeyValuePair(v.Key, v.Value.Item1); - if (filter.IsMatch(value)) + if (filter.IsMatch(value, v.Value.Item2)) { filteredCount++; } @@ -103,7 +103,7 @@ public void ResetFilter() { lock (SyncRoot) { - this.filter = SynchronizedViewFilter>.Null; + this.filter = SynchronizedViewFilter, TView>.Null; this.filteredCount = dict.Count; ViewChanged?.Invoke(new SynchronizedViewChangedEventArgs, TView>(NotifyCollectionChangedAction.Reset, true)); } @@ -131,7 +131,7 @@ public IEnumerator GetEnumerator() foreach (var item in dict) { var v = (new KeyValuePair(item.Key, item.Value.Item1), item.Value.Item2); - if (filter.IsMatch(v.Item1)) + if (filter.IsMatch(v)) { yield return v.Item2; } @@ -150,7 +150,7 @@ public IEnumerator GetEnumerator() foreach (var item in dict) { var v = (new KeyValuePair(item.Key, item.Value.Item1), item.Value.Item2); - if (filter.IsMatch(v.Item1)) + if (filter.IsMatch(v)) { yield return v; } diff --git a/src/ObservableCollections/ObservableHashSet.Views.cs b/src/ObservableCollections/ObservableHashSet.Views.cs index b355eaa..42b0500 100644 --- a/src/ObservableCollections/ObservableHashSet.Views.cs +++ b/src/ObservableCollections/ObservableHashSet.Views.cs @@ -17,7 +17,7 @@ public ISynchronizedView CreateView(Func transform) sealed class View : ISynchronizedView { - public ISynchronizedViewFilter Filter + public ISynchronizedViewFilter Filter { get { lock (SyncRoot) return filter; } } @@ -27,7 +27,7 @@ public ISynchronizedViewFilter Filter readonly Dictionary dict; int filteredCount; - ISynchronizedViewFilter filter; + ISynchronizedViewFilter filter; public event NotifyViewChangedEventHandler? ViewChanged; public event Action? RejectedViewChanged; @@ -39,7 +39,7 @@ public View(ObservableHashSet source, Func selector) { this.source = source; this.selector = selector; - this.filter = SynchronizedViewFilter.Null; + this.filter = SynchronizedViewFilter.Null; this.SyncRoot = new object(); lock (source.SyncRoot) { @@ -71,7 +71,7 @@ public int UnfilteredCount } } - public void AttachFilter(ISynchronizedViewFilter filter) + public void AttachFilter(ISynchronizedViewFilter filter) { if (filter.IsNullFilter()) { @@ -85,7 +85,7 @@ public void AttachFilter(ISynchronizedViewFilter filter) this.filteredCount = 0; foreach (var (_, (value, view)) in dict) { - if (filter.IsMatch(value)) + if (filter.IsMatch(value, view)) { filteredCount++; } @@ -98,7 +98,7 @@ public void ResetFilter() { lock (SyncRoot) { - this.filter = SynchronizedViewFilter.Null; + this.filter = SynchronizedViewFilter.Null; this.filteredCount = dict.Count; ViewChanged?.Invoke(new SynchronizedViewChangedEventArgs(NotifyCollectionChangedAction.Reset, true)); } @@ -125,7 +125,7 @@ public IEnumerator GetEnumerator() { foreach (var item in dict) { - if (filter.IsMatch(item.Value.Item1)) + if (filter.IsMatch(item.Value)) { yield return item.Value.Item2; } @@ -143,7 +143,7 @@ public IEnumerator GetEnumerator() { foreach (var item in dict) { - if (filter.IsMatch(item.Value.Item1)) + if (filter.IsMatch(item.Value)) { yield return item.Value; } diff --git a/src/ObservableCollections/ObservableList.Views.cs b/src/ObservableCollections/ObservableList.Views.cs index e3b9498..c63f074 100644 --- a/src/ObservableCollections/ObservableList.Views.cs +++ b/src/ObservableCollections/ObservableList.Views.cs @@ -48,7 +48,7 @@ public NotifyCollectionChangedSynchronizedViewList ToWritableNotifyCollec internal sealed class View : ISynchronizedView, IWritableSynchronizedView { - public ISynchronizedViewFilter Filter + public ISynchronizedViewFilter Filter { get { @@ -61,7 +61,7 @@ public ISynchronizedViewFilter Filter internal readonly List<(T, TView)> list; // unsafe, be careful to use int filteredCount; - ISynchronizedViewFilter filter; + ISynchronizedViewFilter filter; public event NotifyViewChangedEventHandler? ViewChanged; public event Action? RejectedViewChanged; @@ -73,7 +73,7 @@ public View(ObservableList source, Func selector) { this.source = source; this.selector = selector; - this.filter = SynchronizedViewFilter.Null; + this.filter = SynchronizedViewFilter.Null; this.SyncRoot = new object(); lock (source.SyncRoot) { @@ -105,7 +105,7 @@ public int UnfilteredCount } } - public void AttachFilter(ISynchronizedViewFilter filter) + public void AttachFilter(ISynchronizedViewFilter filter) { if (filter.IsNullFilter()) { @@ -119,7 +119,7 @@ public void AttachFilter(ISynchronizedViewFilter filter) this.filteredCount = 0; for (var i = 0; i < list.Count; i++) { - if (filter.IsMatch(list[i].Item1)) + if (filter.IsMatch(list[i])) { filteredCount++; } @@ -133,7 +133,7 @@ public void ResetFilter() { lock (SyncRoot) { - this.filter = SynchronizedViewFilter.Null; + this.filter = SynchronizedViewFilter.Null; this.filteredCount = list.Count; ViewChanged?.Invoke(new SynchronizedViewChangedEventArgs(NotifyCollectionChangedAction.Reset, true)); } @@ -160,7 +160,7 @@ public IEnumerator GetEnumerator() { foreach (var item in list) { - if (filter.IsMatch(item.Item1)) + if (filter.IsMatch(item)) { yield return item.Item2; } @@ -178,7 +178,7 @@ public IEnumerator GetEnumerator() { foreach (var item in list) { - if (filter.IsMatch(item.Item1)) + if (filter.IsMatch(item)) { yield return item; } @@ -235,7 +235,7 @@ private void SourceCollectionChanged(in NotifyCollectionChangedEventArgs e) var view = selector(item); views.Span[i] = view; valueViews.Span[i] = (item, view); - var isMatch = matches.Span[i] = Filter.IsMatch(item); + var isMatch = matches.Span[i] = Filter.IsMatch(item, view); if (isMatch) { filteredCount++; // increment in this process @@ -271,7 +271,7 @@ private void SourceCollectionChanged(in NotifyCollectionChangedEventArgs e) var item = list[i]; values.Span[j] = item.Item1; views.Span[j] = item.Item2; - var isMatch = matches.Span[j] = Filter.IsMatch(item.Item1); + var isMatch = matches.Span[j] = Filter.IsMatch(item); if (isMatch) { filteredCount--; // decrement in this process diff --git a/src/ObservableCollections/ObservableQueue.Views.cs b/src/ObservableCollections/ObservableQueue.Views.cs index b86af9d..55d0184 100644 --- a/src/ObservableCollections/ObservableQueue.Views.cs +++ b/src/ObservableCollections/ObservableQueue.Views.cs @@ -22,7 +22,7 @@ class View : ISynchronizedView protected readonly Queue<(T, TView)> queue; int filteredCount; - ISynchronizedViewFilter filter; + ISynchronizedViewFilter filter; public event NotifyViewChangedEventHandler? ViewChanged; public event Action? RejectedViewChanged; @@ -30,7 +30,7 @@ class View : ISynchronizedView public object SyncRoot { get; } - public ISynchronizedViewFilter Filter + public ISynchronizedViewFilter Filter { get { lock (SyncRoot) return filter; } } @@ -39,7 +39,7 @@ public View(ObservableQueue source, Func selector) { this.source = source; this.selector = selector; - this.filter = SynchronizedViewFilter.Null; + this.filter = SynchronizedViewFilter.Null; this.SyncRoot = new object(); lock (source.SyncRoot) { @@ -71,7 +71,7 @@ public int UnfilteredCount } } - public void AttachFilter(ISynchronizedViewFilter filter) + public void AttachFilter(ISynchronizedViewFilter filter) { if (filter.IsNullFilter()) { @@ -85,7 +85,7 @@ public void AttachFilter(ISynchronizedViewFilter filter) this.filteredCount = 0; foreach (var (value, view) in queue) { - if (filter.IsMatch(value)) + if (filter.IsMatch(value, view)) { filteredCount++; } @@ -98,7 +98,7 @@ public void ResetFilter() { lock (SyncRoot) { - this.filter = SynchronizedViewFilter.Null; + this.filter = SynchronizedViewFilter.Null; this.filteredCount = queue.Count; ViewChanged?.Invoke(new SynchronizedViewChangedEventArgs(NotifyCollectionChangedAction.Reset, true)); } @@ -125,7 +125,7 @@ public IEnumerator GetEnumerator() { foreach (var item in queue) { - if (filter.IsMatch(item.Item1)) + if (filter.IsMatch(item)) { yield return item.Item2; } @@ -143,7 +143,7 @@ public IEnumerator GetEnumerator() { foreach (var item in queue) { - if (filter.IsMatch(item.Item1)) + if (filter.IsMatch(item)) { yield return item; } diff --git a/src/ObservableCollections/ObservableRingBuffer.Views.cs b/src/ObservableCollections/ObservableRingBuffer.Views.cs index 7cf58bd..269c849 100644 --- a/src/ObservableCollections/ObservableRingBuffer.Views.cs +++ b/src/ObservableCollections/ObservableRingBuffer.Views.cs @@ -18,7 +18,7 @@ public ISynchronizedView CreateView(Func transform) // used with ObservableFixedSizeRingBuffer internal sealed class View : ISynchronizedView { - public ISynchronizedViewFilter Filter + public ISynchronizedViewFilter Filter { get { lock (SyncRoot) return filter; } } @@ -28,7 +28,7 @@ public ISynchronizedViewFilter Filter readonly RingBuffer<(T, TView)> ringBuffer; int filteredCount; - ISynchronizedViewFilter filter; + ISynchronizedViewFilter filter; public event NotifyViewChangedEventHandler? ViewChanged; public event Action? RejectedViewChanged; @@ -40,7 +40,7 @@ public View(IObservableCollection source, Func selector) { this.source = source; this.selector = selector; - this.filter = SynchronizedViewFilter.Null; + this.filter = SynchronizedViewFilter.Null; this.SyncRoot = new object(); lock (source.SyncRoot) { @@ -72,7 +72,7 @@ public int UnfilteredCount } } - public void AttachFilter(ISynchronizedViewFilter filter) + public void AttachFilter(ISynchronizedViewFilter filter) { if (filter.IsNullFilter()) { @@ -87,7 +87,7 @@ public void AttachFilter(ISynchronizedViewFilter filter) for (var i = 0; i < ringBuffer.Count; i++) { var (value, view) = ringBuffer[i]; - if (filter.IsMatch(value)) + if (filter.IsMatch(value, view)) { filteredCount++; } @@ -100,7 +100,7 @@ public void ResetFilter() { lock (SyncRoot) { - this.filter = SynchronizedViewFilter.Null; + this.filter = SynchronizedViewFilter.Null; this.filteredCount = ringBuffer.Count; ViewChanged?.Invoke(new SynchronizedViewChangedEventArgs(NotifyCollectionChangedAction.Reset, true)); } @@ -133,7 +133,7 @@ public IEnumerator GetEnumerator() { foreach (var item in ringBuffer) { - if (filter.IsMatch(item.Item1)) + if (filter.IsMatch(item)) { yield return item.Item2; } @@ -151,7 +151,7 @@ public IEnumerator GetEnumerator() { foreach (var item in ringBuffer) { - if (filter.IsMatch(item.Item1)) + if (filter.IsMatch(item)) { yield return item; } diff --git a/src/ObservableCollections/ObservableStack.Views.cs b/src/ObservableCollections/ObservableStack.Views.cs index b6206e4..9d6c370 100644 --- a/src/ObservableCollections/ObservableStack.Views.cs +++ b/src/ObservableCollections/ObservableStack.Views.cs @@ -21,7 +21,7 @@ class View : ISynchronizedView protected readonly Stack<(T, TView)> stack; int filteredCount; - ISynchronizedViewFilter filter; + ISynchronizedViewFilter filter; public event NotifyViewChangedEventHandler? ViewChanged; public event Action? RejectedViewChanged; @@ -29,7 +29,7 @@ class View : ISynchronizedView public object SyncRoot { get; } - public ISynchronizedViewFilter Filter + public ISynchronizedViewFilter Filter { get { lock (SyncRoot) return filter; } } @@ -38,7 +38,7 @@ public View(ObservableStack source, Func selector) { this.source = source; this.selector = selector; - this.filter = SynchronizedViewFilter.Null; + this.filter = SynchronizedViewFilter.Null; this.SyncRoot = new object(); lock (source.SyncRoot) { @@ -70,7 +70,7 @@ public int UnfilteredCount } } - public void AttachFilter(ISynchronizedViewFilter filter) + public void AttachFilter(ISynchronizedViewFilter filter) { if (filter.IsNullFilter()) { @@ -84,7 +84,7 @@ public void AttachFilter(ISynchronizedViewFilter filter) this.filteredCount = 0; foreach (var (value, view) in stack) { - if (filter.IsMatch(value)) + if (filter.IsMatch(value, view)) { filteredCount++; } @@ -97,7 +97,7 @@ public void ResetFilter() { lock (SyncRoot) { - this.filter = SynchronizedViewFilter.Null; + this.filter = SynchronizedViewFilter.Null; this.filteredCount = stack.Count; ViewChanged?.Invoke(new SynchronizedViewChangedEventArgs(NotifyCollectionChangedAction.Reset, true)); } @@ -130,7 +130,7 @@ public IEnumerator GetEnumerator() { foreach (var item in stack) { - if (filter.IsMatch(item.Item1)) + if (filter.IsMatch(item)) { yield return item.Item2; } @@ -148,7 +148,7 @@ public IEnumerator GetEnumerator() { foreach (var item in stack) { - if (filter.IsMatch(item.Item1)) + if (filter.IsMatch(item)) { yield return item; } diff --git a/src/ObservableCollections/SynchronizedViewChangedEventArgs.cs b/src/ObservableCollections/SynchronizedViewChangedEventArgs.cs index a36cb43..0eb7cef 100644 --- a/src/ObservableCollections/SynchronizedViewChangedEventArgs.cs +++ b/src/ObservableCollections/SynchronizedViewChangedEventArgs.cs @@ -86,12 +86,22 @@ public static class SynchronizedViewExtensions { public static void AttachFilter(this ISynchronizedView source, Func filter) { - source.AttachFilter(new SynchronizedViewFilter(filter)); + source.AttachFilter(new SynchronizedViewValueOnlyFilter(filter)); } - public static bool IsNullFilter(this ISynchronizedViewFilter filter) + public static void AttachFilter(this ISynchronizedView source, Func filter) { - return filter == SynchronizedViewFilter.Null; + source.AttachFilter(new SynchronizedViewFilter(filter)); + } + + public static bool IsNullFilter(this ISynchronizedViewFilter filter) + { + return filter == SynchronizedViewFilter.Null; + } + + internal static bool IsMatch(this ISynchronizedViewFilter filter, (T, TView) item) + { + return filter.IsMatch(item.Item1, item.Item2); } internal static void InvokeOnAdd(this ISynchronizedView collection, ref int filteredCount, NotifyViewChangedEventHandler? ev, Action? ev2, (T value, TView view) value, int index) @@ -101,7 +111,7 @@ internal static void InvokeOnAdd(this ISynchronizedView coll internal static void InvokeOnAdd(this ISynchronizedView collection, ref int filteredCount, NotifyViewChangedEventHandler? ev, Action? ev2, T value, TView view, int index) { - var isMatch = collection.Filter.IsMatch(value); + var isMatch = collection.Filter.IsMatch(value, view); if (isMatch) { filteredCount++; @@ -144,7 +154,7 @@ internal static void InvokeOnRemove(this ISynchronizedView c internal static void InvokeOnRemove(this ISynchronizedView collection, ref int filteredCount, NotifyViewChangedEventHandler? ev, Action? ev2, T value, TView view, int oldIndex) { - var isMatch = collection.Filter.IsMatch(value); + var isMatch = collection.Filter.IsMatch(value, view); if (isMatch) { filteredCount--; @@ -188,7 +198,7 @@ internal static void InvokeOnMove(this ISynchronizedView col internal static void InvokeOnMove(this ISynchronizedView collection, ref int filteredCount, NotifyViewChangedEventHandler? ev, Action? ev2, T value, TView view, int index, int oldIndex) { // move does not changes filtered-count - var isMatch = collection.Filter.IsMatch(value); + var isMatch = collection.Filter.IsMatch(value, view); if (isMatch) { ev?.Invoke(new SynchronizedViewChangedEventArgs(NotifyCollectionChangedAction.Move, true, newItem: (value, view), newStartingIndex: index, oldStartingIndex: oldIndex)); @@ -206,8 +216,8 @@ internal static void InvokeOnReplace(this ISynchronizedView internal static void InvokeOnReplace(this ISynchronizedView collection, ref int filteredCount, NotifyViewChangedEventHandler? ev, T value, TView view, T oldValue, TView oldView, int index, int oldIndex = -1) { - var oldMatched = collection.Filter.IsMatch(oldValue); - var newMatched = collection.Filter.IsMatch(value); + var oldMatched = collection.Filter.IsMatch(oldValue, oldView); + var newMatched = collection.Filter.IsMatch(value, view); var bothMatched = oldMatched && newMatched; if (bothMatched) diff --git a/src/ObservableCollections/SynchronizedViewList.cs b/src/ObservableCollections/SynchronizedViewList.cs index c936b2c..8b146a1 100644 --- a/src/ObservableCollections/SynchronizedViewList.cs +++ b/src/ObservableCollections/SynchronizedViewList.cs @@ -54,7 +54,7 @@ public FiltableSynchronizedViewList(ISynchronizedView parent, bool isS { foreach (var item in parent.Unfiltered) // use Unfiltered { - if (filter.IsMatch(item.Value)) + if (filter.IsMatch(item)) { yield return (index, item.View); }