#include #include // 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); }