Question on the implementation of my Entity System
- by miguel.martin
I am currently creating an Entity System, in C++, it is almost completed (I have all the code there, I just have to add a few things and test it). The only thing is, I can't figure out how to implement some features. This Entity System is based off a bit from the Artemis framework, however it is different.
I'm not sure if I'll be able to type this out the way my head processing it. I'm going to basically ask whether I should do something over something else.
Okay, now I'll give a little detail on my Entity System itself. Here are the basic classes that my Entity System uses to actually work:
Entity - An Id (and some methods to add/remove/get/etc Components)
Component - An empty abstract class
ComponentManager - Manages ALL components for ALL entities within a Scene
EntitySystem - Processes entities with specific components
Aspect - The class that is used to help determine what Components an Entity must contain so a specific EntitySystem can process it
EntitySystemManager - Manages all EntitySystems within a Scene
EntityManager - Manages entities (i.e. holds all Entities, used to determine whether an Entity has been changed, enables/disables them, etc.)
EntityFactory - Creates (and destroys) entities and assigns an ID to them
Scene - Contains an EntityManager, EntityFactory, EntitySystemManager and
ComponentManager. Has functions to update and initialise the scene.
Now in order for an EntitySystem to efficiently know when to check if an Entity is valid for processing (so I can add it to a specific EntitySystem), it must recieve a message from the EntityManager (after a call of activate(Entity& e)). Similarly the EntityManager must know when an Entity is destroyed from the EntityFactory in the Scene, and also the ComponentManager must know when an Entity is created AND destroyed.
I do have a Listener/Observer pattern implemented at the moment, but with this pattern I may remove a Listener (which is this case is dependent on the method being called). I mainly have this implemented for specific things related to a game, i.e. Teams, Tagging of entities, etc.
So... I was thinking maybe I should call a private method (using friend classes) to send out when an Entity has been activated, deleted, etc.
i.e. taken from my EntityFactory
void EntityFactory::killEntity(Entity& e)
{
// if the entity doesn't exsist in the entity manager within the scene
if(!getScene()->getEntityManager().doesExsist(e))
{
return; // go back to the caller! (should throw an exception or something..)
}
// tell the ComponentManager and the EntityManager that we killed an Entity
getScene()->getComponentManager().doOnEntityWillDie(e);
getScene()->getEntityManager().doOnEntityWillDie(e);
// notify the listners
for(Mouth::iterator i = getMouth().begin(); i != getMouth().end(); ++i)
{
(*i)->onEntityWillDie(*this, e);
}
_idPool.addId(e.getId()); // add the ID to the pool
delete &e; // delete the entity
}
As you can see on the lines where I am telling the ComponentManager and the EntityManager that an Entity will die, I am calling a method to make sure it handles it appropriately. Now I realise I could do this without calling it explicitly, with the help of that for loop notifying all listener objects connected to the EntityFactory's Mouth (an object used to tell listeners that there's an event), however is this a good idea (good design, or what)?
I've gone over the PROS and CONS, I just can't decide what I want to do.
Calling Explicitly:
PROS
Faster?
Since these functions are explicitly called, they can't be "removed"
CONS
Not flexible
Bad design? (friend functions)
Calling through Listener objects
(i.e. ComponentManager/EntityManager inherits from a EntityFactoryListener)
PROS
More Flexible?
Better Design?
CONS
Slower? (virtual functions)
Listeners can be removed, i.e. may be removed and not get called again during the program, which could cause in a crash.
P.S. If you wish to view my current source code, I am hosting it on BitBucket.