Skip to content

Commit

Permalink
Change the INotifyCollectionChaneged to IE<TView> from IE<(T, View)>
Browse files Browse the repository at this point in the history
  • Loading branch information
hadashiA committed Feb 15, 2024
1 parent 43ee6ec commit 18aa9e4
Show file tree
Hide file tree
Showing 12 changed files with 109 additions and 48 deletions.
5 changes: 3 additions & 2 deletions src/ObservableCollections/IObservableCollection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,14 @@ public interface IFreezedCollection<T>
public interface ISynchronizedView<T, TView> : IReadOnlyCollection<(T Value, TView View)>, IDisposable
{
object SyncRoot { get; }
ISynchronizedViewFilter<T, TView> CurrentFilter { get; }

event NotifyCollectionChangedEventHandler<T>? RoutingCollectionChanged;
event Action<NotifyCollectionChangedAction>? CollectionStateChanged;

void AttachFilter(ISynchronizedViewFilter<T, TView> filter, bool invokeAddEventForInitialElements = false);
void ResetFilter(Action<T, TView>? resetAction);
INotifyCollectionChangedSynchronizedView<T, TView> WithINotifyCollectionChanged();
INotifyCollectionChangedSynchronizedView<TView> ToNotifyCollectionChanged();
}

public interface ISortableSynchronizedView<T, TView> : ISynchronizedView<T, TView>
Expand All @@ -44,7 +45,7 @@ public interface ISortableSynchronizedView<T, TView> : ISynchronizedView<T, TVie
//{
//}

public interface INotifyCollectionChangedSynchronizedView<T, TView> : ISynchronizedView<T, TView>, INotifyCollectionChanged, INotifyPropertyChanged
public interface INotifyCollectionChangedSynchronizedView<out TView> : IReadOnlyCollection<TView>, INotifyCollectionChanged, INotifyPropertyChanged
{
}

Expand Down
14 changes: 12 additions & 2 deletions src/ObservableCollections/Internal/FreezedView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ internal sealed class FreezedView<T, TView> : ISynchronizedView<T, TView>

ISynchronizedViewFilter<T, TView> filter;

public ISynchronizedViewFilter<T, TView> CurrentFilter
{
get { lock (SyncRoot) return filter; }
}

public event Action<NotifyCollectionChangedAction>? CollectionStateChanged;
public event NotifyCollectionChangedEventHandler<T>? RoutingCollectionChanged;

Expand Down Expand Up @@ -107,7 +112,7 @@ public void Dispose()

}

public INotifyCollectionChangedSynchronizedView<T, TView> WithINotifyCollectionChanged()
public INotifyCollectionChangedSynchronizedView<TView> ToNotifyCollectionChanged()
{
return new NotifyCollectionChangedSynchronizedView<T, TView>(this);
}
Expand All @@ -119,6 +124,11 @@ internal sealed class FreezedSortableView<T, TView> : ISortableSynchronizedView<

ISynchronizedViewFilter<T, TView> filter;

public ISynchronizedViewFilter<T, TView> CurrentFilter
{
get { lock (SyncRoot) return filter; }
}

public event Action<NotifyCollectionChangedAction>? CollectionStateChanged;
public event NotifyCollectionChangedEventHandler<T>? RoutingCollectionChanged;

Expand Down Expand Up @@ -206,7 +216,7 @@ public void Sort(IComparer<TView> viewComparer)
Array.Sort(array, new TViewComparer(viewComparer));
}

public INotifyCollectionChangedSynchronizedView<T, TView> WithINotifyCollectionChanged()
public INotifyCollectionChangedSynchronizedView<TView> ToNotifyCollectionChanged()
{
return new NotifyCollectionChangedSynchronizedView<T, TView>(this);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,38 +6,20 @@

namespace ObservableCollections.Internal
{
internal class NotifyCollectionChangedSynchronizedView<T, TView> : INotifyCollectionChangedSynchronizedView<T, TView>
internal class NotifyCollectionChangedSynchronizedView<T, TView> :
INotifyCollectionChangedSynchronizedView<TView>,
ISynchronizedViewFilter<T, TView>
{
static readonly PropertyChangedEventArgs CountPropertyChangedEventArgs = new("Count");

readonly ISynchronizedView<T, TView> parent;
static readonly PropertyChangedEventArgs CountPropertyChangedEventArgs = new PropertyChangedEventArgs("Count");

public NotifyCollectionChangedSynchronizedView(ISynchronizedView<T, TView> parent)
{
this.parent = parent;
this.parent.RoutingCollectionChanged += Parent_RoutingCollectionChanged;
parent.AttachFilter(this);
}

private void Parent_RoutingCollectionChanged(in NotifyCollectionChangedEventArgs<T> e)
{
CollectionChanged?.Invoke(this, e.ToStandardEventArgs());

switch (e.Action)
{
// add, remove, reset will change the count.
case NotifyCollectionChangedAction.Add:
case NotifyCollectionChangedAction.Remove:
case NotifyCollectionChangedAction.Reset:
PropertyChanged?.Invoke(this, CountPropertyChangedEventArgs);
break;
case NotifyCollectionChangedAction.Replace:
case NotifyCollectionChangedAction.Move:
default:
break;
}
}

public object SyncRoot => parent.SyncRoot;

public int Count => parent.Count;

public event NotifyCollectionChangedEventHandler? CollectionChanged;
Expand All @@ -55,16 +37,43 @@ public event NotifyCollectionChangedEventHandler<T>? RoutingCollectionChanged
remove { parent.RoutingCollectionChanged -= value; }
}

public void AttachFilter(ISynchronizedViewFilter<T, TView> filter, bool invokeAddEventForCurrentElements = false) => parent.AttachFilter(filter, invokeAddEventForCurrentElements);
public void ResetFilter(Action<T, TView>? resetAction) => parent.ResetFilter(resetAction);
public INotifyCollectionChangedSynchronizedView<T, TView> WithINotifyCollectionChanged() => this;
public void Dispose()
{
this.parent.RoutingCollectionChanged -= Parent_RoutingCollectionChanged;
parent.Dispose();
}

public IEnumerator<(T, TView)> GetEnumerator() => parent.GetEnumerator();
public IEnumerator<TView> GetEnumerator()
{
foreach (var (value, view) in parent)
{
yield return view;
}
}

IEnumerator IEnumerable.GetEnumerator() => parent.GetEnumerator();

public bool IsMatch(T value, TView view) => parent.CurrentFilter.IsMatch(value, view);
public void WhenTrue(T value, TView view) => parent.CurrentFilter.WhenTrue(value, view);
public void WhenFalse(T value, TView view) => parent.CurrentFilter.WhenFalse(value, view);

public void OnCollectionChanged(ChangedKind changedKind, T value, TView view, in NotifyCollectionChangedEventArgs<T> eventArgs)
{
parent.CurrentFilter.OnCollectionChanged(changedKind, value, view, in eventArgs);

switch (changedKind)
{
case ChangedKind.Add:
CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, view, eventArgs.NewStartingIndex));
return;
case ChangedKind.Remove:
CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, view, eventArgs.OldStartingIndex));
break;
case ChangedKind.Move:
CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Move, view, eventArgs.NewStartingIndex, eventArgs.OldStartingIndex));
break;
default:
throw new ArgumentOutOfRangeException(nameof(changedKind), changedKind, null);
}
}
}
}
10 changes: 7 additions & 3 deletions src/ObservableCollections/Internal/SortedView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,17 @@
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;

namespace ObservableCollections.Internal
{
internal class SortedView<T, TKey, TView> : ISynchronizedView<T, TView>
where TKey : notnull
{
public ISynchronizedViewFilter<T, TView> CurrentFilter
{
get { lock (SyncRoot) return filter; }
}

readonly IObservableCollection<T> source;
readonly Func<T, TView> transform;
readonly Func<T, TKey> identitySelector;
Expand Down Expand Up @@ -85,7 +89,7 @@ public void ResetFilter(Action<T, TView>? resetAction)
}
}

public INotifyCollectionChangedSynchronizedView<T, TView> WithINotifyCollectionChanged()
public INotifyCollectionChangedSynchronizedView<TView> ToNotifyCollectionChanged()
{
lock (SyncRoot)
{
Expand Down Expand Up @@ -192,7 +196,7 @@ private void SourceCollectionChanged(in NotifyCollectionChangedEventArgs<T> e)
var view = transform(value);
var id = identitySelector(value);
list.Add((value, id), (value, view));
var newIndex = list.IndexOfKey((value, id));
var newIndex = list.IndexOfKey((value, id));

filter.InvokeOnAdd(value, view, NotifyCollectionChangedEventArgs<T>.Add(value, newIndex));
}
Expand Down
9 changes: 7 additions & 2 deletions src/ObservableCollections/Internal/SortedViewViewComparer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ internal class SortedViewViewComparer<T, TKey, TView> : ISynchronizedView<T, TVi

public object SyncRoot { get; } = new object();

public ISynchronizedViewFilter<T, TView> CurrentFilter
{
get { lock (SyncRoot) return filter; }
}

public SortedViewViewComparer(IObservableCollection<T> source, Func<T, TKey> identitySelector, Func<T, TView> transform, IComparer<TView> comparer)
{
this.source = source;
Expand Down Expand Up @@ -89,7 +94,7 @@ public void ResetFilter(Action<T, TView>? resetAction)
}
}

