Skip to content

New feature: Query Generator #124

Description

@friflo

Query Generator

🚀 New feature in v3.6.0

  <PackageReference Include="Friflo.Engine.ECS" Version="3.6.0" />
  <PackageReference Include="Friflo.Engine.ECS.Generators" Version="3.6.0" />



The goal of the Query Generator is to generate highly efficient query code and reduce the amount of boiler plate to a minimum.
The generator is a C# Source Generator to enable seamless development.

A super efficient way to execute queries is Enumerate Query Chunks. But writing them by hand is awkward.
The query generator takes over this task for every method annotated with [Query].
It automatically generates an additional method suffixed with Query. So given:

    [Query]
    [AllTags<IsAlive>]
    void MovePosition(ref Position position, float deltaTime) {
        position.x += deltaTime;
    }

The code generator creates / updates the method:

    void MovePositionQuery(EntityStore store, float deltaTime) { ... }

This method calls MovePosition(ref Position position) for every matching entity.
Now you can call the generated method to execute the query with:

    MovePositionQuery(store, 0.16f); // calls MovePosition() for all matching entities.

Explanation
The same functionality with a manually written ForEach() is:

    void MovePositionQuery(EntityStore store, float deltaTime)
    {
        var query = store.Query<Position>().AllTags<IsAlive>();
        query.ForEach((ref Position position) => {
            position.x += deltaTime;
        });
    }

The behavior of both approaches is the same.

Comparison

ForEach() Query Generator
ArchetypeQuery creation store.Query<>() creates new ArchetypeQuery instance creates and caches the instances internally
Memory allocation creates an ArchetypeQuery and a ForEach delegate an ArchetypeQuery only at the first call
Execution performance calling the ForEach delegate is expensive [Query] method is called directly - can be inlined

How to enable
To bring the Query Generator alive you need to add Friflo.Engine.ECS.Generators to your csproj with:

<PackageReference Include="Friflo.Engine.ECS.Generators" OutputItemType="Analyzer" ReferenceOutputAssembly="false"/>

This dependency is only used by the compiler. It is not a runtime dependency.

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions