Skip to content

Instantly share code, notes, and snippets.

@MURPHYENGINEERING
Created June 9, 2022 06:36
Show Gist options
  • Save MURPHYENGINEERING/4a2ebe660327ff3aebf771d8e1862360 to your computer and use it in GitHub Desktop.
Save MURPHYENGINEERING/4a2ebe660327ff3aebf771d8e1862360 to your computer and use it in GitHub Desktop.
// We control two systems with two tags:
// - when Dirty, a system adds a Texture component to an entity
// - when Visible, a system renders the Texture component
//
// Visible is set on a base entity and inherited by the textured entity
...
ecs_entity_t eOverlay = ecs_new_w_pair(world, EcsChildOf, ui->e);
ecs_set_name(world, eOverlay, "debugOverlay");
ecs_add(world, eOverlay, Visible);
ecs_entity_t eTps = ecs_new_w_pair(world, EcsIsA, eOverlay);
ecs_set_name(world, eTps, "tpsText");
ecs_set(world, eTps, Texture, { NULL });
...
void
SdlImport(ecs_world_t* world)
{
ECS_MODULE(world, Sdl);
ECS_COMPONENT_DEFINE(world, Texture);
ECS_IMPORT(world, Ui); // for Visible tag
// This is the system that fails to run after the system below
// removes Dirty from the entity
ECS_SYSTEM_DEFINE(
world,
lm_sdl_sys_render_textures,
0,
[in] Texture,
[in] Visible);
}
void
TtfImport(ecs_world_t* world)
{
ECS_MODULE(world, Ttf);
ECS_IMPORT(world, Sdl); // for Texture component
ECS_TAG_DEFINE(world, Dirty);
// This is the system that removes Dirty from the entity
ECS_SYSTEM_DEFINE(
world,
lm_ttf_sys_bake_textures,
0,
[out] Texture,
[EcsInOut] Dirty);
}
// Every frame, the first thing we do is add the Dirty tag
void
lm_ui_overlay_debug_update(ecs_world_t* world)
{
...
ecs_add(world, eTps, Dirty);
}
// At this point, the types of the two entities are
// Base (eOverlay) ui.Visible, (Identifier,Name), (ChildOf,ui)
// Descendant (eTps) sdl.Texture, ttf.Dirty, (Identifier,Name), (IsA,ui.debugOverlay)
// Next we run the system that queries the Dirty tag, and removes it
ecs_run(world, ecs_id(lm_ttf_sys_bake_textures), ...
void
lm_ttf_sys_bake_textures(ecs_iter_t* it)
{
Texture* textures = ecs_term(it, Texture, 1);
for (size_t i = 0; i < it->count; ++i) {
ecs_entity_t e = it->entities[i];
textures[i].tex = ...
// Everything works fine if we don't do this:
ecs_remove(it->world, e, Dirty);
log_debug("Baked %d", it->entities[i]);
}
}
// At this point, the types of the two entities are
// Base (eOverlay) ui.Visible, (Identifier,Name), (ChildOf,ui)
// Descendant (eTps) sdl.Texture, (Identifier,Name), (IsA,ui.debugOverlay)
// Then we run the system that queries the Visible tag
ecs_run(world, ecs_id(lm_sdl_sys_render_textures), ...
void
lm_sdl_sys_render_textures(ecs_iter_t* it)
{
Texture* textures = ecs_term(it, Texture, 1);
for (size_t i = 0; i < it->count; ++i) {
log_debug("Rendered %d", it->entities[i]);
}
}
// If we do not remove the Dirty tag then everything runs every frame:
Baked 553
Rendered 553
Baked 553
...
// If we do remove the Dirty tag then the second system stops running:
Baked 553
Baked 553
...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment