Idiomatic foreach over entities with tag

Is there any clean way to iterate over all entities with a (set of) tag(s) in an idiomatic foreach?

What I would expect for it to look like is something like

foreach (Entity entity in SystemAPI.Query().WithAll<SomeTag>().WithEntityAccess()) 
{
    // Add component or something like that
}

This does not work since there is no overload of Query() with no type parameters.

One solution that could work is

foreach ((SomeTag tag, Entity entity) in SystemAPI.Query<SomeTag>().WithEntityAccess()) 
{
    // Add component or something like that
}

however that seems rather dirty since no access to SomeTag is needed (convolutes code).

Is there a good solution for this?
If not, would it be possible to add a SystemAPI.Query() with no type parameters as a feature request?

Thinking about the issue in a different framing, since no other data is read, no branching etc. per entity can be done in the given example so the operation might just as well be done on an entire EntityQuery with APIs like EntityManager.AddComponentData() so I guess that would be the solution.

Still happy to hear other ideas or examples on cases where that solution would not work.

IJobEntity job + [WithAll(typeof(T))] is the cleanest one.
Alternatively - build EntityQuery, fed it as a parameter to the job.

Second is nicer, since you can re-use that job later on in a different system with different type constraint (if neccessary).

Bonus points - you don’t need to rewrite it later on and it can be actually moved away from the main thread at will.

E.g.

[WithAll(typeof(SomeTag))]
public partial struct SomethingJob : IJobEntity {
     public void Execute(Entity entity) { ... }
}

Or

private EntityQuery _someTagQuery;

public void OnCreate(...){
    var allocator = state.WorldUpdateAllocator;
    _someTagQuery = new EntityQueryBuilder(allocator).WithAll<SomeTag>().Build();
}

public void OnUpdate(...) {
    new SomeJob().Schedule(_someTagQuery); // or Run
    // Which should be identical to codegened
    state.Dependency = new SomeJob().Schedule(_someTagQuery, state.Dependency)); 
}

Idiomatic foreach is a nice crutch, and honestly, its a step back from EFE.
You can also ommit not required parameters, but it doesn’t make it less ugly of a construct.

1 Like