std/ecs/query
std/ecs/src/query.trb
fn query
fn query<Space, Component>(space: Space): Iterate<(Entity, Component)> where Space: Store<Component>
Every entity that has a Component in space, with the value, in the order of the column.
A query answers an Iterate of tuples and holds a copy of the column for as long as it is walked: the loop may
spawn, attach and detach on the live group, and none of it reaches the rows being visited (ECS.md, "Structural
change while a query runs").
Examples
use Column from "std/ecs"
type Health with Equals, Show {
points: Int
}
type Vitals {
var health: Column<Health> = Column()
}
extend Vitals with Store<Health> {
fn column(): Column<Health> {
health
}
var fn attach(entity: Entity, value: Health) {
health.put entity, value
}
var fn detach(entity: Entity) {
health.remove entity
}
}
var vitals = Vitals()
vitals.attach Entity(0), Health(3)
vitals.attach Entity(1), Health(5)
var total = 0
for (entity, health) in query<Vitals, Health>(vitals) {
total = total + health.points + entity.index
}
assert(total == 9)
fn pairs
fn pairs<FirstSpace, SecondSpace, First, Second>(first: FirstSpace, second: SecondSpace): Iterate<(Entity, First, Second)> where FirstSpace: Store<First>, SecondSpace: Store<Second>
Every entity that has a First in first and a Second in second, in the order of the first column; an entity
missing from the second drops out. The with-filter of other engines is one more column here, and the
without-filter is pairs(...).filter { !other.column().has(_.0) }.
The order is a function of the operations that built the columns: the column of the first group is walked and the second is only probed, so which group drives the query is the order the caller writes them in.
fn triples
fn triples<FirstSpace, SecondSpace, ThirdSpace, First, Second, Third>(first: FirstSpace, second: SecondSpace, third: ThirdSpace): Iterate<(Entity, First, Second, Third)> where FirstSpace: Store<First>, SecondSpace: Store<Second>, ThirdSpace: Store<Third>
Every entity that has a First, a Second and a Third, in the order of the first column. See pairs.
fn quadruples
fn quadruples<FirstSpace, SecondSpace, ThirdSpace, FourthSpace, First, Second, Third, Fourth>(first: FirstSpace, second: SecondSpace, third: ThirdSpace, fourth: FourthSpace): Iterate<(Entity, First, Second, Third, Fourth)> where FirstSpace: Store<First>, SecondSpace: Store<Second>, ThirdSpace: Store<Third>, FourthSpace: Store<Fourth>
Every entity that has a First, a Second, a Third and a Fourth, in the order of the first column. Four is
where it stops: a system that reads five component types wants two queries. See pairs.