gaia-ecs
gaia-ecs copied to clipboard
Do work properly `ChildOf` and `DependsOn`?
Hello there!
I've met some strange behavior of using it. During loading a module (a container of components, systems, etc) I add some system groups (using ChildOf) and edges (using DependsOn).
My code is pretty simple:
for (auto sys : info.systems)
{
auto* currentSystem = ...;
logger().info(fmt::format("system {}, {}", sys.get_name(), currentSystem->entity().id()));
if (sys.hasGroup())
{
auto* groupSystem = ...;
m_world.add(currentSystem->entity(), gaia::ecs::Pair{gaia::ecs::ChildOf, groupSystem->entity()});
logger().info(fmt::format("\t ({}) has group {}, {}", currentSystem->entity().id(), groupType.get_name(), groupSystem->entity().id()));
}
if (sys.hasRunBeforeEdges())
{
for (auto edge : edges)
{
auto* edgeSystem = ...;
m_world.add(edgeSystem->entity(), gaia::ecs::Pair{ gaia::ecs::DependsOn, currentSystem->entity() });
logger().info(fmt::format("\t ({}) has runBefore edge {}, {}", currentSystem->entity().id(), edge.get_name(), edgeSystem->entity().id()));
}
}
if (sys.hasRunAfterEdges())
{
for (auto edge : edges)
{
auto* edgeSystem = ...;
m_world.add(currentSystem->entity(), gaia::ecs::Pair{ gaia::ecs::DependsOn, edgeSystem->entity() });
logger().info(fmt::format("\t ({}) has runAfter edge {}, {}", currentSystem->entity().id(), edge.get_name(), edgeSystem->entity().id()));
}
}
}
It produces the following info in output:
system RenderInitGroup, 32
system RenderGroup, 33
system RenderPrepareGroup, 34
system RenderFinishGroup, 35
system RenderInitSystem<unsigned __int64,0>, 36
(36) has group render::RenderInitGroup, 32
system RenderInitSystem<unsigned __int64,1>, 37
(37) has group render::RenderInitGroup, 32
system RenderInitSystem<unsigned __int64,2>, 38
(38) has group render::RenderInitGroup, 32
system RenderInitSystem<unsigned __int64,3>, 39
(39) has group render::RenderInitGroup, 32
system RenderInitSystem<unsigned __int64,4>, 40
(40) has group render::RenderInitGroup, 32
system RenderInitSystem<unsigned __int64,5>, 41
(41) has group render::RenderInitGroup, 32
system RenderSystem<unsigned __int64,6>, 42
(42) has group render::RenderGroup, 33
system RenderSystem<unsigned __int64,7>, 43
(43) has group render::RenderGroup, 33
system RenderSystem<unsigned __int64,8>, 44
(44) has group render::RenderGroup, 33
system RenderSystem<unsigned __int64,9>, 45
(45) has group render::RenderGroup, 33
system RenderSystem<unsigned __int64,10>, 46
(46) has group render::RenderGroup, 33
system RenderSystem<unsigned __int64,11>, 47
(47) has group render::RenderGroup, 33
system RenderPrepareSystem, 48
(48) has group RenderPrepareGroup, 34
system RenderFinishSystem, 49
(49) has group RenderFinishGroup, 35
(32) has runBefore edge render::RenderGroup, 33
(34) has runBefore edge render::RenderInitGroup, 32
(35) has runAfter edge render::RenderGroup, 33
I interpret it as RenderPrepareGroup (RenderPrepareSystem) starts at the beginning, afterwards start working RenderInitGroup (RenderInitSystemX, 6 systems), after that works RenderGroup (RenderSystemX, 6 systems) and at the end of pipe start working RenderFinishGroup (RenderFinishSystem).
But I saw in the tracy something strange: Firstly launches RenderInitGroup, then RenderGroup, afterwards RenderPrepareGroup and finally RenderFinishGroup, that sounds strange for me. At least RenderInitGroup and RenderGroup work as intended.
What do I wrong? or may be is there some bug?
ecs::DependsOn is something that is meant for systems created via World::system (and is not implemented in the current master).
If you use the undocumented BaseSystemManager systems, you need to override their DependsOn virtual function.
You can expect the support for ecs::DependsOn to land on master very soon. I only have to find time to test the feature properly and write unit tests for it.
ecs::DependsOn is something that is meant for systems created via World::system (and is not implemented in the current master).
My systems are just wrappers around World::system(). In their ctor I do something like that:
TransformSystem::TransformSystem(gaia::ecs::World& w)
{
m_builder = w.system();
auto callback = std::bind(&TransformSystem::tick, this, std::placeholders::_1);
m_builder.all<LocalTransformComponent, WorldTransformComponent&>()
.changed<LocalTransformComponent>()
.on_each(callback);
}
I see. In that case you will have to wait a tiny bit until I push the support for ecs::DependsOn to master. Like I said, it should happen not too long from now.
I see. In that case you will have to wait a tiny bit until I push the support for ecs::DependsOn to master. Like I said, it should happen not too long from now.
Sounds fine, because I started thinking that I do something wrong:)
@richardbiely May I ask also systems within child relationship will take into account their parents' DependsOn relationships?
What I mean: In my case above I put all RenderInitSystems into the system/group RenderInitGroup. There will be enough to add DependsOn only for RenderInitGroup to move the all systems inside the graph?
Yes, but there's yet another thing that needs to happen before that - support for hierarchies needs to be implemented for queries. This is the next thing that will happen after DependsOn.