Arch.System.SourceGenerator
What's the point of organized queries if it's sooo much work to write them? We have a solution!
Last updated
What's the point of organized queries if it's sooo much work to write them? We have a solution!
Last updated
I know, I know... writing queries is always sooo much work. If only you could have it all generated... wait... you can!
The Arch.System.SourceGenerator
package provides some code generation utils. With them, queries can be written virtually by themselves which saves some boilerplate code.
Query methods can be generated in as long as they are partial. However it makes most sense in the BaseSystem
. The attributes can be used to meaningfully describe what query to generate, and the query will always call the annotated method. And the best, they can even be called manually!
Let's take a look at the whole thing and what is possible with it.
Again, there are attributes without generics that accept types. In addition, you can also pass an entity
in the method signature of a [Query]
to refer to the current entity. In addition to ref
, you can also use in
or out
or omit the modifier altogether.
Looks simple, doesn't it? But perhaps also a little confusing because you don't yet know what exactly is happening here. Let me explain it to you.
Each method marked with [Query]
is extended to a Query
by the source generation and called once for each Entity
that matches it. The method signature and additional annotations act as a filter. This means that the MoveEntity
method from above is called for each Entity
with Position
and Velocity
. We only write the method with which we process each Entity
and what we need... and Arch.System.SourceGenerator
takes care of the rest.
A method with the same name and query is generated for each of these selected methods. This query method then calls our selected method for each Entity
. E.g. MoveEntity
which is getting called for each fitting Entity
and MoveEntityQuery
, the generated method that runs the query and calls MoveEntity
for each Entity
. This happens for every method within a class that has been marked with Query
. So also for StopDeadEntities
.
In addition, if BaseSystem.Update
has not been implemented itself, a BaseSystem.Update
is generated which calls all Queries
according to their sequence in the system. So all you have to do is call BaseSystem.Update()
or the generated query directly.
It can be that easy, I bet that blew your mind, didn't it?