public INotifyCollectionChangedSynchronizedView<T, TView> WithINotifyCollectionChanged()
public INotifyCollectionChangedSynchronizedView<TView> ToNotifyCollectionChanged()
{
lock (SyncRoot)
{
Expand Down Expand Up @@ -146,7 +151,7 @@ private void SourceCollectionChanged(in NotifyCollectionChangedEventArgs<T> e)
var id = identitySelector(value);
list.Add((view, id), (value, view));
viewMap.Add(id, view);
var index = list.IndexOfKey((view, id));
var index = list.IndexOfKey((view, id));
filter.InvokeOnAdd(value, view, NotifyCollectionChangedEventArgs<T>.Add(value, index));
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/ObservableCollections/ObservableCollections.csproj
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>netstandard2.0;netstandard2.1;net5.0;net6.0</TargetFrameworks>
<TargetFrameworks>netstandard2.0;netstandard2.1;net6.0;net8.0</TargetFrameworks>
<Nullable>enable</Nullable>
<LangVersion>10.0</LangVersion>
<LangVersion>12.0</LangVersion>
<ImplicitUsings>disable</ImplicitUsings>

<!-- NuGet Packaging -->
Expand Down
9 changes: 7 additions & 2 deletions src/ObservableCollections/ObservableDictionary.Views.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public ISynchronizedView<KeyValuePair<TKey, TValue>, TView> CreateView<TView>(Fu
// reverse is no used.
return new View<TView>(this, transform);
}

class View<TView> : ISynchronizedView<KeyValuePair<TKey, TValue>, TView>
{
readonly ObservableDictionary<TKey, TValue> source;
Expand All @@ -39,6 +39,11 @@ public View(ObservableDictionary<TKey, TValue> source, Func<KeyValuePair<TKey, T
public event NotifyCollectionChangedEventHandler<KeyValuePair<TKey, TValue>>? RoutingCollectionChanged;
public event Action<NotifyCollectionChangedAction>? CollectionStateChanged;

public ISynchronizedViewFilter<KeyValuePair<TKey, TValue>, TView> CurrentFilter
{
get { lock (SyncRoot) return filter; }
}

public int Count
{
get
Expand Down Expand Up @@ -91,7 +96,7 @@ public void ResetFilter(Action<KeyValuePair<TKey, TValue>, TView>? resetAction)
}
}

public INotifyCollectionChangedSynchronizedView<KeyValuePair<TKey, TValue>, TView> WithINotifyCollectionChanged()
public INotifyCollectionChangedSynchronizedView<TView> ToNotifyCollectionChanged()
{
lock (SyncRoot)
{
Expand Down
7 changes: 6 additions & 1 deletion src/ObservableCollections/ObservableHashSet.Views.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ public ISynchronizedView<T, TView> CreateView<TView>(Func<T, TView> transform, b

sealed class View<TView> : ISynchronizedView<T, TView>
{
public ISynchronizedViewFilter<T, TView> CurrentFilter
{
get { lock (SyncRoot) return filter; }
}

readonly ObservableHashSet<T> source;
readonly Func<T, TView> selector;
readonly Dictionary<T, (T, TView)> dict;
Expand Down Expand Up @@ -85,7 +90,7 @@ public void ResetFilter(Action<T, TView>? resetAction)
}
}

public INotifyCollectionChangedSynchronizedView<T, TView> WithINotifyCollectionChanged()
public INotifyCollectionChangedSynchronizedView<TView> ToNotifyCollectionChanged()
{
lock (SyncRoot)
{
Expand Down
11 changes: 9 additions & 2 deletions src/ObservableCollections/ObservableList.Views.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@ public ISynchronizedView<T, TView> CreateView<TView>(Func<T, TView> transform, b

sealed class View<TView> : ISynchronizedView<T, TView>
{
public ISynchronizedViewFilter<T, TView> CurrentFilter
{
get
{
lock (SyncRoot) { return filter; }
}
}

readonly ObservableList<T> source;
readonly Func<T, TView> selector;
readonly bool reverse;
Expand All @@ -33,7 +41,6 @@ public View(ObservableList<T> source, Func<T, TView> selector, bool reverse)
this.source = source;
this.selector = selector;
this.reverse = reverse;
this.filter = SynchronizedViewFilter<T, TView>.Null;
this.SyncRoot = new object();
lock (source.SyncRoot)
{
Expand Down Expand Up @@ -89,7 +96,7 @@ public void ResetFilter(Action<T, TView>? resetAction)
}
}

public INotifyCollectionChangedSynchronizedView<T, TView> WithINotifyCollectionChanged()
public INotifyCollectionChangedSynchronizedView<TView> ToNotifyCollectionChanged()
{
lock (SyncRoot)
{
Expand Down
7 changes: 6 additions & 1 deletion src/ObservableCollections/ObservableQueue.Views.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ class View<TView> : ISynchronizedView<T, TView>

public object SyncRoot { get; }

public ISynchronizedViewFilter<T, TView> CurrentFilter
{
get { lock (SyncRoot) return filter; }
}

public View(ObservableQueue<T> source, Func<T, TView> selector, bool reverse)
{
this.source = source;
Expand Down Expand Up @@ -89,7 +94,7 @@ public void ResetFilter(Action<T, TView>? resetAction)
}
}

public INotifyCollectionChangedSynchronizedView<T, TView> WithINotifyCollectionChanged()
public INotifyCollectionChangedSynchronizedView<TView> ToNotifyCollectionChanged()
{
lock (SyncRoot)
{
Expand Down
7 changes: 6 additions & 1 deletion src/ObservableCollections/ObservableRingBuffer.Views.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ public ISynchronizedView<T, TView> CreateView<TView>(Func<T, TView> transform, b
// used with ObservableFixedSizeRingBuffer
internal sealed class View<TView> : ISynchronizedView<T, TView>
{
public ISynchronizedViewFilter<T, TView> CurrentFilter
{
get { lock (SyncRoot) return filter; }
}

readonly IObservableCollection<T> source;
readonly Func<T, TView> selector;
readonly bool reverse;
Expand Down Expand Up @@ -89,7 +94,7 @@ public void ResetFilter(Action<T, TView>? resetAction)
}
}

public INotifyCollectionChangedSynchronizedView<T, TView> WithINotifyCollectionChanged()
public INotifyCollectionChangedSynchronizedView<TView> ToNotifyCollectionChanged()
{
lock (SyncRoot)
{
Expand Down
7 changes: 6 additions & 1 deletion src/ObservableCollections/ObservableStack.Views.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ class View<TView> : ISynchronizedView<T, TView>

public object SyncRoot { get; }

public ISynchronizedViewFilter<T, TView> CurrentFilter
{
get { lock (SyncRoot) return filter; }
}

public View(ObservableStack<T> source, Func<T, TView> selector, bool reverse)
{
this.source = source;
Expand Down Expand Up @@ -89,7 +94,7 @@ public void ResetFilter(Action<T, TView>? resetAction)
}
}

public INotifyCollectionChangedSynchronizedView<T, TView> WithINotifyCollectionChanged()
public INotifyCollectionChangedSynchronizedView<TView> ToNotifyCollectionChanged()
{
lock (SyncRoot)
{
Expand Down

0 comments on commit 18aa9e4

Please sign in to comment.