using System.Collections; namespace OECS; /// /// An insertion-ordered set of entities that supports O(1) Add, Remove, and Contains /// while iterating in insertion order. Drop-in for cases where both /// stable ordering and fast membership checks are needed. /// /// Not thread-safe. /// internal sealed class OrderedEntitySet : IReadOnlyCollection { // Entities are stored in a packed list; a secondary dictionary maps // each entity to its index for O(1) removal via swap-with-last. private readonly List _order = new(); private readonly Dictionary _index = new(); public int Count => _order.Count; public bool Add(Entity entity) { if (_index.ContainsKey(entity)) return false; _index[entity] = _order.Count; _order.Add(entity); return true; } public bool Remove(Entity entity) { if (!_index.Remove(entity, out var idx)) return false; int lastIdx = _order.Count - 1; if (idx < lastIdx) { var last = _order[lastIdx]; _order[idx] = last; _index[last] = idx; } _order.RemoveAt(lastIdx); return true; } /// /// Reorders the set to match the given entity order. /// The provided list must contain exactly the same entities as the set. /// public void Reorder(IReadOnlyList ordered) { _order.Clear(); _index.Clear(); for (int i = 0; i < ordered.Count; i++) { _order.Add(ordered[i]); _index[ordered[i]] = i; } } public IEnumerator GetEnumerator() => _order.GetEnumerator(); IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); }