Skip to content
Flecs v4.1
queries/cyclic_variables

  • C

    View on GitHub

    1#include <cyclic_variables.h>
    2#include <stdio.h>
    3
    4// This example shows how a query may have terms with cyclic dependencies on
    5// variables.
    6
    7int main(int argc, char *argv[]) {
    8 ecs_world_t *ecs = ecs_init_w_args(argc, argv);
    9
    10 ECS_TAG(ecs, Likes); // Likes relationship
    11
    12 ecs_entity_t bob = ecs_entity(ecs, { .name = "Bob" });
    13 ecs_entity_t alice = ecs_entity(ecs, { .name = "Alice" });
    14 ecs_entity_t john = ecs_entity(ecs, { .name = "John" });
    15 ecs_entity_t jane = ecs_entity(ecs, { .name = "Jane" });
    16
    17 ecs_add_pair(ecs, bob, Likes, alice);
    18 ecs_add_pair(ecs, alice, Likes, bob);
    19 ecs_add_pair(ecs, john, Likes, jane);
    20 ecs_add_pair(ecs, jane, Likes, john);
    21 ecs_add_pair(ecs, bob, Likes, jane); // inserting a bit of drama
    22
    23 // The following query will only return entities that have a cyclic Likes
    24 // relationship- that is they must both like each other.
    25 //
    26 // The equivalent query in the DSL is:
    27 // Likes($X, $Y), Likes($Y, $X)
    28 //
    29 // This is also an example of a query where all sources are variables. By
    30 // default queries use the builtin "this" variable as subject, which is what
    31 // populates the entities array in the query result (accessed by the
    32 // iter::entity function).
    33 //
    34 // Because this query does not use This at all, the entities array will not
    35 // be populated, and it.count() will always be 0.
    36 // Create a query to find all ranged units
    37 ecs_query_t *q = ecs_query(ecs, {
    38 .terms = {
    39 { .first.id = Likes, .src.name = "$x", .second.name = "$y" },
    40 { .first.id = Likes, .src.name = "$y", .second.name = "$x" }
    41 }
    42 });
    43
    44 // Lookup the index of the variables. This will let us quickly lookup their
    45 // values while we're iterating.
    46 int x_var = ecs_query_find_var(q, "x");
    47 int y_var = ecs_query_find_var(q, "y");
    48
    49 // Iterate the query
    50 ecs_iter_t it = ecs_query_iter(ecs, q);
    51 while (ecs_query_next(&it)) {
    52 ecs_entity_t x = ecs_iter_get_var(&it, x_var);
    53 ecs_entity_t y = ecs_iter_get_var(&it, y_var);
    54 printf("%s likes %s\n", ecs_get_name(ecs, x), ecs_get_name(ecs, y));
    55 }
    56
    58
    59 // Output
    60 // Bob likes Alice
    61 // Jane likes John
    62 // John likes Jane
    63 // Alice likes Bob
    64
    65 // Note that the query returns each pair twice. The reason for this is that
    66 // the goal of the query engine is to return all "facts" that are true
    67 // within the given constraints. Since we did not give it any constraints
    68 // that would favor a person being matched by X or Y, the query
    69 // returns both.
    70
    71 return ecs_fini(ecs);
    72}
    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
    #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_TAG(world, id)
    Declare and define a tag.
    Definition flecs_c.h:59
    #define ecs_query(world,...)
    Shorthand for creating a query with ecs_query_init().
    Definition flecs_c.h:215
    ecs_entity_t ecs_iter_get_var(ecs_iter_t *it, int32_t var_id)
    Get the value of an iterator variable as an entity.
    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.
    int32_t ecs_query_find_var(const ecs_query_t *query, const char *name)
    Find a variable index.
    void ecs_query_fini(ecs_query_t *query)
    Delete a query.
    ecs_iter_t ecs_query_iter(const ecs_world_t *world, const ecs_query_t *query)
    Create a query iterator.
    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

  • C++

    View on GitHub

    1#include <cyclic_variables.h>
    2#include <iostream>
    3
    4// This example shows how a query may have terms with cyclic dependencies on
    5// variables.
    6
    7struct Likes { };
    8
    9int main(int, char *[]) {
    10 flecs::world ecs;
    11
    12 flecs::entity bob = ecs.entity("Bob");
    13 flecs::entity alice = ecs.entity("Alice");
    14 flecs::entity john = ecs.entity("John");
    15 flecs::entity jane = ecs.entity("Jane");
    16
    17 bob.add<Likes>(alice);
    18 alice.add<Likes>(bob);
    19 john.add<Likes>(jane);
    20 jane.add<Likes>(john);
    21 bob.add<Likes>(jane); // inserting a bit of drama
    22
    23 // The following query will only return entities that have a cyclic Likes
    24 // relationship- that is they must both like each other.
    25 //
    26 // The equivalent query in the DSL is:
    27 // Likes($X, $Y), Likes($Y, $X)
    28 //
    29 // This is also an example of a query where all sources are variables. By
    30 // default queries use the builtin "this" variable as subject, which is what
    31 // populates the entities array in the query result (accessed by the
    32 // iter::entity function).
    33 //
    34 // Because this query does not use This at all, the entities array will not
    35 // be populated, and it.count() will always be 0.
    37 .with<Likes>("$Y").src("$X")
    38 .with<Likes>("$X").src("$Y")
    39 .build();
    40
    41 // Lookup the index of the variables. This will let us quickly lookup their
    42 // values while we're iterating.
    43 int x_var = q.find_var("X");
    44 int y_var = q.find_var("Y");
    45
    46 q.each([&](flecs::iter& it, size_t) {
    47 flecs::entity x = it.get_var(x_var);
    48 flecs::entity y = it.get_var(y_var);
    49 std::cout << x.name() << " likes " << y.name() << "\n";
    50 });
    51
    52 // Output
    53 // Alice likes Bob
    54 // Bob likes Alice
    55 // Jane likes John
    56 // John likes Jane
    57
    58 // Note that the query returns each pair twice. The reason for this is that
    59 // the goal of the query engine is to return all "facts" that are true
    60 // within the given constraints. Since we did not give it any constraints
    61 // that would favor a person being matched by X or Y, the query engine
    62 // returns both.
    63}
    flecs::query_builder< Comps... > query_builder(Args &&... args) const
    Create a query builder.
    Definition impl.hpp:342
    flecs::entity entity(Args &&... args) const
    Create an entity.
    Definition impl.hpp:195
    flecs::string_view name() const
    Return the entity name.
    Entity.
    Definition entity.hpp:30
    Class for iterating over query results.
    Definition iter.hpp:68
    flecs::entity get_var(int var_id) const
    Get value of variable by ID.
    Definition iter.hpp:128
    Typed query.
    Definition impl.hpp:271
    The world.
    Definition world.hpp:129