remove unused new observable collection

This commit is contained in:
Matt Parker
2025-11-01 13:02:33 +10:00
parent 3b4097f5fe
commit 1b1ca51f40
2 changed files with 0 additions and 545 deletions

View File

@@ -1,227 +0,0 @@
using System.Collections;
using System.Collections.Specialized;
namespace ObservableCollections
{
public partial class ObservableSortedSet<T> : IReadOnlyCollection<T>, IObservableCollection<T>
{
public ISynchronizedView<T, TView> CreateView<TView>(Func<T, TView> transform)
{
return new View<TView>(this, transform);
}
sealed class View<TView> : ISynchronizedView<T, TView>
{
public ISynchronizedViewFilter<T, TView> Filter
{
get { lock (SyncRoot) return filter; }
}
readonly ObservableSortedSet<T> source;
readonly Func<T, TView> selector;
readonly Dictionary<T, (T, TView)> dict;
int filteredCount;
ISynchronizedViewFilter<T, TView> filter;
public event NotifyViewChangedEventHandler<T, TView>? ViewChanged;
public event Action<RejectedViewChangedAction, int, int>? RejectedViewChanged;
public event Action<NotifyCollectionChangedAction>? CollectionStateChanged;
public object SyncRoot { get; }
public View(ObservableSortedSet<T> source, Func<T, TView> selector)
{
this.source = source;
this.selector = selector;
this.filter = SynchronizedViewFilter<T, TView>.Null;
this.SyncRoot = new object();
lock (source.SyncRoot)
{
this.dict = source._set.ToDictionary(x => x, x => (x, selector(x)));
this.filteredCount = dict.Count;
this.source.CollectionChanged += SourceCollectionChanged;
}
}
public int Count
{
get
{
lock (SyncRoot)
{
return filteredCount;
}
}
}
public int UnfilteredCount
{
get
{
lock (SyncRoot)
{
return dict.Count;
}
}
}
public void AttachFilter(ISynchronizedViewFilter<T, TView> filter)
{
if (filter.IsNullFilter())
{
ResetFilter();
return;
}
lock (SyncRoot)
{
this.filter = filter;
this.filteredCount = 0;
foreach (var (_, (value, view)) in dict)
{
if (filter.IsMatch(value, view))
{
filteredCount++;
}
}
ViewChanged?.Invoke(new SynchronizedViewChangedEventArgs<T, TView>(NotifyCollectionChangedAction.Reset, true));
}
}
public void ResetFilter()
{
lock (SyncRoot)
{
this.filter = SynchronizedViewFilter<T, TView>.Null;
this.filteredCount = dict.Count;
ViewChanged?.Invoke(new SynchronizedViewChangedEventArgs<T, TView>(NotifyCollectionChangedAction.Reset, true));
}
}
public ISynchronizedViewList<TView> ToViewList()
{
return new FiltableSynchronizedViewList<T, TView>(this, isSupportRangeFeature: true);
}
public NotifyCollectionChangedSynchronizedViewList<TView> ToNotifyCollectionChanged()
{
return new FiltableSynchronizedViewList<T, TView>(this, isSupportRangeFeature: false);
}
public NotifyCollectionChangedSynchronizedViewList<TView> ToNotifyCollectionChanged(ICollectionEventDispatcher? collectionEventDispatcher)
{
return new FiltableSynchronizedViewList<T, TView>(this, isSupportRangeFeature: false, collectionEventDispatcher);
}
public IEnumerator<TView> GetEnumerator()
{
lock (SyncRoot)
{
foreach (var item in dict)
{
if (filter.IsMatch(item.Value))
{
yield return item.Value.Item2;
}
}
}
}
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
public IEnumerable<(T Value, TView View)> Filtered
{
get
{
lock (SyncRoot)
{
foreach (var item in dict)
{
if (filter.IsMatch(item.Value))
{
yield return item.Value;
}
}
}
}
}
public IEnumerable<(T Value, TView View)> Unfiltered
{
get
{
lock (SyncRoot)
{
foreach (var item in dict)
{
yield return item.Value;
}
}
}
}
public void Dispose()
{
this.source.CollectionChanged -= SourceCollectionChanged;
}
private void SourceCollectionChanged(in NotifyCollectionChangedEventArgs<T> e)
{
lock (SyncRoot)
{
switch (e.Action)
{
case NotifyCollectionChangedAction.Add:
if (e.IsSingleItem)
{
var v = (e.NewItem, selector(e.NewItem));
dict.Add(e.NewItem, v);
this.InvokeOnAdd(ref filteredCount, ViewChanged, RejectedViewChanged, v, -1);
}
else
{
var i = e.NewStartingIndex;
foreach (var item in e.NewItems)
{
var v = (item, selector(item));
dict.Add(item, v);
this.InvokeOnAdd(ref filteredCount, ViewChanged, RejectedViewChanged, v, i++);
}
}
break;
case NotifyCollectionChangedAction.Remove:
if (e.IsSingleItem)
{
if (dict.Remove(e.OldItem, out var value))
{
this.InvokeOnRemove(ref filteredCount, ViewChanged, RejectedViewChanged, value, -1);
}
}
else
{
foreach (var item in e.OldItems)
{
if (dict.Remove(item, out var value))
{
this.InvokeOnRemove(ref filteredCount, ViewChanged, RejectedViewChanged, value, -1);
}
}
}
break;
case NotifyCollectionChangedAction.Reset:
dict.Clear();
this.InvokeOnReset(ref filteredCount, ViewChanged);
break;
case NotifyCollectionChangedAction.Replace:
case NotifyCollectionChangedAction.Move:
default:
break;
}
CollectionStateChanged?.Invoke(e.Action);
}
}
}
}
}

