78 lines
2.7 KiB
C
78 lines
2.7 KiB
C
#include <union.h>
|
|
#include <stdio.h>
|
|
|
|
// This example shows how to use union relationships. Union relationships behave
|
|
// much like exclusive relationships in that entities can have only one instance
|
|
// and that adding an instance removes the previous instance.
|
|
//
|
|
// What makes union relationships stand out is that changing the relationship
|
|
// target doesn't change the archetype of an entity. This allows for quick
|
|
// switching of tags, which can be useful when encoding state machines in ECS.
|
|
//
|
|
// There is a tradeoff, and that is that because a single archetype can contain
|
|
// entities with multiple targets, queries need to do a bit of extra work to
|
|
// only return the requested target.
|
|
|
|
int main(int argc, char *argv[]) {
|
|
ecs_world_t *world = ecs_init_w_args(argc, argv);
|
|
|
|
// Create a Movement state machine with 3 states
|
|
ECS_ENTITY(world, Movement, Union);
|
|
ECS_TAG(world, Standing);
|
|
ECS_TAG(world, Walking);
|
|
ECS_TAG(world, Running);
|
|
|
|
// Create a Direction state machine with 4 states
|
|
ECS_ENTITY(world, Direction, Union);
|
|
ECS_TAG(world, Front);
|
|
ECS_TAG(world, Back);
|
|
ECS_TAG(world, Left);
|
|
ECS_TAG(world, Right);
|
|
|
|
// Create a query that subscribers for all entities that have a Direction
|
|
// and that are walking.
|
|
ecs_query_t *q = ecs_query(world, {
|
|
.filter.terms = {
|
|
{ .id = ecs_pair(Movement, Walking) },
|
|
{ .id = ecs_pair(Direction, EcsWildcard) }
|
|
}
|
|
});
|
|
|
|
// Create a few entities with various state combinations
|
|
ecs_entity_t e1 = ecs_new_entity(world, "e1");
|
|
ecs_add_pair(world, e1, Movement, Walking);
|
|
ecs_add_pair(world, e1, Direction, Front);
|
|
|
|
ecs_entity_t e2 = ecs_new_entity(world, "e2");
|
|
ecs_add_pair(world, e2, Movement, Running);
|
|
ecs_add_pair(world, e2, Direction, Left);
|
|
|
|
ecs_entity_t e3 = ecs_new_entity(world, "e3");
|
|
ecs_add_pair(world, e3, Movement, Running);
|
|
ecs_add_pair(world, e3, Direction, Right);
|
|
|
|
// Add Walking to e3. This will remove the Running case
|
|
ecs_add_pair(world, e3, Movement, Walking);
|
|
|
|
// Iterate query as usual
|
|
ecs_iter_t it = ecs_query_iter(world, q);
|
|
while (ecs_iter_next(&it)) {
|
|
ecs_entity_t *movement = ecs_field(&it, ecs_entity_t, 1);
|
|
ecs_entity_t *direction = ecs_field(&it, ecs_entity_t, 2);
|
|
|
|
for (int i = 0; i < it.count; i ++) {
|
|
printf("%s: Movement: %s, Direction: %s\n",
|
|
ecs_get_name(world, it.entities[i]),
|
|
ecs_get_name(world, movement[i]),
|
|
ecs_get_name(world, direction[i]));
|
|
}
|
|
}
|
|
|
|
// Output:
|
|
// e3: Movement: Walking, Direction: Back
|
|
// e1: Movement: Walking, Direction: Front
|
|
|
|
// Cleanup
|
|
return ecs_fini(world);
|
|
}
|