gaia-ecs icon indicating copy to clipboard operation
gaia-ecs copied to clipboard

Do work properly `ChildOf` and `DependsOn`?

Open obfuscate opened this issue 7 months ago • 7 comments

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?

Image

obfuscate avatar Apr 11 '25 09:04 obfuscate

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.

richardbiely avatar Apr 11 '25 11:04 richardbiely

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.

richardbiely avatar Apr 11 '25 11:04 richardbiely

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);
}

obfuscate avatar Apr 11 '25 11:04 obfuscate

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.

richardbiely avatar Apr 11 '25 11:04 richardbiely

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:)

obfuscate avatar Apr 11 '25 11:04 obfuscate

@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?

obfuscate avatar Apr 11 '25 11:04 obfuscate

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.

richardbiely avatar Apr 11 '25 12:04 richardbiely