working linkedlist

This commit is contained in:
neuecc 2021-08-18 19:48:30 +09:00
parent d7d621ab0d
commit e8ac54e738
2 changed files with 66 additions and 9 deletions

View File

@ -14,6 +14,7 @@ namespace ObservableCollections
sealed class View<TView> : ISynchronizedView<LinkedListNode<T>, TView> sealed class View<TView> : ISynchronizedView<LinkedListNode<T>, TView>
{ {
readonly ObservableLinkedList<T> source; readonly ObservableLinkedList<T> source;
readonly Dictionary<LinkedListNode<T>, LinkedListNode<(LinkedListNode<T>, TView)>> nodeMap;
readonly LinkedList<(LinkedListNode<T>, TView)> list; readonly LinkedList<(LinkedListNode<T>, TView)> list;
readonly Func<LinkedListNode<T>, TView> selector; readonly Func<LinkedListNode<T>, TView> selector;
@ -72,25 +73,74 @@ namespace ObservableCollections
{ {
lock (SyncRoot) lock (SyncRoot)
{ {
// Range operations is not supported.
switch (e.Action) switch (e.Action)
{ {
case NotifyCollectionChangedAction.Add: case NotifyCollectionChangedAction.Add:
{ {
// AddAfter var view = selector(e.NewItem);
if (e.OldItem != null) var value = (e.NewItem, view);
LinkedListNode<(LinkedListNode<T>, TView)>? addNode = null;
if (e.OldItem == null)
{ {
// AddFirst
if (e.NewStartingIndex == 0)
{
addNode = list.AddFirst(value);
}
// AddLast
else
{
addNode = list.AddLast(value);
}
}
else
{
// AddBefore
if (e.NewStartingIndex == -1)
{
if (nodeMap.TryGetValue(e.OldItem, out var node))
{
addNode = list.AddBefore(node, value);
}
}
// AddAfter
else
{
if (nodeMap.TryGetValue(e.OldItem, out var node))
{
addNode = list.AddAfter(node, value);
}
}
} }
if (addNode != null)
{
nodeMap.Add(e.NewItem, addNode);
// TODO: filter invoke.
}
} }
break; break;
case NotifyCollectionChangedAction.Remove: case NotifyCollectionChangedAction.Remove:
break; {
case NotifyCollectionChangedAction.Replace: if (nodeMap.Remove(e.OldItem, out var node))
break; {
case NotifyCollectionChangedAction.Move: list.Remove(node);
// TODO:filter invoke
}
}
break; break;
case NotifyCollectionChangedAction.Reset: case NotifyCollectionChangedAction.Reset:
{
nodeMap.Clear();
list.Clear();
// TODO:filter invoke
}
break; break;
case NotifyCollectionChangedAction.Replace:
case NotifyCollectionChangedAction.Move:
default: default:
break; break;
} }
@ -98,4 +148,4 @@ namespace ObservableCollections
} }
} }
} }
} }

View File

@ -63,8 +63,6 @@ namespace ObservableCollections
{ {
var newNode = list.AddBefore(node, value); var newNode = list.AddBefore(node, value);
// list.
// special event, oldItem is target, newStartingIndex:-1 = before // special event, oldItem is target, newStartingIndex:-1 = before
var ev = new NotifyCollectionChangedEventArgs<LinkedListNode<T>>( var ev = new NotifyCollectionChangedEventArgs<LinkedListNode<T>>(
NotifyCollectionChangedAction.Add, isSingleItem: true, NotifyCollectionChangedAction.Add, isSingleItem: true,
@ -126,6 +124,15 @@ namespace ObservableCollections
} }
} }
public void Clear()
{
lock (SyncRoot)
{
list.Clear();
CollectionChanged?.Invoke(NotifyCollectionChangedEventArgs<LinkedListNode<T>>.Reset());
}
}
public IEnumerator<LinkedListNode<T>> GetEnumerator() public IEnumerator<LinkedListNode<T>> GetEnumerator()
{ {
throw new NotImplementedException(); throw new NotImplementedException();