Skip to content
Flecs v4.1
prefabs/nested_prefabs

  • C

    View on GitHub

    1#include <nested_prefabs.h>
    2#include <stdio.h>
    3
    4// Nested prefabs make it possible to reuse an existing prefab inside another
    5// prefab. An example of where this could be useful is a car with four wheels:
    6// instead of defining four times what a wheel is a Car prefab can reference an
    7// existing Wheel prefab.
    8//
    9// Nested prefabs can be created by adding a child that is a variant (inherits
    10// from) another prefab. For more information on variants, see the variants
    11// example.
    12//
    13// Instantiated children from a nested prefab still inherit from the original
    14// prefab. The reason for this is that an instantiated child is an exact copy
    15// of the prefab child, and the prefab child only has an IsA relationship to the
    16// nested prefab.
    17
    18typedef struct {
    19 double value;
    20} TirePressure;
    21
    22int main(int argc, char *argv[]) {
    23 ecs_world_t *ecs = ecs_init_w_args(argc, argv);
    24
    25 ECS_COMPONENT(ecs, TirePressure);
    26
    27 // Create a Wheel prefab.
    28 ecs_entity_t Wheel = ecs_entity(ecs, { .name = "Wheel" });
    29 ecs_add_id(ecs, Wheel, EcsPrefab);
    30 ecs_set(ecs, Wheel, TirePressure, { 32 });
    31
    32 // Create a Car prefab with four wheels. Note how the wheel names are
    33 // prefixed with 'Car.', this is has the same effect as adding the
    34 // (ChildOf, Car) relationship.
    35 ecs_entity_t Car = ecs_entity(ecs, { .name = "Car" });
    36 ecs_add_id(ecs, Car, EcsPrefab);
    37 ecs_entity_t WheelFrontLeft = ecs_entity(ecs, { .name = "Car.FrontLeft" });
    38 ecs_add_id(ecs, WheelFrontLeft, EcsPrefab);
    39 ecs_add_pair(ecs, WheelFrontLeft, EcsIsA, Wheel);
    40
    41 ecs_entity_t WheelFrontRight = ecs_entity(ecs, { .name = "Car.FrontRight" });
    42 ecs_add_id(ecs, WheelFrontRight, EcsPrefab);
    43 ecs_add_pair(ecs, WheelFrontRight, EcsIsA, Wheel);
    44
    45 ecs_entity_t WheelBackLeft = ecs_entity(ecs, { .name = "Car.BackLeft" });
    46 ecs_add_id(ecs, WheelBackLeft, EcsPrefab);
    47 ecs_add_pair(ecs, WheelBackLeft, EcsIsA, Wheel);
    48
    49 ecs_entity_t WheelBackRight = ecs_entity(ecs, { .name = "Car.BackRight" });
    50 ecs_add_id(ecs, WheelBackRight, EcsPrefab);
    51 ecs_add_pair(ecs, WheelBackRight, EcsIsA, Wheel);
    52
    53 // Create a prefab instance.
    54 ecs_entity_t inst = ecs_entity(ecs, { .name = "my_car" });
    55 ecs_add_pair(ecs, inst, EcsIsA, Car);
    56
    57 // Lookup one of the wheels
    58 ecs_entity_t inst_front_left = ecs_lookup_child(ecs, inst, "FrontLeft");
    59
    60 // The type shows that the child has a private copy of the TirePressure
    61 // component, and an IsA relationship to the Wheel prefab.
    62 char *type = ecs_type_str(ecs, ecs_get_type(ecs, inst_front_left));
    63 printf("type: [%s]\n", type);
    64 ecs_os_free(type);
    65
    66 // Get the TirePressure component & print its value
    67 const TirePressure *p = ecs_get(ecs, inst_front_left, TirePressure);
    68 printf("pressure: %f\n", p->value);
    69
    70 // Output
    71 // type: [TirePressure, (Identifier,Name), (ChildOf,my_car), (IsA,Wheel)]
    72 // pressure: 32.000000
    73
    74 return ecs_fini(ecs);
    75}
    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.
    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_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
    ecs_entity_t ecs_lookup_child(const ecs_world_t *world, ecs_entity_t parent, const char *name)
    Look up a child entity by name.
    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 <nested_prefabs.h>
    2#include <iostream>
    3
    4// Nested prefabs make it possible to reuse an existing prefab inside another
    5// prefab. An example of where this could be useful is a car with four wheels:
    6// instead of defining four times what a wheel is a Car prefab can reference an
    7// existing Wheel prefab.
    8//
    9// Nested prefabs can be created by adding a child that is a variant (inherits
    10// from) another prefab. For more information on variants, see the variants
    11// example.
    12//
    13// Instantiated children from a nested prefab still inherit from the original
    14// prefab. The reason for this is that an instantiated child is an exact copy
    15// of the prefab child, and the prefab child only has an IsA relationship to the
    16// nested prefab.
    17
    18struct TirePressure {
    19 double value;
    20};
    21
    22int main() {
    23 flecs::world ecs;
    24
    25 // Create a Wheel prefab.
    26 flecs::entity Wheel = ecs.prefab("Wheel")
    27 .set<TirePressure>({ 32 });
    28
    29 // Create a Car prefab with four wheels. Note how we're using the scope
    30 // method, which has the same effect as adding the (ChildOf, Car) pair.
    31 flecs::entity Car = ecs.prefab("Car").scope([&]{
    32 ecs.prefab("FrontLeft").is_a(Wheel);
    33 ecs.prefab("FrontRight").is_a(Wheel);
    34 ecs.prefab("BackLeft").is_a(Wheel);
    35 ecs.prefab("BackRight").is_a(Wheel);
    36 });
    37
    38 // Create a prefab instance.
    39 flecs::entity inst = ecs.entity("my_car").is_a(Car);
    40
    41 // Lookup one of the wheels
    42 flecs::entity inst_front_left = inst.lookup("FrontLeft");
    43
    44 // The type shows that the child has a private copy of the TirePressure
    45 // component, and an IsA relationship to the Wheel prefab.
    46 std::cout << "type: [" << inst_front_left.type().str() << "]\n";
    47
    48 // Get the TirePressure component & print its value
    49 inst_front_left.get([](const TirePressure p) {
    50 std::cout << "pressure: " << p.value << "\n";
    51 });
    52
    53 // Output:
    54 // type: [TirePressure, (Identifier,Name), (ChildOf,my_car), (IsA,Wheel)]
    55 // pressure: 32
    56}
    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
    const Self & scope(const Func &func) const
    The function will be run with the scope set to the current entity.
    Definition builder.hpp:533
    flecs::type type() const
    Get the entity's type.
    Definition impl.hpp:94
    flecs::entity lookup(const char *path, bool search_path=false) const
    Lookup an entity by name.
    Definition impl.hpp:177
    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