oecs-sharp/OECS/OrderedEntitySet.cs

49 lines
1.4 KiB
C#

using System.Collections;
namespace OECS;
/// <summary>
/// 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.
/// </summary>
internal sealed class OrderedEntitySet : IReadOnlyCollection<Entity>
{
// 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<Entity> _order = new();
private readonly Dictionary<Entity, int> _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;
}
public IEnumerator<Entity> GetEnumerator() => _order.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}