174 lines
4.3 KiB
C#
174 lines
4.3 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
|
|
namespace BITKit
|
|
{
|
|
public sealed class CacheList<T> : IList<T>
|
|
{
|
|
public T[] ValueArray
|
|
{
|
|
get
|
|
{
|
|
CheckChanges();
|
|
return _array;
|
|
}
|
|
}
|
|
|
|
private readonly IList<T> _listImplementation = new List<T>();
|
|
private T[] _array = Array.Empty<T>();
|
|
private IEnumerator<T> _enumerable=Array.Empty<T>().AsEnumerable().GetEnumerator();
|
|
private bool _isDirty = true;
|
|
|
|
public IEnumerator<T> GetEnumerator()
|
|
{
|
|
CheckChanges();
|
|
return _enumerable;
|
|
}
|
|
|
|
IEnumerator IEnumerable.GetEnumerator()
|
|
{
|
|
CheckChanges();
|
|
return _enumerable;
|
|
}
|
|
|
|
public void Add(T item)
|
|
{
|
|
_listImplementation.Add(item);
|
|
_isDirty = true;
|
|
}
|
|
|
|
public void Clear()
|
|
{
|
|
_isDirty = false;
|
|
_listImplementation.Clear();
|
|
_array = Array.Empty<T>();
|
|
}
|
|
|
|
public bool Contains(T item)
|
|
{
|
|
CheckChanges();
|
|
return _listImplementation.Contains(item);
|
|
}
|
|
|
|
public void CopyTo(T[] array, int arrayIndex)
|
|
{
|
|
CheckChanges();
|
|
_listImplementation.CopyTo(array, arrayIndex);
|
|
_isDirty = true;
|
|
}
|
|
|
|
public bool Remove(T item)
|
|
{
|
|
_isDirty = true;
|
|
return _listImplementation.Remove(item);
|
|
}
|
|
|
|
public int Count
|
|
{
|
|
|
|
get
|
|
{
|
|
CheckChanges();
|
|
return _listImplementation.Count;
|
|
}
|
|
}
|
|
|
|
public bool IsReadOnly
|
|
{
|
|
get
|
|
{
|
|
CheckChanges();
|
|
return _listImplementation.IsReadOnly;
|
|
}
|
|
}
|
|
|
|
public int IndexOf(T item)
|
|
{
|
|
CheckChanges();
|
|
return _listImplementation.IndexOf(item);
|
|
}
|
|
|
|
public void Insert(int index, T item)
|
|
{
|
|
CheckChanges();
|
|
_listImplementation.Insert(index, item);
|
|
_isDirty = true;
|
|
}
|
|
|
|
public void RemoveAt(int index)
|
|
{
|
|
CheckChanges();
|
|
_listImplementation.RemoveAt(index);
|
|
_isDirty = true;
|
|
}
|
|
|
|
public T this[int index]
|
|
{
|
|
get
|
|
{
|
|
CheckChanges();
|
|
return _listImplementation[index];
|
|
}
|
|
set
|
|
{
|
|
_isDirty = true;
|
|
_listImplementation[index] = value;
|
|
CheckChanges();
|
|
}
|
|
}
|
|
|
|
public bool CheckChanges()
|
|
{
|
|
if (!_isDirty) return false;
|
|
_array = new T[_listImplementation.Count];
|
|
_listImplementation.CopyTo(_array, 0);
|
|
_enumerable = _array.AsEnumerable().GetEnumerator();
|
|
_isDirty = false;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
public sealed class PrioritySelector<T>
|
|
{
|
|
public T Current { get; private set; }
|
|
public event Action<T> OnRelease;
|
|
private readonly SortedDictionary<int,T> _sortedDictionary = new();
|
|
public void Set(int priority, T item)
|
|
{
|
|
_sortedDictionary.Set(priority,item);
|
|
CheckChanges();
|
|
}
|
|
public void Remove(int priority)
|
|
{
|
|
_sortedDictionary.Remove(priority);
|
|
CheckChanges();
|
|
}
|
|
|
|
private void CheckChanges()
|
|
{
|
|
if (_sortedDictionary.Count is 0)
|
|
return;
|
|
var _current = _sortedDictionary.Last().Value;
|
|
switch (_current, Current)
|
|
{
|
|
case (not null, null):
|
|
Current = _current;
|
|
break;
|
|
case (null, not null):
|
|
Current = default;
|
|
break;
|
|
case (not null, not null):
|
|
if (Current.Equals(_current) is false)
|
|
{
|
|
Current = _current;
|
|
}
|
|
break;
|
|
case (null, null):
|
|
break;
|
|
}
|
|
OnRelease?.Invoke(Current);
|
|
}
|
|
}
|
|
} |