Add ObserveClear, ObserveReverse, ObserverSort

This commit is contained in:
neuecc 2024-09-02 19:50:59 +09:00
parent c0c9cd48d7
commit 90e6a54218
3 changed files with 108 additions and 15 deletions

View File

@ -40,11 +40,26 @@ public static class ObservableCollectionR3Extensions
return new ObservableCollectionMove<T>(source, cancellationToken); return new ObservableCollectionMove<T>(source, cancellationToken);
} }
public static Observable<Unit> ObserveReset<T>(this IObservableCollection<T> source, CancellationToken cancellationToken = default) public static Observable<SortOperation<T>> ObserveReset<T>(this IObservableCollection<T> source, CancellationToken cancellationToken = default)
{ {
return new ObservableCollectionReset<T>(source, cancellationToken); return new ObservableCollectionReset<T>(source, cancellationToken);
} }
public static Observable<Unit> ObserveClear<T>(this IObservableCollection<T> source, CancellationToken cancellationToken = default)
{
return new ObservableCollectionClear<T>(source, cancellationToken);
}
public static Observable<Unit> ObserveReverse<T>(this IObservableCollection<T> source, CancellationToken cancellationToken = default)
{
return new ObservableCollectionReverse<T>(source, cancellationToken);
}
public static Observable<(int Index, int Count, IComparer<T> Comparer)> ObserveSort<T>(this IObservableCollection<T> source, CancellationToken cancellationToken = default)
{
return new ObservableCollectionSort<T>(source, cancellationToken);
}
public static Observable<int> ObserveCountChanged<T>(this IObservableCollection<T> source, bool notifyCurrentCount = false, CancellationToken cancellationToken = default) public static Observable<int> ObserveCountChanged<T>(this IObservableCollection<T> source, bool notifyCurrentCount = false, CancellationToken cancellationToken = default)
{ {
return new ObservableCollectionCountChanged<T>(source, notifyCurrentCount, cancellationToken); return new ObservableCollectionCountChanged<T>(source, notifyCurrentCount, cancellationToken);
@ -188,16 +203,39 @@ sealed class ObservableCollectionMove<T>(IObservableCollection<T> collection, Ca
} }
} }
} }
sealed class ObservableCollectionReset<T>(IObservableCollection<T> collection, CancellationToken cancellationToken) sealed class ObservableCollectionReset<T>(IObservableCollection<T> collection, CancellationToken cancellationToken)
: Observable<Unit> : Observable<SortOperation<T>>
{ {
protected override IDisposable SubscribeCore(Observer<Unit> observer) protected override IDisposable SubscribeCore(Observer<SortOperation<T>> observer)
{ {
return new _ObservableCollectionReset(collection, observer, cancellationToken); return new _ObservableCollectionReset(collection, observer, cancellationToken);
} }
sealed class _ObservableCollectionReset( sealed class _ObservableCollectionReset(
IObservableCollection<T> collection,
Observer<SortOperation<T>> observer,
CancellationToken cancellationToken)
: ObservableCollectionObserverBase<T, SortOperation<T>>(collection, observer, cancellationToken)
{
protected override void Handler(in NotifyCollectionChangedEventArgs<T> eventArgs)
{
if (eventArgs.Action == NotifyCollectionChangedAction.Reset)
{
observer.OnNext(eventArgs.SortOperation);
}
}
}
}
sealed class ObservableCollectionClear<T>(IObservableCollection<T> collection, CancellationToken cancellationToken)
: Observable<Unit>
{
protected override IDisposable SubscribeCore(Observer<Unit> observer)
{
return new _ObservableCollectionClear(collection, observer, cancellationToken);
}
sealed class _ObservableCollectionClear(
IObservableCollection<T> collection, IObservableCollection<T> collection,
Observer<Unit> observer, Observer<Unit> observer,
CancellationToken cancellationToken) CancellationToken cancellationToken)
@ -205,7 +243,7 @@ sealed class ObservableCollectionReset<T>(IObservableCollection<T> collection, C
{ {
protected override void Handler(in NotifyCollectionChangedEventArgs<T> eventArgs) protected override void Handler(in NotifyCollectionChangedEventArgs<T> eventArgs)
{ {
if (eventArgs.Action == NotifyCollectionChangedAction.Reset) if (eventArgs.Action == NotifyCollectionChangedAction.Reset && eventArgs.SortOperation.IsNull)
{ {
observer.OnNext(Unit.Default); observer.OnNext(Unit.Default);
} }
@ -213,6 +251,52 @@ sealed class ObservableCollectionReset<T>(IObservableCollection<T> collection, C
} }
} }
sealed class ObservableCollectionReverse<T>(IObservableCollection<T> collection, CancellationToken cancellationToken) : Observable<Unit>
{
protected override IDisposable SubscribeCore(Observer<Unit> observer)
{
return new _ObservableCollectionReverse(collection, observer, cancellationToken);
}
sealed class _ObservableCollectionReverse(
IObservableCollection<T> collection,
Observer<Unit> observer,
CancellationToken cancellationToken)
: ObservableCollectionObserverBase<T, Unit>(collection, observer, cancellationToken)
{
protected override void Handler(in NotifyCollectionChangedEventArgs<T> eventArgs)
{
if (eventArgs.Action == NotifyCollectionChangedAction.Reset && eventArgs.SortOperation.IsReverse)
{
observer.OnNext(Unit.Default);
}
}
}
}
sealed class ObservableCollectionSort<T>(IObservableCollection<T> collection, CancellationToken cancellationToken) : Observable<(int Index, int Count, IComparer<T> Comparer)>
{
protected override IDisposable SubscribeCore(Observer<(int Index, int Count, IComparer<T> Comparer)> observer)
{
return new _ObservableCollectionSort(collection, observer, cancellationToken);
}
sealed class _ObservableCollectionSort(
IObservableCollection<T> collection,
Observer<(int Index, int Count, IComparer<T> Comparer)> observer,
CancellationToken cancellationToken)
: ObservableCollectionObserverBase<T, (int Index, int Count, IComparer<T> Comparer)>(collection, observer, cancellationToken)
{
protected override void Handler(in NotifyCollectionChangedEventArgs<T> eventArgs)
{
if (eventArgs.Action == NotifyCollectionChangedAction.Reset && eventArgs.SortOperation.IsSort)
{
observer.OnNext(eventArgs.SortOperation.AsTuple());
}
}
}
}
sealed class ObservableCollectionCountChanged<T>(IObservableCollection<T> collection, bool notifyCurrentCount, CancellationToken cancellationToken) sealed class ObservableCollectionCountChanged<T>(IObservableCollection<T> collection, bool notifyCurrentCount, CancellationToken cancellationToken)
: Observable<int> : Observable<int>
{ {

View File

@ -2,6 +2,7 @@
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Specialized; using System.Collections.Specialized;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace ObservableCollections namespace ObservableCollections
@ -16,6 +17,9 @@ namespace ObservableCollections
public bool IsReverse => Comparer == ReverseSentinel.Instance; public bool IsReverse => Comparer == ReverseSentinel.Instance;
public bool IsNull => Comparer == null; public bool IsNull => Comparer == null;
[MemberNotNullWhen(true, nameof(Comparer))]
public bool IsSort => !IsNull && !IsReverse;
public SortOperation(int index, int count, IComparer<T>? comparer) public SortOperation(int index, int count, IComparer<T>? comparer)
{ {
Index = index; Index = index;
@ -23,6 +27,11 @@ namespace ObservableCollections
Comparer = comparer ?? NullComparerSentinel.Instance; Comparer = comparer ?? NullComparerSentinel.Instance;
} }
public (int Index, int Count, IComparer<T> Comparer) AsTuple()
{
return (Index, Count, Comparer!);
}
public static SortOperation<T> CreateReverse(int index, int count) public static SortOperation<T> CreateReverse(int index, int count)
{ {
return new SortOperation<T>(index, count, ReverseSentinel.Instance); return new SortOperation<T>(index, count, ReverseSentinel.Instance);

View File

@ -157,7 +157,7 @@ namespace ObservableCollections.Tests
// list.AddRange(new[] { 10, 21, 30, 44 }); // list.AddRange(new[] { 10, 21, 30, 44 });
// var filter1 = new TestFilter<int>((x, v) => x % 2 == 0); // var filter1 = new TestFilter<int>((x, v) => x % 2 == 0);
// view1.AttachFilter(filter1); // view1.AttachFilter((x, v) => x % 2 == 0));
// filter1.CalledOnCollectionChanged[0].Action.Should().Be(NotifyCollectionChangedAction.Add); // filter1.CalledOnCollectionChanged[0].Action.Should().Be(NotifyCollectionChangedAction.Add);
// filter1.CalledOnCollectionChanged[0].NewValue.Should().Be(10); // filter1.CalledOnCollectionChanged[0].NewValue.Should().Be(10);