Add IObservableCollection<>.ObserveCountChanged
This commit is contained in:
parent
320012d840
commit
b912fc6324
@ -36,6 +36,11 @@ public static class ObservableCollectionR3Extensions
|
|||||||
{
|
{
|
||||||
return new ObservableCollectionReset<T>(source, cancellationToken);
|
return new ObservableCollectionReset<T>(source, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Observable<int> ObserveCountChanged<T>(this IObservableCollection<T> source, bool notifyCurrentCount = false, CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
return new ObservableCollectionCountChanged<T>(source, notifyCurrentCount, cancellationToken);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed class ObservableCollectionAdd<T>(IObservableCollection<T> collection, CancellationToken cancellationToken)
|
sealed class ObservableCollectionAdd<T>(IObservableCollection<T> collection, CancellationToken cancellationToken)
|
||||||
@ -180,6 +185,49 @@ sealed class ObservableCollectionReset<T>(IObservableCollection<T> collection, C
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sealed class ObservableCollectionCountChanged<T>(IObservableCollection<T> collection, bool notifyCurrentCount, CancellationToken cancellationToken)
|
||||||
|
: Observable<int>
|
||||||
|
{
|
||||||
|
protected override IDisposable SubscribeCore(Observer<int> observer)
|
||||||
|
{
|
||||||
|
return new _ObservableCollectionCountChanged(collection, notifyCurrentCount, observer, cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
sealed class _ObservableCollectionCountChanged : ObservableCollectionObserverBase<T, int>
|
||||||
|
{
|
||||||
|
readonly IObservableCollection<T> collection;
|
||||||
|
int countPrev;
|
||||||
|
|
||||||
|
public _ObservableCollectionCountChanged(
|
||||||
|
IObservableCollection<T> collection,
|
||||||
|
bool notifyCurrentCount,
|
||||||
|
Observer<int> observer,
|
||||||
|
CancellationToken cancellationToken) : base(collection, observer, cancellationToken)
|
||||||
|
{
|
||||||
|
this.collection = collection;
|
||||||
|
this.countPrev = collection.Count;
|
||||||
|
if (notifyCurrentCount)
|
||||||
|
{
|
||||||
|
observer.OnNext(collection.Count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Handler(in NotifyCollectionChangedEventArgs<T> eventArgs)
|
||||||
|
{
|
||||||
|
switch (eventArgs.Action)
|
||||||
|
{
|
||||||
|
case NotifyCollectionChangedAction.Add:
|
||||||
|
case NotifyCollectionChangedAction.Remove:
|
||||||
|
case NotifyCollectionChangedAction.Reset when countPrev != collection.Count:
|
||||||
|
observer.OnNext(collection.Count);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
countPrev = collection.Count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
abstract class ObservableCollectionObserverBase<T, TEvent> : IDisposable
|
abstract class ObservableCollectionObserverBase<T, TEvent> : IDisposable
|
||||||
{
|
{
|
||||||
protected readonly IObservableCollection<T> collection;
|
protected readonly IObservableCollection<T> collection;
|
||||||
|
@ -49,7 +49,7 @@ namespace ObservableCollections.Internal
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var array = ArrayPool<T>.Shared.Rent(count);
|
var array = ArrayPool<T>.Shared.Rent(16);
|
||||||
|
|
||||||
var i = 0;
|
var i = 0;
|
||||||
foreach (var item in source)
|
foreach (var item in source)
|
||||||
@ -75,8 +75,8 @@ namespace ObservableCollections.Internal
|
|||||||
if (array.Length == index)
|
if (array.Length == index)
|
||||||
{
|
{
|
||||||
ArrayPool<T>.Shared.Return(array, RuntimeHelpersEx.IsReferenceOrContainsReferences<T>());
|
ArrayPool<T>.Shared.Return(array, RuntimeHelpersEx.IsReferenceOrContainsReferences<T>());
|
||||||
|
array = ArrayPool<T>.Shared.Rent(index * 2);
|
||||||
}
|
}
|
||||||
array = ArrayPool<T>.Shared.Rent(index * 2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
|
@ -132,4 +132,43 @@ public class ObservableCollectionExtensionsTest
|
|||||||
collection.Move(1, 2);
|
collection.Move(1, 2);
|
||||||
events.Count.Should().Be(1);
|
events.Count.Should().Be(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void ObserveCountChanged()
|
||||||
|
{
|
||||||
|
var events = new List<int>();
|
||||||
|
var collection = new ObservableList<int>([111, 222, 333]);
|
||||||
|
|
||||||
|
using var _ = collection.ObserveCountChanged().Subscribe(count => events.Add(count));
|
||||||
|
|
||||||
|
events.Should().BeEmpty();
|
||||||
|
|
||||||
|
collection.Add(444);
|
||||||
|
events[0].Should().Be(4);
|
||||||
|
|
||||||
|
collection.Remove(111);
|
||||||
|
events[1].Should().Be(3);
|
||||||
|
|
||||||
|
collection.Move(0, 1);
|
||||||
|
events.Count.Should().Be(2);
|
||||||
|
|
||||||
|
collection[0] = 999;
|
||||||
|
events.Count.Should().Be(2);
|
||||||
|
|
||||||
|
collection.Clear();
|
||||||
|
events[2].Should().Be(0);
|
||||||
|
|
||||||
|
collection.Clear();
|
||||||
|
events.Count.Should().Be(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void ObserveCountChanged_NotifyCurrent()
|
||||||
|
{
|
||||||
|
var events = new List<int>();
|
||||||
|
var collection = new ObservableList<int>([111, 222, 333]);
|
||||||
|
|
||||||
|
var subscription = collection.ObserveCountChanged(notifyCurrentCount: true).Subscribe(count => events.Add(count));
|
||||||
|
events[0].Should().Be(3);
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user