I am done with my game's framework and I am trying to implement a life-management system. My framework so far has:
- Systems that hold pointers to the Entities they are interested in.
- An Engine class that owns the different systems.
- An EntityManager that owns the Entities.
Now every time you add/remove a Component to/from an Entity, the Entity notifies the engine class to run a(n) (un)registration routine that passes the Entity to the Systems which in turn decide whether they want to (un)register the Entity or not.
Say that I have a DestroyerSystem that remembers all Entities with a HealthComponent and is responsible for deleting the ones with no life:
void DestroyerSystem::update(float dt = 0)
{
for (auto& entity : registered_entities)
{
if (entity.getComponent<HealthComponent>().hp == 0)
{
EntityManager.destroy(entity);
}
}
}
The problem is that the Systems are supposed to keep valid pointers to the Entities and I am not sure how I can achieve that cleanly.
The only solution that I have so far is to make the Systems have an unregister() function that takes the pointer to the deleted element and erases it from the registered_entities container. The Engine class would also have an unregister() function that would call the unregister() functions of the Systems. This works good for the other systems but creates problems when applied to the DestroyerSystem because it breaks iteration. To tackle this I copy the container and iterate on that one instead:
void DestroyerSystem::update(float dt = 0)
{
auto entities = registered_entities;
for (auto& entity : entities)
{
if (entity.getComponent<HealthComponent>().hp == 0)
{
entityManager.destroy(entity);
engine.unregister(entity);
}
}
}
Does anyone have any better proposals for this?