Skip to content
Flecs v4.1
entities/parent_hierarchy

  • C

    View on GitHub

    1#include <parent_hierarchy.h>
    2#include <stdio.h>
    3
    4// ChildOf hierarchies are optimized for scenarios with few parents that have
    5// lots of children. Parent hierarchies are optimized for scenarios with lots of
    6// parents that have a small number of children. See the documentation for more
    7// information:
    8// https://www.flecs.dev/flecs/HierarchiesManual.html#hierarchy-storage
    9//
    10// This example is the same as the hierarchy example, but instead of using
    11// ChildOf hierarchies it uses Parent hierarchies.
    12
    13typedef struct {
    14 double x, y;
    15} Position;
    16
    17// Forward declare component so we can use it from functions other than main
    18ECS_COMPONENT_DECLARE(Position);
    19
    20void iterate_tree(ecs_world_t *world, ecs_entity_t e, Position p_parent) {
    21 // Print hierarchical name of entity & the entity type
    22 char *path_str = ecs_get_path(world, e);
    23 char *type_str = ecs_type_str(world, ecs_get_type(world, e));
    24 printf("%s [%s]\n", path_str, type_str);
    25 ecs_os_free(type_str);
    26 ecs_os_free(path_str);
    27
    28 // Get entity position
    29 const Position *ptr = ecs_get(world, e, Position);
    30
    31 // Calculate actual position
    32 Position p_actual = {ptr->x + p_parent.x, ptr->y + p_parent.y};
    33 printf("{%f, %f}\n\n", p_actual.x, p_actual.y);
    34
    35 // Iterate children recursively
    36 ecs_iter_t it = ecs_children(world, e);
    37 while (ecs_children_next(&it)) {
    38 for (int i = 0; i < it.count; i ++) {
    39 iterate_tree(world, it.entities[i], p_actual);
    40 }
    41 }
    42}
    43
    44int main(int argc, char *argv[]) {
    45 ecs_world_t *world = ecs_init_w_args(argc, argv);
    46
    47 ECS_COMPONENT_DEFINE(world, Position);
    48 ECS_TAG(world, Star);
    49 ECS_TAG(world, Planet);
    50 ECS_TAG(world, Moon);
    51
    52 // Create a simple hierarchy.
    53 // Use the ecs_new_w_parent function to create entities that use Parent
    54 // hierarchies.
    55 //
    56 // Entities can be reparented afterwards by setting the Parent component:
    57 // ecs_set(world, moon, EcsParent, { mars });
    58
    59 ecs_entity_t sun = ecs_entity(world, { .name = "Sun" });
    60 ecs_add(world, sun, Star);
    61 ecs_set(world, sun, Position, {1, 1});
    62
    63 ecs_entity_t mercury = ecs_new_w_parent(world, sun, "Mercury");
    64 ecs_add(world, mercury, Planet);
    65 ecs_set(world, mercury, Position, {1, 1});
    66
    67 ecs_entity_t venus = ecs_new_w_parent(world, sun, "Venus");
    68 ecs_add(world, venus, Planet);
    69 ecs_set(world, venus, Position, {2, 2});
    70
    71 ecs_entity_t earth = ecs_new_w_parent(world, sun, "Earth");
    72 ecs_add(world, earth, Planet);
    73 ecs_set(world, earth, Position, {3, 3});
    74
    75 ecs_entity_t moon = ecs_new_w_parent(world, earth, "Moon");
    76 ecs_add(world, moon, Moon);
    77 ecs_set(world, moon, Position, {0.1, 0.1});
    78
    79 // Is the Moon a child of Earth?
    80 printf("Child of Earth? %d\n\n", ecs_has_pair(world, moon, EcsChildOf, earth));
    81
    82 // Lookup moon by name
    83 ecs_entity_t e = ecs_lookup(world, "Sun.Earth.Moon");
    84 char *path = ecs_get_path(world, e);
    85 printf("Moon found: %s\n\n", path);
    86 ecs_os_free(path);
    87
    88 // Do a depth-first walk of the tree
    89 iterate_tree(world, sun, (Position){0, 0});
    90
    91 return ecs_fini(world);
    92
    93 // Output:
    94 // Child of Earth? 1
    95 //
    96 // Moon found: Sun.Earth.Moon
    97 //
    98 // Sun [Position, Star, (Identifier,Name)]
    99 // {1.000000, 1.000000}
    100 //
    101 // Sun.Mercury [Parent, Position, Planet, (Identifier,Name), (ParentDepth,@1)]
    102 // {2.000000, 2.000000}
    103 //
    104 // Sun.Venus [Parent, Position, Planet, (Identifier,Name), (ParentDepth,@1)]
    105 // {3.000000, 3.000000}
    106 //
    107 // Sun.Earth [Parent, Position, Planet, (Identifier,Name), (ParentDepth,@1)]
    108 // {4.000000, 4.000000}
    109 //
    110 // Sun.Earth.Moon [Parent, Position, Moon, (Identifier,Name), (ParentDepth,@2)]
    111 // {4.100000, 4.100000}
    112}
    const ecs_entity_t EcsChildOf
    Used to express parent-child relationships.
    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_children_next(ecs_iter_t *it)
    Progress an iterator created with ecs_children().
    ecs_iter_t ecs_children(const ecs_world_t *world, ecs_entity_t parent)
    Iterate children of a parent.
    const ecs_type_t * ecs_get_type(const ecs_world_t *world, ecs_entity_t entity)
    Get the type of an entity.
    char * ecs_type_str(const ecs_world_t *world, const ecs_type_t *type)
    Convert a type to a string.
    ecs_entity_t ecs_new_w_parent(ecs_world_t *world, ecs_entity_t parent, const char *name)
    Create child with Parent component.
    #define ecs_add(world, entity, T)
    Add a component to an entity.
    Definition flecs_c.h:271
    #define ecs_entity(world,...)
    Shorthand for creating an entity with ecs_entity_init().
    Definition flecs_c.h:188
    #define ECS_COMPONENT_DEFINE(world, id_)
    Define a forward-declared component.
    Definition flecs_c.h:75
    #define ECS_TAG(world, id)
    Declare and define a tag.
    Definition flecs_c.h:59
    #define ECS_COMPONENT_DECLARE(id)
    Forward declare a component.
    Definition flecs_c.h:65
    #define ecs_get_path(world, child)
    Get path from root.
    Definition flecs_c.h:594
    #define ecs_set(world, entity, component,...)
    Set a component value.
    Definition flecs_c.h:310
    #define ecs_get(world, entity, T)
    Get a component.
    Definition flecs_c.h:339
    #define ecs_has_pair(world, entity, first, second)
    Test if an entity has a pair.
    Definition flecs_c.h:527
    ecs_entity_t ecs_lookup(const ecs_world_t *world, const char *path)
    Look up an entity by its path.
    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
    int32_t count
    Number of entities to iterate.
    Definition flecs.h:1189
    const ecs_entity_t * entities
    Entity identifiers.
    Definition flecs.h:1190

  • C++

    View on GitHub

    1#include <parent_hierarchy.h>
    2#include <iostream>
    3
    4// ChildOf hierarchies are optimized for scenarios with few parents that have
    5// lots of children. Parent hierarchies are optimized for scenarios with lots of
    6// parents that have a small number of children. See the documentation for more
    7// information:
    8// https://www.flecs.dev/flecs/HierarchiesManual.html#hierarchy-storage
    9//
    10// This example is the same as the hierarchy example, but instead of using
    11// ChildOf hierarchies it uses Parent hierarchies.
    12
    13struct Position {
    14 double x, y;
    15};
    16
    17struct Star { };
    18struct Planet { };
    19struct Moon { };
    20
    21void iterate_tree(flecs::entity e, Position p_parent = {0, 0}) {
    22 // Print hierarchical name of entity & the entity type
    23 std::cout << e.path() << " [" << e.type().str() << "]\n";
    24
    25 // Get entity position
    26 const Position& p = e.get<Position>();
    27
    28 // Calculate actual position
    29 Position p_actual = {p.x + p_parent.x, p.y + p_parent.y};
    30 std::cout << "{" << p_actual.x << ", " << p_actual.y << "}\n\n";
    31
    32 // Iterate children recursively
    33 e.children([&](flecs::entity child) {
    34 iterate_tree(child, p_actual);
    35 });
    36}
    37
    38int main(int, char *[]) {
    39 flecs::world ecs;
    40
    41 // Create a simple hierarchy.
    42 // Hierarchies use ECS relationships and the builtin flecs::ChildOf relationship to
    43 // create entities as children of other entities.
    44
    45 flecs::entity sun = ecs.entity("Sun")
    46 .add<Star>()
    47 .set<Position>({1, 1});
    48
    49 ecs.entity(flecs::Parent{sun}, "Mercury")
    50 .add<Planet>()
    51 .set<Position>({1, 1});
    52
    53 ecs.entity(flecs::Parent{sun}, "Venus")
    54 .add<Planet>()
    55 .set<Position>({2, 2});
    56
    57 flecs::entity earth = ecs.entity(flecs::Parent{sun}, "Earth")
    58 .add<Planet>()
    59 .set<Position>({3, 3});
    60
    61 flecs::entity moon = ecs.entity(flecs::Parent{earth}, "Moon")
    62 .add<Moon>()
    63 .set<Position>({0.1, 0.1});
    64
    65 // Is the Moon a child of Earth?
    66 std::cout << "Child of Earth? " << moon.has(flecs::ChildOf, earth) << "\n\n";
    67
    68 // Lookup the moon by name
    69 flecs::entity e = ecs.lookup("Sun::Earth::Moon");
    70 std::cout << "Moon found: " << e.path() << "\n\n";
    71
    72 // Do a depth-first walk of the tree
    73 iterate_tree(sun);
    74
    75 // Output:
    76 // Child of Earth? 1
    77 //
    78 // Moon found: ::Sun::Earth::Moon
    79 //
    80 // ::Sun [Star, Position, (Identifier,Name)]
    81 // {1, 1}
    82 //
    83 // ::Sun::Mercury [Parent, Position, Planet, (Identifier,Name), (ParentDepth,@1)]
    84 // {2, 2}
    85 //
    86 // ::Sun::Venus [Parent, Position, Planet, (Identifier,Name), (ParentDepth,@1)]
    87 // {3, 3}
    88 //
    89 // ::Sun::Earth [Parent, Position, Planet, (Identifier,Name), (ParentDepth,@1)]
    90 // {4, 4}
    91 //
    92 // ::Sun::Earth::Moon [Parent, Position, Moon, (Identifier,Name), (ParentDepth,@2)]
    93 // {4.1, 4.1}
    94}
    flecs::entity entity(Args &&... args) const
    Create an entity.
    Definition impl.hpp:195
    EcsParent Parent
    Built-in EcsParent type.
    Definition c_types.hpp:86
    flecs::type type() const
    Get the entity's type.
    Definition impl.hpp:94
    flecs::string path(const char *sep="::", const char *init_sep="::") const
    Return the entity path.
    void children(flecs::entity_t rel, Func &&func) const
    Iterate children for an entity.
    Entity.
    Definition entity.hpp:30
    flecs::string str() const
    Convert the type to a comma-separated string.
    Definition type.hpp:38
    The world.
    Definition world.hpp:129
    flecs::entity lookup(const char *name, const char *sep="::", const char *root_sep="::", bool recursive=true) const
    Lookup entity by name.
    Definition world.hpp:102