namespace OECS; /// /// Accumulates entries during a system run. /// /// Deduplication: if the same (entity, kind, componentType) change is marked /// multiple times, only one entry is kept. Entity-level changes (Added/Removed) /// take precedence over component-level changes for the same entity. /// internal class ChangeSet { private readonly List _changes = new(); private readonly HashSet<(Entity Entity, ChangeKind Kind, Type? ComponentType)> _dedup = new(); /// /// All accumulated changes in insertion order. /// public IReadOnlyList Changes => _changes; /// /// Number of changes in this set. /// public int Count => _changes.Count; /// /// Records that an entity was created. /// public void MarkEntityAdded(Entity entity) { TryAdd(new EntityChange(entity, ChangeKind.EntityAdded)); } /// /// Records that an entity was destroyed. /// public void MarkEntityRemoved(Entity entity) { TryAdd(new EntityChange(entity, ChangeKind.EntityRemoved)); } /// /// Records that a component was added to an entity. /// public void MarkComponentAdded(Entity entity, Type componentType) { TryAdd(new EntityChange(entity, ChangeKind.ComponentAdded, componentType)); } /// /// Records that a component was removed from an entity. /// public void MarkComponentRemoved(Entity entity, Type componentType) { TryAdd(new EntityChange(entity, ChangeKind.ComponentRemoved, componentType)); } /// /// Records that a component's value was modified. /// Must be called explicitly by user code via . /// public void MarkComponentModified(Entity entity, Type componentType) { TryAdd(new EntityChange(entity, ChangeKind.ComponentModified, componentType)); } /// /// Clears all accumulated changes. /// public void Clear() { _changes.Clear(); _dedup.Clear(); } private void TryAdd(EntityChange change) { var key = (change.Entity, change.Kind, change.ComponentType); if (_dedup.Add(key)) { _changes.Add(change); } } }