Skip to content
Flecs v4.1
prefabs/override

  • C

    View on GitHub

    1#include <override.h>
    2#include <stdio.h>
    3
    4// When an entity is instantiated from a prefab, components are by default
    5// copied from the prefab to the instance. This behavior can be customized with
    6// the OnInstantiate trait, which has three options:
    7//
    8// - Override (copy to instance)
    9// - Inherit (inherit from prefab)
    10// - DontInherit (don't copy or inherit)
    11//
    12// When a component is inheritable, it can be overridden manually by adding the
    13// component to the instance, which also copies the value from the prefab
    14// component. Additionally, when creating a prefab it is possible to flag a
    15// component as "auto override", which can change the behavior for a specific
    16// prefab from "inherit" to "override".
    17//
    18// This example shows how these different features can be used.
    19
    20typedef struct {
    21 double value;
    22} Attack, Defense, Damage;
    23
    24int main(int argc, char *argv[]) {
    25 ecs_world_t *ecs = ecs_init_w_args(argc, argv);
    26
    27 ECS_COMPONENT(ecs, Attack);
    28 ECS_COMPONENT(ecs, Defense);
    29 ECS_COMPONENT(ecs, Damage);
    30
    31 // Change the instantiation behavior for Attack and Defense to inherit.
    34
    35 ecs_entity_t SpaceShip = ecs_entity(ecs, { .name = "SpaceShip" });
    36 ecs_add_id(ecs, SpaceShip, EcsPrefab);
    37
    38 ecs_set(ecs, SpaceShip, Attack, { 75 });
    39 ecs_set(ecs, SpaceShip, Defense, { 100 });
    40 ecs_set(ecs, SpaceShip, Damage, { 50 });
    41
    42 // Create a prefab instance.
    43 ecs_entity_t inst = ecs_entity(ecs, { .name = "my_instance" });
    44 ecs_add_pair(ecs, inst, EcsIsA, SpaceShip);
    45
    46 // The entity will now have a private copy of the Damage component, but not
    47 // of the Attack and Defense components. We can see this when we look at the
    48 // type of the instance:
    49 char *type = ecs_type_str(ecs, ecs_get_type(ecs, inst));
    50 printf("instance type = [%s]\n", type);
    51 ecs_os_free(type);
    52
    53 // Even though Attack was not copied to the instance when instantiated, we
    54 // can still override it manually afterwards by adding it to the instance:
    55 ecs_add(ecs, inst, Attack);
    56
    57 // The Attack component is now owned and shows up in the entity type:
    58 type = ecs_type_str(ecs, ecs_get_type(ecs, inst));
    59 printf("instance type = [%s]\n", type);
    60 ecs_os_free(type);
    61
    62 // We can get all components on the instance, regardless of whether they
    63 // are overridden or not. Note that the overridden components (Attack and
    64 // Damage) are initialized with the values from the prefab component:
    65 const Attack *attack = ecs_get(ecs, inst, Attack);
    66 const Defense *defense = ecs_get(ecs, inst, Defense);
    67 const Damage *damage = ecs_get(ecs, inst, Damage);
    68
    69 printf("attack: %f\n", attack->value);
    70 printf("defense: %f\n", defense->value);
    71 printf("damage: %f\n", damage->value);
    72
    73 // Output:
    74 // instance type = [Damage, (Identifier,Name), (IsA,SpaceShip)]
    75 // instance type = [Attack, Damage, (Identifier,Name), (IsA,SpaceShip)]
    76 // attack: 75.000000
    77 // defense: 100.000000
    78 // damage: 50.000000
    79
    80 return ecs_fini(ecs);
    81}
    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 EcsInherit
    Inherit component on instantiate.
    const ecs_entity_t EcsPrefab
    Tag added to prefab entities.
    const ecs_entity_t EcsOnInstantiate
    Relationship that specifies component inheritance behavior.
    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
    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.
    #define ecs_add_pair(world, subject, first, second)
    Add a pair to an entity.
    Definition flecs_c.h:275
    #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(world, id)
    Declare and define a component.
    Definition flecs_c.h:98
    #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
    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.

  • C++

    View on GitHub

    1#include <override.h>
    2#include <iostream>
    3
    4// When an entity is instantiated from a prefab, components are by default
    5// copied from the prefab to the instance. This behavior can be customized with
    6// the OnInstantiate trait, which has three options:
    7//
    8// - Override (copy to instance)
    9// - Inherit (inherit from prefab)
    10// - DontInherit (don't copy or inherit)
    11//
    12// When a component is inheritable, it can be overridden manually by adding the
    13// component to the instance, which also copies the value from the prefab
    14// component. Additionally, when creating a prefab it is possible to flag a
    15// component as "auto override", which can change the behavior for a specific
    16// prefab from "inherit" to "override".
    17//
    18// This example shows how these different features can be used.
    19
    20struct Attack {
    21 double value;
    22};
    23
    24struct Defense {
    25 double value;
    26};
    27
    28struct Damage {
    29 double value;
    30};
    31
    32int main() {
    33 flecs::world ecs;
    34
    35 // Change the instantiation behavior for Attack and Defense to inherit.
    36 ecs.component<Attack>().add(flecs::OnInstantiate, flecs::Inherit);
    37 ecs.component<Defense>().add(flecs::OnInstantiate, flecs::Inherit);
    38
    39 // Attack and Defense are properties that can be shared across many
    40 // spaceships. This saves memory, and speeds up prefab creation as we don't
    41 // have to copy the values of Attack and Defense to private components.
    42 flecs::entity SpaceShip = ecs.prefab("SpaceShip")
    43 .set<Attack>({ 75 })
    44 .set<Defense>({ 100 })
    45 .set<Damage>({ 50 });
    46
    47 // Create a prefab instance.
    48 flecs::entity inst = ecs.entity("my_spaceship").is_a(SpaceShip);
    49
    50 // The entity will now have a private copy of the Damage component, but not
    51 // of the Attack and Defense components. We can see this when we look at the
    52 // type of the instance:
    53 std::cout << inst.type().str() << "\n";
    54
    55 // Even though Attack was not automatically overridden, we can always
    56 // override it manually afterwards by adding it:
    57 inst.add<Attack>();
    58
    59 // The Attack component now shows up in the entity type:
    60 std::cout << inst.type().str() << "\n";
    61
    62 // We can get all components on the instance, regardless of whether they
    63 // are overridden or not. Note that the overridden components (Attack and
    64 // Damage) are initialized with the values from the prefab component:
    65 const Attack& a = inst.get<Attack>();
    66 const Defense& d = inst.get<Defense>();
    67 const Damage& dmg = inst.get<Damage>();
    68
    69 std::cout << "attack: " << a.value << "\n";
    70 std::cout << "defense: " << d.value << "\n";
    71 std::cout << "damage: " << dmg.value << "\n";
    72
    73 // Output:
    74 // Damage, (Identifier,Name), (IsA,SpaceShip)
    75 // Attack, Damage, (Identifier,Name), (IsA,SpaceShip)
    76 // attack: 75
    77 // defense: 100
    78 // damage: 50
    79}
    flecs::component< T > component(Args &&... args) const
    Find or register a component.
    Definition impl.hpp:11
    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::type type() const
    Get the entity's type.
    Definition impl.hpp:94
    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