using System; using System.Collections.Generic; namespace Engine.Core; public class BehaviourCollectorOrdered : BehaviourCollectorBase where TItem : class where TIndex : IComparable { private readonly SortedDictionary> behaviours = null!; private readonly Dictionary indexCache = null!; private readonly Func getIndexFunc = null!; private readonly IComparer sortBy = null!; private int count = 0; public override int Count => count; public override TItem this[Index index] { get { int actualIndex = index.IsFromEnd ? count - index.Value : index.Value; if (actualIndex < 0 || actualIndex >= count) throw new IndexOutOfRangeException(); int leftIndex = actualIndex; foreach ((TIndex i, FastList list) in behaviours) { if (leftIndex < list.Count) return list[leftIndex]; leftIndex -= list.Count; } throw new IndexOutOfRangeException(); } } protected override bool RemoveBehaviour(TItem tBehaviour) { if (!indexCache.TryGetValue(tBehaviour, out TIndex? index) || !behaviours.TryGetValue(index, out FastList? list)) throw new Exceptions.NotFoundException($"Index of '{index}' is not found in the collector"); if (!list.Remove(tBehaviour) || !indexCache.Remove(tBehaviour)) return false; count--; return true; } protected override void AddBehaviour(TItem behaviour) { TIndex key = getIndexFunc(behaviour); if (!behaviours.TryGetValue(key, out FastList? list)) behaviours[key] = list = []; count++; list.Add(behaviour); indexCache.Add(behaviour, key); } public BehaviourCollectorOrdered(Func getIndexFunc, Comparison sortBy) { this.getIndexFunc = getIndexFunc; this.sortBy = Comparer.Create(sortBy); behaviours = new(this.sortBy); } public BehaviourCollectorOrdered(IUniverse universe, Func getIndexFunc, Comparison sortBy) : base(universe) { this.getIndexFunc = getIndexFunc; this.sortBy = Comparer.Create(sortBy); behaviours = new(this.sortBy); } public BehaviourCollectorOrdered(Func getIndexFunc, IComparer sortBy) { this.getIndexFunc = getIndexFunc; this.sortBy = sortBy; behaviours = new(sortBy); } public BehaviourCollectorOrdered(IUniverse universe, Func getIndexFunc, IComparer sortBy) : base(universe) { this.getIndexFunc = getIndexFunc; this.sortBy = sortBy; behaviours = new(sortBy); } }