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);
}
}
}