diff --git a/Engine.Core/ActiveBehaviourCollector.cs b/Engine.Core/ActiveBehaviourCollector.cs index f5fbd06..f6a5fc0 100644 --- a/Engine.Core/ActiveBehaviourCollector.cs +++ b/Engine.Core/ActiveBehaviourCollector.cs @@ -16,8 +16,8 @@ public class ActiveBehaviourCollector : IBehaviourCollector where T : clas private readonly Event.EventHandler delegateOnUniverseObjectRegistered = null!; private readonly Event.EventHandler delegateOnUniverseObjectUnregistered = null!; - private readonly List monitoringBehaviours = new(32); - protected readonly List activeBehaviours = new(32); + private readonly FastList monitoringBehaviours = new(32); + protected readonly FastList activeBehaviours = new(32); protected readonly Dictionary monitoringActiveToBehaviour = new(32); public IUniverse Universe { get; private set; } = null!; diff --git a/Engine.Core/BehaviourCollector.cs b/Engine.Core/BehaviourCollector.cs index 56617c2..f43ef7b 100644 --- a/Engine.Core/BehaviourCollector.cs +++ b/Engine.Core/BehaviourCollector.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; namespace Engine.Core; @@ -15,7 +14,7 @@ public class BehaviourCollector : IBehaviourCollector where T : class private readonly Event.EventHandler delegateOnUniverseObjectRegistered = null!; private readonly Event.EventHandler delegateOnUniverseObjectUnregistered = null!; - protected readonly List behaviours = new(32); + protected readonly FastList behaviours = new(32); public IUniverse Universe { get; private set; } = null!; diff --git a/Engine.Core/BehaviourController.cs b/Engine.Core/BehaviourController.cs index 45497aa..00618a8 100644 --- a/Engine.Core/BehaviourController.cs +++ b/Engine.Core/BehaviourController.cs @@ -10,7 +10,7 @@ public class BehaviourController : BaseEntity, IBehaviourController public Event OnBehaviourRemoved { get; } = new(); public Event OnUniverseObjectAssigned { get; } = new(); - private readonly List behaviours = new(Constants.BEHAVIOURS_SIZE_INITIAL); + private readonly FastList behaviours = new(Constants.BEHAVIOURS_SIZE_INITIAL); private IUniverseObject _universeObject = null!; diff --git a/Engine.Core/Helpers/FastList.cs b/Engine.Core/Helpers/FastList.cs new file mode 100644 index 0000000..fa64216 --- /dev/null +++ b/Engine.Core/Helpers/FastList.cs @@ -0,0 +1,74 @@ +using System.Collections; +using System.Collections.Generic; + +namespace Engine.Core; + +public class FastList : IReadOnlyList, IEnumerable where T : notnull +{ + private readonly List items = []; + private readonly Dictionary indexMap = []; + + public int Count => items.Count; + + public T this[int index] => items[index]; + + public void Add(T item) + { + indexMap[item] = items.Count; + items.Add(item); + } + + public void RemoveAt(int i) => Remove(items[i], i); + public bool Remove(T item) + { + if (!indexMap.TryGetValue(item, out int index)) + return false; + + Remove(item, index); + + return true; + } + + private void Remove(T item, int index) + { + int lastIndex = items.Count - 1; + T lastItem = items[lastIndex]; + + items[index] = lastItem; + indexMap[lastItem] = index; + + items.RemoveAt(lastIndex); + indexMap.Remove(item); + } + + public void Insert(int index, T item) + { + items.Insert(index, item); + + for (int i = index; i < items.Count; i++) + indexMap[items[i]] = i; + } + + public void Clear() + { + items.Clear(); + indexMap.Clear(); + } + + public bool Contains(T item) => indexMap.ContainsKey(item); + + public int BinarySearch(T item, IComparer? comparer = null) => items.BinarySearch(item, comparer); + public void Sort(IComparer comparer) + { + items.Sort(comparer); + + for (int i = 0; i < items.Count; i++) + indexMap[items[i]] = i; + } + + public IEnumerator GetEnumerator() => items.GetEnumerator(); + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + + public FastList() { } + public FastList(int count) { items.Capacity = count; } +}