Skip to content
Flecs v4.1
relationships/relation_component

  • C

    View on GitHub

    1#include <relation_component.h>
    2#include <stdio.h>
    3
    4// This example shows how relationships can be combined with components to attach
    5// data to a relationship.
    6
    7// Some demo components:
    8
    9typedef struct {
    10 double amount;
    11} Requires;
    12
    13typedef struct {
    14 double timeout;
    15} Expires;
    16
    17typedef struct {
    18 double x;
    19 double y;
    20} Position;
    21
    22int main(int argc, char *argv[]) {
    23 ecs_world_t *ecs = ecs_init_w_args(argc, argv);
    24
    25 ECS_COMPONENT(ecs, Requires);
    26 ECS_COMPONENT(ecs, Expires);
    27 ECS_COMPONENT(ecs, Position);
    28
    29 ECS_TAG(ecs, Gigawatts);
    30 ECS_TAG(ecs, MustHave);
    31
    32 // When one element of a pair is a component and the other element is a tag,
    33 // the pair assumes the type of the component.
    34 ecs_entity_t e1 = ecs_new(ecs);
    35 ecs_set_pair(ecs, e1, Requires, Gigawatts, {1.21});
    36 const Requires *r = ecs_get_pair(ecs, e1, Requires, Gigawatts);
    37 printf("requires: %.2f\n", r->amount);
    38
    39 // The component can be either the first or second part of a pair:
    40 ecs_entity_t e2 = ecs_new(ecs);
    41 ecs_set_pair_second(ecs, e2, Gigawatts, Requires, {1.21});
    42 r = ecs_get_pair_second(ecs, e2, Gigawatts, Requires);
    43 printf("requires: %.2f\n", r->amount);
    44
    45 // Note that <Requires, Gigawatts> and <Gigawatts, Requires> are two
    46 // different pairs, and can be added to an entity at the same time.
    47
    48 // If both parts of a pair are components, the pair assumes the type of
    49 // the first element:
    50 ecs_entity_t e3 = ecs_new(ecs);
    51 ecs_set_pair(ecs, e3, Expires, ecs_id(Position), {0.5});
    52 const Expires *e = ecs_get_pair(ecs, e3, Expires, ecs_id(Position));
    53 printf("expires: %.1f\n", e->timeout);
    54
    55 // You can prevent a pair from assuming the type of a component by adding
    56 // the Tag property to a relationship:
    57 ecs_add_id(ecs, MustHave, EcsPairIsTag);
    58
    59 // Even though Position is a component, <MustHave, Position> contains no
    60 // data because MustHave has the Tag property.
    61 ecs_new_w_pair(ecs, MustHave, ecs_id(Position));
    62
    63 // The id::type_id method can be used to find the component type for a pair:
    64 ecs_entity_t type_id;
    65 char *type_str;
    66
    67 type_id = ecs_get_typeid(ecs, ecs_pair(ecs_id(Requires), Gigawatts));
    68 type_str = ecs_get_path(ecs, type_id);
    69 printf("%s\n", type_str);
    70 ecs_os_free(type_str);
    71
    72 type_id = ecs_get_typeid(ecs, ecs_pair(Gigawatts, ecs_id(Requires)));
    73 type_str = ecs_get_path(ecs, type_id);
    74 printf("%s\n", type_str);
    75 ecs_os_free(type_str);
    76
    77 type_id = ecs_get_typeid(ecs, ecs_pair(ecs_id(Expires), ecs_id(Position)));
    78 type_str = ecs_get_path(ecs, type_id);
    79 printf("%s\n", type_str);
    80 ecs_os_free(type_str);
    81
    82 type_id = ecs_get_typeid(ecs, ecs_pair(MustHave, ecs_id(Position)));
    83 type_str = ecs_get_path(ecs, type_id);
    84 printf("%s\n", type_str);
    85 ecs_os_free(type_str);
    86
    87 // When querying for a relationship, provide both parts of the pair:
    88 ecs_query_t *q = ecs_query(ecs, {
    89 .terms = {
    90 { .id = ecs_pair(ecs_id(Requires), Gigawatts) }
    91 }
    92 });
    93
    94 // When iterating, always use the pair type:
    95 ecs_iter_t it = ecs_query_iter(ecs, q);
    96 while (ecs_query_next(&it)) {
    97 r = ecs_field(&it, Requires, 0);
    98 for (int i = 0; i < it.count; i ++) {
    99 printf("requires %.2f gigawatts\n", r[i].amount);
    100 }
    101 }
    102
    103 // Output:
    104 // requires: 1.21
    105 // requires: 1.21
    106 // expires: 0.5
    107 // Requires
    108 // Requires
    109 // Expires
    110 // 0
    111 // requires 1.21 gigawatts
    112}
    void ecs_add_id(ecs_world_t *world, ecs_entity_t entity, ecs_id_t component)
    Add a (component) ID to an entity.
    const ecs_entity_t EcsPairIsTag
    Can be added to a relationship to indicate that it should never hold data, even when it or the relati...
    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
    ecs_entity_t ecs_new(ecs_world_t *world)
    Create new entity ID.
    #define ecs_new_w_pair(world, first, second)
    Create a new entity with a pair.
    Definition flecs_c.h:256
    #define ECS_COMPONENT(world, id)
    Declare and define a component.
    Definition flecs_c.h:98
    #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
    #define ecs_get_path(world, child)
    Get path from root.
    Definition flecs_c.h:594
    #define ecs_get_pair_second(world, subject, first, Second)
    Get the second element of a pair.
    Definition flecs_c.h:348
    #define ecs_get_pair(world, subject, First, second)
    Get the first element of a pair.
    Definition flecs_c.h:343
    #define ecs_set_pair_second(world, subject, first, Second,...)
    Set the second element of a pair.
    Definition flecs_c.h:320
    #define ecs_set_pair(world, subject, First, second,...)
    Set the first element of a pair.
    Definition flecs_c.h:314
    #define ecs_field(it, T, index)
    Get field data for a component.
    Definition flecs_c.h:720
    ecs_entity_t ecs_get_typeid(const ecs_world_t *world, ecs_id_t component)
    Get the type for a component.
    bool ecs_query_next(ecs_iter_t *it)
    Progress a query iterator.
    ecs_iter_t ecs_query_iter(const ecs_world_t *world, const ecs_query_t *query)
    Create a query iterator.
    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 <relation_component.h>
    2#include <iostream>
    3
    4// This example shows how relationships can be combined with components to attach
    5// data to a relationship.
    6
    7// Some demo components:
    8
    9struct Requires {
    10 double amount;
    11};
    12
    13struct Gigawatts { };
    14
    15struct Expires {
    16 double timeout;
    17};
    18
    19struct Position {
    20 double x;
    21 double y;
    22};
    23
    24struct MustHave { };
    25
    26int main(int, char*[]) {
    27 flecs::world ecs;
    28
    29 // When one element of a pair is a component and the other element is a tag,
    30 // the pair assumes the type of the component.
    31 flecs::entity e1 = ecs.entity().set<Requires, Gigawatts>({1.21});
    32 const Requires& r1 = e1.get<Requires, Gigawatts>();
    33 std::cout << "requires: " << r1.amount << std::endl;
    34
    35 // The component can be either the first or second part of a pair:
    36 flecs::entity e2 = ecs.entity().set<Gigawatts, Requires>({1.21});
    37 const Requires& r2 = e2.get<Gigawatts, Requires>();
    38 std::cout << "requires: " << r2.amount << std::endl;
    39
    40 // Note that <Requires, Gigawatts> and <Gigawatts, Requires> are two
    41 // different pairs, and can be added to an entity at the same time.
    42
    43 // If both parts of a pair are components, the pair assumes the type of
    44 // the first element:
    45 flecs::entity e3 = ecs.entity().set<Expires, Position>({0.5});
    46 const Expires& e = e3.get<Expires, Position>();
    47 std::cout << "expires: " << e.timeout << std::endl;
    48
    49 // You can prevent a pair from assuming the type of a component by adding
    50 // the Tag property to a relationship:
    51 ecs.component<MustHave>().add(flecs::PairIsTag);
    52
    53 // Even though Position is a component, <MustHave, Position> contains no
    54 // data because MustHave has the Tag property.
    55 ecs.entity().add<MustHave, Position>();
    56
    57 // The id::type_id method can be used to find the component type for a pair:
    58 std::cout << ecs.pair<Requires, Gigawatts>().type_id().path() << "\n";
    59 std::cout << ecs.pair<Gigawatts, Requires>().type_id().path() << "\n";
    60 std::cout << ecs.pair<Expires, Position>().type_id().path() << "\n";
    61 std::cout << ecs.pair<MustHave, Position>().type_id().path() << "\n";
    62
    63 // When querying for a relationship component, add the pair type as template
    64 // argument to the builder:
    65 flecs::query<Requires> q = ecs.query_builder<Requires>()
    66 .term_at(0).second<Gigawatts>() // set second part of pair for first term
    67 .build();
    68
    69 // When iterating, always use the pair type:
    70 q.each([](Requires& rq) {
    71 std::cout << "requires " << rq.amount << " gigawatts\n";
    72 });
    73
    74 // Output:
    75 // requires: 1.21
    76 // requires: 1.21
    77 // expires: 0.5
    78 // ::Requires
    79 // ::Requires
    80 // ::Expires
    81 // 0
    82 // requires 1.21 gigawatts
    83}
    flecs::component< T > component(Args &&... args) const
    Find or register a component.
    Definition impl.hpp:11
    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
    void each(Func &&func) const
    Each iterator.
    Definition iterable.hpp:37
    Typed query.
    Definition impl.hpp:271
    void timeout(ecs_ftime_t timeout)
    Set timeout.
    The world.
    Definition world.hpp:129
    flecs::id pair() const
    Get pair ID from relationship and object.
    Definition impl.hpp:82