feat: add deferred structural mutations and entity iterators

Implement deferred structural mutations (AddComponent, RemoveComponent,
DestroyEntity) to allow safe modification of the world during
iteration.

Additionally, introduce a new `EntityIterator` API providing zero-
allocation `ref struct` iterators (`Select<T1>`, `Select<T1, T2>`, etc.)
to support manual iteration with early-exit capabilities.

As part of these changes, component access via `GetComponent<T>` during
iteration now automatically marks components as modified.
This commit is contained in:
2026-07-18 21:22:23 +08:00
parent 9aa2a71257
commit f1eddc75ae
5 changed files with 467 additions and 79 deletions
@@ -20,20 +20,20 @@ public struct PlaceMarkCommand : ICommand
if (state.Status != GameStatus.Playing)
return;
// Copy to locals so the lambda in ForEach can capture them
// (this is a struct, so `this` cannot be captured directly).
int row = Row;
int col = Col;
// Find the cell entity at (Row, Col) that has no Mark.
// Use the iterator API with early-exit via break.
var query = world.Query().With<Cell>().Without<Mark>().Build();
Entity? target = null;
world.ForEach(query, (Entity entity, ref Cell cell) =>
using var iter = world.Select<Cell>(query);
while (iter.MoveNext())
{
if (cell.Row == row && cell.Col == col)
target = entity;
});
if (iter.Current1.Row == Row && iter.Current1.Col == Col)
{
target = iter.CurrentEntity;
break;
}
}
if (target == null)
return; // Cell already occupied or invalid position.