#include #include // This example shows how to use singleton components in queries. // Singleton component typedef struct { double value; } Gravity; // Entity component typedef struct { double x, y; } Velocity; int main(int argc, char *argv[]) { ecs_world_t *ecs = ecs_init_w_args(argc, argv); ECS_COMPONENT(ecs, Gravity); ECS_COMPONENT(ecs, Velocity); // Set singleton ecs_singleton_set(ecs, Gravity, { 9.81 }); ecs_entity_t e1 = ecs_new_entity(ecs, "e1"); ecs_entity_t e2 = ecs_new_entity(ecs, "e2"); ecs_entity_t e3 = ecs_new_entity(ecs, "e3"); // Set Velocity ecs_set(ecs, e1, Velocity, {0, 0}); ecs_set(ecs, e2, Velocity, {0, 1}); ecs_set(ecs, e3, Velocity, {0, 2}); // Create query that matches Gravity as singleton ecs_query_t *q = ecs_query(ecs, { .filter.terms = { { .id = ecs_id(Velocity) }, // A singleton is a component matched on itself { .id = ecs_id(Gravity), .src.id = ecs_id(Gravity) } }, // Optional, but lets us iterate entities in bulk even though the query // returns fields with mixed counts (see query manual). .filter.instanced = true }); // In a query string expression you can use the $ shortcut for singletons: // Velocity, Gravity($) ecs_iter_t it = ecs_query_iter(ecs, q); while (ecs_query_next(&it)) { Velocity *v = ecs_field(&it, Velocity, 1); Gravity *g = ecs_field(&it, Gravity, 2); for (int i = 0; i < it.count; i ++) { // Make sure to access g as a pointer, as we only have a single // instance of the Gravity component. v[i].y += g->value; printf("%s velocity is {%f, %f}\n", ecs_get_name(ecs, it.entities[i]), v[i].x, v[i].y); } } // Output // e1 velocity is {0.000000, 9.810000} // e2 velocity is {0.000000, 10.810000} // e3 velocity is {0.000000, 11.810000} ecs_fini(ecs); }