Skip to content
Flecs v4.1
systems/run_callback

  • C

    View on GitHub

    1#include <run_callback.h>
    2#include <stdio.h>
    3
    4// Systems can be created with a custom run function that takes control over the
    5// entire iteration. By default, a system is invoked once per matched table,
    6// which means the function can be called multiple times per frame. In some
    7// cases that's inconvenient, like when a system has things it needs to do only
    8// once per frame. For these use cases, the run callback can be used which is
    9// called once per frame per system.
    10
    11typedef struct {
    12 double x, y;
    13} Position, Velocity;
    14
    15void Move(ecs_iter_t *it) {
    16 printf("Move begin\n");
    17
    18 // In a run function we have to manually iterate through the query results.
    19 // Note that this code looks the same as iterating a query.
    20 while (ecs_query_next(it)) {
    21 // Inside the loop the code looks the same as for a regular system
    22 Position *p = ecs_field(it, Position, 0);
    23 const Velocity *v = ecs_field(it, Velocity, 1);
    24
    25 for (int i = 0; i < it->count; i ++) {
    26 p[i].x += v[i].x;
    27 p[i].y += v[i].y;
    28 printf("%s: {%f, %f}\n", ecs_get_name(it->stage, it->entities[i]),
    29 p[i].x, p[i].y);
    30 }
    31 }
    32
    33 printf("Move end\n");
    34}
    35
    36int main(int argc, char *argv[]) {
    37 ecs_world_t *ecs = ecs_init_w_args(argc, argv);
    38
    39 ECS_COMPONENT(ecs, Position);
    40 ECS_COMPONENT(ecs, Velocity);
    41
    42 // Create a system for Position, Velocity
    43 ecs_entity_t move = ecs_system(ecs, {
    44 .query.terms = {
    45 { .id = ecs_id(Position) },
    46 { .id = ecs_id(Velocity), .inout = EcsIn }
    47 },
    48 .run = Move // use .run instead of .callback
    49 });
    50
    51 // Create a few test entities for a Position, Velocity query
    52 ecs_entity_t e1 = ecs_entity(ecs, { .name = "e1" });
    53 ecs_set(ecs, e1, Position, {10, 20});
    54 ecs_set(ecs, e1, Velocity, {1, 2});
    55
    56 ecs_entity_t e2 = ecs_entity(ecs, { .name = "e2" });
    57 ecs_set(ecs, e2, Position, {10, 20});
    58 ecs_set(ecs, e2, Velocity, {3, 4});
    59
    60 // This entity will not match as it does not have Position, Velocity
    61 ecs_entity_t e3 = ecs_entity(ecs, { .name = "e3" });
    62 ecs_set(ecs, e3, Position, {10, 20});
    63
    64 // Run the system
    65 ecs_run(ecs, move, 0.0f, NULL);
    66
    67 return ecs_fini(ecs);
    68
    69 // Output
    70 // Move begin
    71 // e1: {11.000000, 22.000000}
    72 // e2: {13.000000, 24.000000}
    73 // Move end
    74}
    FLECS_API const ecs_entity_t ecs_id(EcsDocDescription)
    Component ID for EcsDocDescription.
    #define ecs_system(world,...)
    Shorthand for creating a system with ecs_system_init().
    Definition system.h:285
    FLECS_API ecs_entity_t ecs_run(ecs_world_t *world, ecs_entity_t system, ecs_ftime_t delta_time, void *param)
    Run a specific system manually.
    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_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_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.
    @ EcsIn
    Term is only read.
    Definition flecs.h:731
    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 <run_callback.h>
    2#include <iostream>
    3
    4// This example shows how to use the run callback, which provides more direct
    5// control over the iteration of the system. It also makes it easier to run code
    6// before and after the iteration.
    7
    8struct Position {
    9 double x, y;
    10};
    11
    12struct Velocity {
    13 double x, y;
    14};
    15
    16int main(int, char *[]) {
    17 flecs::world ecs;
    18
    19 flecs::system s = ecs.system<Position, const Velocity>()
    20 .run([](flecs::iter& it) {
    21 std::cout << "Move begin\n";
    22
    23 while (it.next()) {
    24 auto p = it.field<Position>(0);
    25 auto v = it.field<const Velocity>(1);
    26
    27 for (auto i : it) {
    28 flecs::entity e = it.entity(i);
    29 p[i].x += v[i].x;
    30 p[i].y += v[i].y;
    31 std::cout << e.name()
    32 << ": {" << p[i].x << ", " << p[i].y << "}\n";
    33 }
    34 }
    35
    36 std::cout << "Move end\n";
    37 });
    38
    39 // Create a few test entities for a Position, Velocity query
    40 ecs.entity("e1")
    41 .set<Position>({10, 20})
    42 .set<Velocity>({1, 2});
    43
    44 ecs.entity("e2")
    45 .set<Position>({10, 20})
    46 .set<Velocity>({3, 4});
    47
    48 // This entity will not match as it does not have Position, Velocity
    49 ecs.entity("e3")
    50 .set<Position>({10, 20});
    51
    52 // Run the system
    53 s.run();
    54
    55 // Output
    56 // Move begin
    57 // e1: {11, 22}
    58 // e2: {13, 24}
    59 // Move end
    60}
    flecs::system system(flecs::entity e) const
    Upcast an entity to a system.
    Definition impl.hpp:181
    flecs::entity entity(Args &&... args) const
    Create an entity.
    Definition impl.hpp:195
    flecs::string_view name() const
    Return the entity name.
    Entity.
    Definition entity.hpp:30
    entity()
    Default constructor.
    Definition entity.hpp:32
    Class for iterating over query results.
    Definition iter.hpp:68
    flecs::field< A > field(int8_t index) const
    Get read-only access to field data.
    Definition iter.hpp:84
    bool next()
    Progress iterator.
    Definition iter.hpp:465
    System.
    Definition impl.hpp:78
    system & run(Func &&func)
    Replace the system's run callback.
    Definition impl.hpp:108
    The world.
    Definition world.hpp:129