Skip to content
Flecs v4.1
queries/facts

  • C

    View on GitHub

    1#include <facts.h>
    2#include <stdio.h>
    3
    4// This example shows how to use queries for testing facts. A fact is a query
    5// that has no variable elements. Consider a regular ECS query like this:
    6// Position, Velocity
    7//
    8// When written out in full, this query looks like:
    9// Position($this), Velocity($this)
    10//
    11// "this" is a (builtin) query variable that is unknown before we evaluate the
    12// query. Therefore this query does not test a fact, we can't know which values
    13// This will assume.
    14//
    15// An example of a fact-checking query is:
    16// IsA(Cat, Animal)
    17//
    18// This is a fact: the query has no elements that are unknown before evaluating
    19// the query. A query that checks a fact does not return entities, but will
    20// instead return the reasons why a fact is true (if it is true).
    21
    22int main(int argc, char *argv[]) {
    23 ecs_world_t *ecs = ecs_init_w_args(argc, argv);
    24
    25 ECS_TAG(ecs, Likes); // Likes relationship
    26
    27 ecs_entity_t bob = ecs_entity(ecs, { .name = "Bob" });
    28 ecs_entity_t alice = ecs_entity(ecs, { .name = "Alice" });
    29 ecs_entity_t john = ecs_entity(ecs, { .name = "John" });
    30 ecs_entity_t jane = ecs_entity(ecs, { .name = "Jane" });
    31
    32 ecs_add_pair(ecs, bob, Likes, alice);
    33 ecs_add_pair(ecs, alice, Likes, bob);
    34 ecs_add_pair(ecs, john, Likes, jane);
    35 ecs_add_pair(ecs, jane, Likes, john);
    36 ecs_add_pair(ecs, bob, Likes, jane); // inserting a bit of drama
    37
    38 // Create a query that checks if two entities like each other. By itself this
    39 // query is not a fact, but we can use it to check facts by populating both
    40 // of its variables.
    41 //
    42 // The equivalent of this query in the DSL is:
    43 // Likes($X, $Y), Likes($Y, $X)
    44 //
    45 // Instead of using variables we could have created a query that referred the
    46 // entities directly, but then we would have to create a query for each
    47 // fact, vs reusing a single query for multiple facts.
    48 //
    49 // See the setting_variables example for more details
    50 ecs_query_t *friends = ecs_query(ecs, {
    51 .terms = {
    52 { .first.id = Likes, .src.name = "$x", .second.name = "$y" },
    53 { .first.id = Likes, .src.name = "$x", .second.name = "$x" }
    54 }
    55 });
    56
    57 // Lookup the index of the variables.
    58 int x_var = ecs_query_find_var(friends, "x");
    59 int y_var = ecs_query_find_var(friends, "y");
    60
    61 ecs_iter_t it = ecs_query_iter(ecs, friends);
    62 ecs_iter_set_var(&it, x_var, bob);
    63 ecs_iter_set_var(&it, y_var, alice);
    64 printf("Are Bob and Alice friends? %s\n",
    65 ecs_iter_is_true(&it) ? "Yes" : "No");
    66
    67 it = ecs_query_iter(ecs, friends);
    68 ecs_iter_set_var(&it, x_var, bob);
    69 ecs_iter_set_var(&it, y_var, john);
    70 printf("Are Bob and John friends? %s\n",
    71 ecs_iter_is_true(&it) ? "Yes" : "No");
    72
    73 it = ecs_query_iter(ecs, friends);
    74 ecs_iter_set_var(&it, x_var, jane);
    75 ecs_iter_set_var(&it, y_var, john);
    76 printf("Are Jane and John friends? %s\n",
    77 ecs_iter_is_true(&it) ? "Yes" : "No");
    78
    79 // It doesn't matter who we assign to X or Y. After the variables are
    80 // substituted, either yields a fact that is true.
    81 it = ecs_query_iter(ecs, friends);
    82 ecs_iter_set_var(&it, x_var, john);
    83 ecs_iter_set_var(&it, y_var, jane);
    84 printf("Are John and Jane friends? %s\n",
    85 ecs_iter_is_true(&it) ? "Yes" : "No");
    86
    87 ecs_query_fini(friends);
    88
    89 // Output
    90 // Are Bob and Alice friends? Yes
    91 // Are Bob and John friends? No
    92 // Are Jane and John friends? Yes
    93 // Are John and Jane friends? Yes
    94
    95 return ecs_fini(ecs);
    96}
    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
    bool ecs_iter_is_true(ecs_iter_t *it)
    Test if an iterator is true.
    void ecs_iter_set_var(ecs_iter_t *it, int32_t var_id, ecs_entity_t entity)
    Set the value for an iterator variable.
    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 <facts.h>
    2#include <iostream>
    3
    4// This example shows how to use queries for testing facts. A fact is a query
    5// that has no variable elements. Consider a regular ECS query like this:
    6// Position, Velocity
    7//
    8// When written out in full, this query looks like:
    9// Position($this), Velocity($this)
    10//
    11// "this" is a (builtin) query variable that is unknown before we evaluate the
    12// query. Therefore this query does not test a fact, we can't know which values
    13// This will assume.
    14//
    15// An example of a fact-checking query is:
    16// IsA(Cat, Animal)
    17//
    18// This is a fact: the query has no elements that are unknown before evaluating
    19// the query. A query that checks a fact does not return entities, but will
    20// instead return the reasons why a fact is true (if it is true).
    21
    22struct Likes { };
    23
    24int main(int, char *[]) {
    25 flecs::world ecs;
    26
    27 flecs::entity bob = ecs.entity("Bob");
    28 flecs::entity alice = ecs.entity("Alice");
    29 flecs::entity jane = ecs.entity("Jane");
    30 flecs::entity john = ecs.entity("John");
    31
    32 bob.add<Likes>(alice);
    33 alice.add<Likes>(bob);
    34 jane.add<Likes>(john);
    35 john.add<Likes>(jane);
    36
    37 bob.add<Likes>(john); // bit of drama
    38
    39 // Create a query that checks if two entities like each other. By itself this
    40 // query is not a fact, but we can use it to check facts by populating both
    41 // of its variables.
    42 //
    43 // The equivalent query in the DSL is:
    44 // Likes($x, $y), Likes($y, $x)
    45 //
    46 // Instead of using variables we could have created a query that referred the
    47 // entities directly, but then we would have to create a query for each
    48 // fact, vs reusing a single query for multiple facts.
    49 flecs::query<> friends = ecs.query_builder()
    50 .with<Likes>("$y").src("$x")
    51 .with<Likes>("$x").src("$y")
    52 .build();
    53
    54 int x_var = friends.find_var("x");
    55 int y_var = friends.find_var("y");
    56
    57 // Check a few facts
    58
    59 std::cout << "Are Bob and Alice friends? " <<
    60 (friends.iter()
    61 .set_var(x_var, bob)
    62 .set_var(y_var, alice)
    63 .is_true() ? "Yes\n" : "No\n");
    64
    65 std::cout << "Are Bob and John friends? " <<
    66 (friends.iter()
    67 .set_var(x_var, bob)
    68 .set_var(y_var, john)
    69 .is_true() ? "Yes\n" : "No\n");
    70
    71 std::cout << "Are Jane and John friends? " <<
    72 (friends.iter()
    73 .set_var(x_var, jane)
    74 .set_var(y_var, john)
    75 .is_true() ? "Yes\n" : "No\n");
    76
    77 // It doesn't matter who we assign to X or Y. After the variables are
    78 // substituted, either yields a fact that is true.
    79 std::cout << "Are John and Jane friends? " <<
    80 (friends.iter()
    81 .set_var(x_var, john)
    82 .set_var(y_var, jane)
    83 .is_true() ? "Yes\n" : "No\n");
    84
    85 // Output
    86 // Are Bob and Alice friends? Yes
    87 // Are Bob and John friends? No
    88 // Are Jane and John friends? Yes
    89 // Are John and Jane friends? Yes
    90}
    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
    Entity.
    Definition entity.hpp:30
    Typed query.
    Definition impl.hpp:271
    The world.
    Definition world.hpp:129