Skip to content
Flecs v4.1
queries/hierarchies

  • C

    View on GitHub

    1#include <hierarchies.h>
    2#include <stdio.h>
    3
    4// Simple transform location with 2D location
    5typedef struct {
    6 double x;
    7 double y;
    8} Transform;
    9
    10// Create two typedefs types for world and local transform
    11typedef Transform WorldTransform;
    12typedef Transform LocalTransform;
    13
    14int main(int argc, char *argv[]) {
    15 ecs_world_t *ecs = ecs_init_w_args(argc, argv);
    16
    17 ECS_COMPONENT(ecs, LocalTransform);
    18 ECS_COMPONENT(ecs, WorldTransform);
    19
    20 // Whenever we add LocalTransform, also add WorldTransform
    21 ecs_add_pair(ecs, ecs_id(LocalTransform), EcsWith, ecs_id(WorldTransform));
    22
    23 // Create a hierarchy. For an explanation see the entities/hierarchy example
    24 ecs_entity_t sun = ecs_entity(ecs, { .name = "Sun" });
    25 ecs_set(ecs, sun, LocalTransform, {1, 1});
    26
    27 ecs_entity_t mercury = ecs_entity(ecs, { .name = "Mercury", .parent = sun });
    28 ecs_set(ecs, mercury, LocalTransform, {1, 1});
    29
    30 ecs_entity_t venus = ecs_entity(ecs, { .name = "Venus", .parent = sun });
    31 ecs_set(ecs, venus, LocalTransform, {2, 2});
    32
    33 ecs_entity_t earth = ecs_entity(ecs, { .name = "Earth", .parent = sun });
    34 ecs_set(ecs, earth, LocalTransform, {3, 3});
    35
    36 ecs_entity_t moon = ecs_entity(ecs, { .name = "Moon", .parent = earth });
    37 ecs_set(ecs, moon, LocalTransform, {0.1, 0.1});
    38
    39 // Create a hierarchical query to compute the global transform from the
    40 // local transform and the parent transform.
    41 ecs_query_t *q = ecs_query(ecs, {
    42 .terms = {
    43 // Read from entity's Local transform
    44 { .id = ecs_id(LocalTransform), .inout = EcsIn },
    45 // Write to entity's World transform
    46 { .id = ecs_id(WorldTransform), .inout = EcsOut },
    47
    48 // Read from parent's World transform
    49 {
    50 .id = ecs_id(WorldTransform),
    51 .inout = EcsIn,
    52 // Get from the parent in breadth-first order (cascade)
    53 .src.id = EcsCascade,
    54 // Make parent term optional so we also match the root (sun)
    55 .oper = EcsOptional
    56 }
    57 }
    58 });
    59
    60 // Do the transform
    61 ecs_iter_t it = ecs_query_iter(ecs, q);
    62 while (ecs_query_next(&it)) {
    63 const LocalTransform *p = ecs_field(&it, LocalTransform, 0);
    64 WorldTransform *p_out = ecs_field(&it, WorldTransform, 1);
    65 const WorldTransform *p_parent = ecs_field(&it, WorldTransform, 2);
    66
    67 // Inner loop, iterates entities in archetype
    68 for (int i = 0; i < it.count; i ++) {
    69 p_out[i].x = p[i].x;
    70 p_out[i].y = p[i].y;
    71 if (p_parent) {
    72 p_out[i].x += p_parent->x;
    73 p_out[i].y += p_parent->y;
    74 }
    75 }
    76 }
    77
    78 // Print ecs transforms
    79 it = ecs_each(ecs, WorldTransform);
    80 while (ecs_each_next(&it)) {
    81 WorldTransform *p = ecs_field(&it, WorldTransform, 0);
    82 for (int i = 0; i < it.count; i ++) {
    83 printf("%s: {%f, %f}\n", ecs_get_name(ecs, it.entities[i]),
    84 p[i].x, p[i].y);
    85 }
    86 }
    87
    88 return ecs_fini(ecs);
    89}
    const ecs_entity_t EcsWith
    Ensure that a component is always added together with another component.
    FLECS_API const ecs_entity_t ecs_id(EcsDocDescription)
    Component ID for EcsDocDescription.
    ecs_id_t ecs_entity_t
    An entity identifier.
    Definition flecs.h:395
    struct ecs_world_t ecs_world_t
    A world is the container for all ECS data and supporting features.
    Definition flecs.h:439
    bool ecs_each_next(ecs_iter_t *it)
    Progress an iterator created with ecs_each_id().
    #define ecs_add_pair(world, subject, first, second)
    Add a pair to an entity.
    Definition flecs_c.h:275
    #define ecs_entity(world,...)
    Shorthand for creating an entity with ecs_entity_init().
    Definition flecs_c.h:188
    #define ECS_COMPONENT(world, id)
    Declare and define a component.
    Definition flecs_c.h:98
    #define ecs_query(world,...)
    Shorthand for creating a query with ecs_query_init().
    Definition flecs_c.h:215
    #define ecs_set(world, entity, component,...)
    Set a component value.
    Definition flecs_c.h:310
    #define ecs_field(it, T, index)
    Get field data for a component.
    Definition flecs_c.h:720
    #define ecs_each(world, id)
    Iterate entities with a component.
    Definition flecs_c.h:931
    const char * ecs_get_name(const ecs_world_t *world, ecs_entity_t entity)
    Get the name of an entity.
    bool ecs_query_next(ecs_iter_t *it)
    Progress a query iterator.
    #define EcsCascade
    Sort results breadth-first.
    Definition flecs.h:780
    ecs_iter_t ecs_query_iter(const ecs_world_t *world, const ecs_query_t *query)
    Create a query iterator.
    @ EcsOut
    Term is only written.
    Definition flecs.h:732
    @ EcsIn
    Term is only read.
    Definition flecs.h:731
    @ EcsOptional
    The term may match.
    Definition flecs.h:740
    int ecs_fini(ecs_world_t *world)
    Delete a world.
    ecs_world_t * ecs_init_w_args(int argc, char *argv[])
    Create a new world with arguments.
    Iterator.
    Definition flecs.h:1183
    Queries are lists of constraints (terms) that match entities.
    Definition flecs.h:858