Skip to content
Flecs v4.1
prefabs/variant

  • C

    View on GitHub

    1#include <variant.h>
    2#include <stdio.h>
    3
    4/* Prefabs can inherit from each other, which creates prefab variants. With
    5 * variants applications can reuse a common set of components and specialize it
    6 * by adding or overriding components on the variant. */
    7
    8typedef struct { double value; } Attack;
    9typedef struct { double value; } Defense;
    10typedef struct { double value; } FreightCapacity;
    11typedef struct { double value; } ImpulseSpeed;
    12
    13typedef struct {
    14 double x;
    15 double y;
    16} Position;
    17
    18int main(int argc, char *argv[]) {
    19 ecs_world_t *ecs = ecs_init_w_args(argc, argv);
    20
    21 ECS_COMPONENT(ecs, Position);
    22 ECS_COMPONENT(ecs, Attack);
    23 ECS_COMPONENT(ecs, Defense);
    24 ECS_COMPONENT(ecs, FreightCapacity);
    25 ECS_COMPONENT(ecs, ImpulseSpeed);
    26
    27 // Create a base prefab for SpaceShips.
    28 ecs_entity_t SpaceShip = ecs_entity(ecs, { .name = "SpaceShip" });
    29 ecs_add_id(ecs, SpaceShip, EcsPrefab);
    30 ecs_set(ecs, SpaceShip, ImpulseSpeed, {50});
    31 ecs_set(ecs, SpaceShip, Defense, {25});
    32
    33 // Create a Freighter variant which inherits from SpaceShip
    34 ecs_entity_t Freighter = ecs_entity(ecs, { .name = "Freighter" });
    35 ecs_add_id(ecs, Freighter, EcsPrefab);
    36 ecs_add_pair(ecs, Freighter, EcsIsA, SpaceShip);
    37 ecs_set(ecs, Freighter, FreightCapacity, {100});
    38 ecs_set(ecs, Freighter, Defense, {50});
    39
    40 // Create a MammothFreighter variant which inherits from Freighter
    41 ecs_entity_t MammothFreighter = ecs_entity(ecs, { .name = "MammothFreighter" });
    42 ecs_add_id(ecs, MammothFreighter, EcsPrefab);
    43 ecs_add_pair(ecs, MammothFreighter, EcsIsA, Freighter);
    44 ecs_set(ecs, MammothFreighter, FreightCapacity, {500});
    45
    46 // Create a Frigate variant which inherits from SpaceShip
    47 ecs_entity_t Frigate = ecs_entity(ecs, { .name = "Frigate" });
    48 ecs_add_id(ecs, Frigate, EcsPrefab);
    49 ecs_add_pair(ecs, Frigate, EcsIsA, SpaceShip);
    50 ecs_set(ecs, Frigate, Attack, {100});
    51 ecs_set(ecs, Frigate, Defense, {75});
    52 ecs_set(ecs, Frigate, ImpulseSpeed, {125});
    53
    54
    55 // Create an instance of the MammothFreighter. This entity will inherit the
    56 // ImpulseSpeed from SpaceShip, Defense from Freighter and FreightCapacity
    57 // from MammothFreighter.
    58 ecs_entity_t inst = ecs_entity(ecs, { .name = "my_freighter" });
    59 ecs_add_pair(ecs, inst, EcsIsA, MammothFreighter);
    60
    61 // Add a private Position component.
    62 ecs_set(ecs, inst, Position, {10, 20});
    63
    64 // Instances can override inherited components to give them a private copy
    65 // of the component. This freighter got an armor upgrade:
    66 ecs_set(ecs, inst, Defense, {100});
    67
    68 // Queries can match components from multiple levels of inheritance
    69 ecs_query_t *q = ecs_query(ecs, {
    70 .terms = {
    71 { .id = ecs_id(Position) },
    72 { .id = ecs_id(ImpulseSpeed) },
    73 { .id = ecs_id(Defense) },
    74 { .id = ecs_id(FreightCapacity) }
    75 }
    76 });
    77
    78 ecs_iter_t it = ecs_query_iter(ecs, q);
    79 while (ecs_query_next(&it)) {
    80 Position *p = ecs_field(&it, Position, 0);
    81 ImpulseSpeed *s = ecs_field(&it, ImpulseSpeed, 1);
    82 Defense *d = ecs_field(&it, Defense, 2);
    83 FreightCapacity *c = ecs_field(&it, FreightCapacity, 3);
    84
    85 for (int i = 0; i < it.count; i ++) {
    86 printf("%s:\n", ecs_get_name(ecs, it.entities[i]));
    87 printf(" - position: %f, %f\n", p[i].x, p[i].y);
    88 printf(" - impulse speed: %f\n", s[i].value);
    89 printf(" - defense: %f\n", d[i].value);
    90 printf(" - capacity: %f\n", c[i].value);
    91 }
    92 }
    93
    94 // Output:
    95 // my_freighter:
    96 // - position: 10.000000, 20.000000
    97 // - impulse speed: 50.000000
    98 // - defense: 100.000000
    99 // - capacity: 500.000000
    100
    101 return ecs_fini(ecs);
    102}
    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 EcsIsA
    Used to express inheritance relationships.
    const ecs_entity_t EcsPrefab
    Tag added to prefab entities.
    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
    #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
    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.
    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 <variant.h>
    2#include <iostream>
    3
    4/* Prefabs can inherit from each other, which creates prefab variants. With
    5 * variants applications can reuse a common set of components and specialize it
    6 * by adding or overriding components on the variant. */
    7
    8struct Attack {
    9 double value;
    10};
    11
    12struct Defense {
    13 double value;
    14};
    15
    16struct FreightCapacity {
    17 double value;
    18};
    19
    20struct ImpulseSpeed {
    21 double value;
    22};
    23
    24struct Position {
    25 double x;
    26 double y;
    27};
    28
    29int main() {
    30 flecs::world ecs;
    31
    32 // Create a base prefab for SpaceShips.
    33 flecs::entity SpaceShip = ecs.prefab("SpaceShip")
    34 .set<ImpulseSpeed>({ 50 })
    35 .set<Defense>({ 25 });
    36
    37 // Create a Freighter variant which inherits from SpaceShip
    38 flecs::entity Freighter = ecs.prefab("Freighter")
    39 .is_a(SpaceShip)
    40 .set<FreightCapacity>({ 100 })
    41 .set<Defense>({ 50 });
    42
    43 // Create a MammothFreighter variant which inherits from Freighter
    44 flecs::entity MammothFreighter = ecs.prefab("MammothFreighter")
    45 .is_a(Freighter)
    46 .set<FreightCapacity>({ 500 });
    47
    48 // Create a Frigate variant which inherits from SpaceShip
    49 ecs.prefab("Frigate")
    50 .is_a(SpaceShip)
    51 .set<Attack>({ 100 })
    52 .set<Defense>({ 75 })
    53 .set<ImpulseSpeed>({ 125 });
    54
    55 // Create an instance of the MammothFreighter. This entity will inherit the
    56 // ImpulseSpeed from SpaceShip, Defense from Freighter and FreightCapacity
    57 // from MammothFreighter.
    58 flecs::entity inst = ecs.entity("my_freighter").is_a(MammothFreighter);
    59
    60 // Add a private Position component.
    61 inst.set<Position>({ 10, 20});
    62
    63 // Instances can override inherited components to give them a private copy
    64 // of the component. This freighter got an armor upgrade:
    65 inst.set<Defense>({ 100 });
    66
    67 // Queries can match components from multiple levels of inheritance
    68 ecs.each([](flecs::entity e,
    69 Position& p, ImpulseSpeed& s, Defense& d, FreightCapacity& c) {
    70 std::cout << e.name() << ":\n";
    71 std::cout << " - position: " << p.x << ", " << p.y << "\n";
    72 std::cout << " - impulse speed: " << s.value << "\n";
    73 std::cout << " - defense: " << d.value << "\n";
    74 std::cout << " - capacity: " << c.value << "\n";
    75 });
    76
    77 // Output:
    78 // my_freighter:
    79 // - position: 10, 20
    80 // - impulse speed: 50
    81 // - defense: 100
    82 // - capacity: 500
    83}
    void each(Func &&func) const
    Iterate over all entities with components in the argument list of the function.
    Definition impl.hpp:368
    flecs::entity entity(Args &&... args) const
    Create an entity.
    Definition impl.hpp:195
    flecs::entity prefab(const char *name=nullptr) const
    Create a prefab that's associated with a type.
    Definition impl.hpp:18
    const Self & is_a(entity_t second) const
    Shortcut for add(IsA, entity).
    Definition builder.hpp:122
    flecs::string_view name() const
    Return the entity name.
    Entity.
    Definition entity.hpp:30
    The world.
    Definition world.hpp:129