123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325 |
- using System;
- using System.Collections;
- using System.Collections.Generic;
- namespace Animancer
- {
-
-
-
- public class Key : Key.IListItem
- {
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- public interface IListItem
- {
-
- Key Key { get; }
- }
-
-
- public const int NotInList = -1;
-
- private int _Index = -1;
-
- public static int IndexOf(Key key) => key._Index;
-
- public static bool IsInList(Key key) => key._Index != NotInList;
-
-
- Key IListItem.Key => this;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- public class KeyedList<T> : IList<T>, ICollection where T : class, IListItem
- {
-
- private const string
- SingleUse = "Each item can only be used in one " + nameof(KeyedList<T>) + " at a time.",
- NotFound = "The specified item does not exist in this " + nameof(KeyedList<T>) + ".";
-
- private readonly List<T> Items;
-
-
- public KeyedList() => Items = new List<T>();
-
- public KeyedList(int capacity) => Items = new List<T>(capacity);
-
-
-
- public int Count => Items.Count;
-
- public int Capacity
- {
- get => Items.Capacity;
- set => Items.Capacity = value;
- }
-
-
-
- public T this[int index]
- {
- get => Items[index];
- set
- {
- var key = value.Key;
-
- if (key._Index != NotInList)
- throw new ArgumentException(SingleUse);
-
- Items[index].Key._Index = NotInList;
-
- key._Index = index;
- Items[index] = value;
- }
- }
-
-
- public bool Contains(T item)
- {
- if (item == null)
- return false;
- var index = item.Key._Index;
- return
- (uint)index < (uint)Items.Count &&
- Items[index] == item;
- }
-
-
- public int IndexOf(T item)
- {
- if (item == null)
- return NotInList;
- var index = item.Key._Index;
- if ((uint)index < (uint)Items.Count &&
- Items[index] == item)
- return index;
- else
- return NotInList;
- }
-
-
-
- public void Add(T item)
- {
- var key = item.Key;
-
- if (key._Index != NotInList)
- throw new ArgumentException(SingleUse);
-
- key._Index = Items.Count;
- Items.Add(item);
- }
-
- public void AddNew(T item)
- {
- if (!Contains(item))
- Add(item);
- }
-
-
- public void Insert(int index, T item)
- {
- for (int i = index; i < Items.Count; i++)
- Items[i].Key._Index++;
- item.Key._Index = index;
- Items.Insert(index, item);
- }
-
-
- public void RemoveAt(int index)
- {
-
- for (int i = index + 1; i < Items.Count; i++)
- Items[i].Key._Index--;
-
- Items[index].Key._Index = NotInList;
- Items.RemoveAt(index);
- }
-
-
-
-
-
- public void RemoveAtSwap(int index)
- {
-
- Items[index].Key._Index = NotInList;
-
- var lastIndex = Items.Count - 1;
- if (lastIndex > index)
- {
- var lastItem = Items[lastIndex];
- lastItem.Key._Index = index;
- Items[index] = lastItem;
- }
-
- Items.RemoveAt(lastIndex);
- }
-
-
-
- public bool Remove(T item)
- {
- var key = item.Key;
- var index = key._Index;
-
- if (index == NotInList)
- return false;
-
-
- if (Items[index] != item)
- throw new ArgumentException(NotFound, nameof(item));
-
- RemoveAt(index);
- return true;
- }
-
-
-
-
-
-
-
- public bool RemoveSwap(T item)
- {
- var key = item.Key;
- var index = key._Index;
-
- if (index == NotInList)
- return false;
-
-
- if (Items[index] != item)
- throw new ArgumentException(NotFound, nameof(item));
-
- RemoveAtSwap(index);
- return true;
- }
-
-
- public void Clear()
- {
- for (int i = Items.Count - 1; i >= 0; i--)
- Items[i].Key._Index = NotInList;
- Items.Clear();
- }
-
-
- public void CopyTo(T[] array, int index) => Items.CopyTo(array, index);
-
- void ICollection.CopyTo(Array array, int index) => ((ICollection)Items).CopyTo(array, index);
-
- bool ICollection<T>.IsReadOnly => false;
-
- public List<T>.Enumerator GetEnumerator() => Items.GetEnumerator();
-
- IEnumerator<T> IEnumerable<T>.GetEnumerator() => GetEnumerator();
-
- IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
-
-
- bool ICollection.IsSynchronized => ((ICollection)Items).IsSynchronized;
-
- object ICollection.SyncRoot => ((ICollection)Items).SyncRoot;
-
- }
-
- }
- }
|