View File

@@ -1,318 +0,0 @@
using ObservableCollections.Internal;
using System.Collections;
using System.Diagnostics.CodeAnalysis;
// Courtesy of Copilot Agent
// Replace with https://github.com/Cysharp/ObservableCollections/pull/111 if it gets merged
namespace ObservableCollections
{
// can not implements ISet<T> because set operation can not get added/removed values.
public partial class ObservableSortedSet<T> : IReadOnlySet<T>, IReadOnlyCollection<T>, IObservableCollection<T> where T : notnull
{
private readonly SortedSet<T> _set;
public object SyncRoot { get; } = new object();
public ObservableSortedSet()
{
_set = new SortedSet<T>();
}
public ObservableSortedSet(IComparer<T>? comparer)
{
_set = new SortedSet<T>(comparer: comparer);
}
public ObservableSortedSet(IEnumerable<T> collection)
{
_set = new SortedSet<T>(collection: collection);
}
public ObservableSortedSet(IEnumerable<T> collection, IComparer<T>? comparer)
{
_set = new SortedSet<T>(collection: collection, comparer: comparer);
}
public event NotifyCollectionChangedEventHandler<T>? CollectionChanged;
public int Count
{
get
{
lock (SyncRoot)
{
return _set.Count;
}
}
}
public bool IsReadOnly => false;
public bool Add(T item)
{
lock (SyncRoot)
{
if (_set.Add(item))
{
CollectionChanged?.Invoke(NotifyCollectionChangedEventArgs<T>.Add(item, -1));
return true;
}
return false;
}
}
public void AddRange(IEnumerable<T> items)
{
lock (SyncRoot)
{
if (!items.TryGetNonEnumeratedCount(out var capacity))
{
capacity = 4;
}
using (var list = new ResizableArray<T>(capacity))
{
foreach (var item in items)
{
if (_set.Add(item))
{
list.Add(item);
}
}
CollectionChanged?.Invoke(NotifyCollectionChangedEventArgs<T>.Add(list.Span, -1));
}
}
}
public void AddRange(T[] items)
{
AddRange(items.AsSpan());
}
public void AddRange(ReadOnlySpan<T> items)
{
lock (SyncRoot)
{
using (var list = new ResizableArray<T>(items.Length))
{
foreach (var item in items)
{
if (_set.Add(item))
{
list.Add(item);
}
}
CollectionChanged?.Invoke(NotifyCollectionChangedEventArgs<T>.Add(list.Span, -1));
}
}
}
public bool Remove(T item)
{
lock (SyncRoot)
{
if (_set.Remove(item))
{
CollectionChanged?.Invoke(NotifyCollectionChangedEventArgs<T>.Remove(item, -1));
return true;
}
return false;
}
}
public void RemoveRange(IEnumerable<T> items)
{
lock (SyncRoot)
{
if (!items.TryGetNonEnumeratedCount(out var capacity))
{
capacity = 4;
}
using (var list = new ResizableArray<T>(capacity))
{
foreach (var item in items)
{
if (_set.Remove(item))
{
list.Add(item);
}
}
CollectionChanged?.Invoke(NotifyCollectionChangedEventArgs<T>.Remove(list.Span, -1));
}
}
}
public void RemoveRange(T[] items)
{
RemoveRange(items.AsSpan());
}
public void RemoveRange(ReadOnlySpan<T> items)
{
lock (SyncRoot)
{
using (var list = new ResizableArray<T>(items.Length))
{
foreach (var item in items)
{
if (_set.Remove(item))
{
list.Add(item);
}
}
CollectionChanged?.Invoke(NotifyCollectionChangedEventArgs<T>.Remove(list.Span, -1));
}
}
}
public void Clear()
{
lock (SyncRoot)
{
_set.Clear();
CollectionChanged?.Invoke(NotifyCollectionChangedEventArgs<T>.Reset());
}
}
#if !NETSTANDARD2_0 && !NET_STANDARD_2_0 && !NET_4_6
public bool TryGetValue(T equalValue, [MaybeNullWhen(false)] out T actualValue)
{
lock (SyncRoot)
{
return _set.TryGetValue(equalValue, out actualValue);
}
}
#endif
public bool Contains(T item)
{
lock (SyncRoot)
{
return _set.Contains(item);
}
}
public bool IsProperSubsetOf(IEnumerable<T> other)
{
lock (SyncRoot)
{
return _set.IsProperSubsetOf(other);
}
}
public bool IsProperSupersetOf(IEnumerable<T> other)
{
lock (SyncRoot)
{
return _set.IsProperSupersetOf(other);
}
}
public bool IsSubsetOf(IEnumerable<T> other)
{
lock (SyncRoot)
{
return _set.IsSubsetOf(other);
}
}
public bool IsSupersetOf(IEnumerable<T> other)
{
lock (SyncRoot)
{
return _set.IsSupersetOf(other);
}
}
public bool Overlaps(IEnumerable<T> other)
{
lock (SyncRoot)
{
return _set.Overlaps(other);
}
}
public bool SetEquals(IEnumerable<T> other)
{
lock (SyncRoot)
{
return _set.SetEquals(other);
}
}
public IEnumerator<T> GetEnumerator()
{
lock (SyncRoot)
{
foreach (var item in _set)
{
yield return item;
}
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public IComparer<T> Comparer
{
get
{
lock (SyncRoot)
{
return _set.Comparer;
}
}
}
// SortedSet-specific properties
public T? Min
{
get
{
lock (SyncRoot)
{
return _set.Count > 0 ? _set.Min : default;
}
}
}
public T? Max
{
get
{
lock (SyncRoot)
{
return _set.Count > 0 ? _set.Max : default;
}
}
}
// SortedSet-specific methods
public IEnumerable<T> Reverse()
{
lock (SyncRoot)
{
return _set.Reverse().ToArray();
}
}
public IEnumerable<T> GetViewBetween(T lowerValue, T upperValue)
{
lock (SyncRoot)
{
return _set.GetViewBetween(lowerValue, upperValue).ToArray();
}
}
}
}