I've recently discover the Entity System architecture and i've got some difficulties to do it in C++ / understand implementation.
How i see Entity System :
Components : A class with attributs, set and get.
- Sprite
- Physicbody
- SpaceShip
- ...
System : A class with a list of components.
- List item
- EntityManager
- Renderer
- Input
- Camera
- ...
Entity : Just a empty class with a list of components.
What i've done :
Currently, i've got a program who allow me to do that :
// Create a new entity/
Entity* entity = game.createEntity();
// Add some components.
entity->addComponent( new TransformableComponent() )
->setPosition( 15, 50 )
->setRotation( 90 )
->addComponent( new PhysicComponent() )
->setMass( 70 )
->addComponent( new SpriteComponent() )
->setTexture( "name.png" )
->addToSystem( new RendererSystem() );
If I've correctly understood the EntitySystem, each System has its own list of components on which it works. (List of components or list of entity, that is the question)
class Component;
/////////////////////////////////////////////////
/// \brief An abstract system. (Interface)
///
/////////////////////////////////////////////////
class System
{
public:
/////////////////////////////////////////////////
/// \brief Call when process is created.
///
/////////////////////////////////////////////////
virtual bool start() = 0;
/////////////////////////////////////////////////
/// \brief Call when process is updated.
///
/////////////////////////////////////////////////
virtual void update() = 0;
/////////////////////////////////////////////////
/// \brief Call when process is removed.
///
/////////////////////////////////////////////////
virtual void end() = 0;
/////////////////////////////////////////////////
/// \brief Call when process is removed.
///
/////////////////////////////////////////////////
virtual void addComponent( Component* component )
{
elements.push_back( component );
}
protected:
std::vector<Component*> elements;
};
(I'had put the code in .h just for fast debug ^^)
The problem
I want add a "T" Component in a System with a list of X components
What i've tried :
std::vector<Component*> elements;
But i want something like that :
std::vector<T*> elements;
My System class is abstract. My System childrens class needs to have this list with is own type.
Solution :
I've tried to put my System class has a template class, so i've just to do : class Renderer : System
But my SystemManager doesn't like this code : std::vector<System> systems
.
System class with T type :
template<class T>
class System
{
public:
/////////////////////////////////////////////////
/// \brief Call when process is created.
///
/////////////////////////////////////////////////
virtual bool start() = 0;
/////////////////////////////////////////////////
/// \brief Call when process is updated.
///
/////////////////////////////////////////////////
virtual void update() = 0;
/////////////////////////////////////////////////
/// \brief Call when process is removed.
///
/////////////////////////////////////////////////
virtual void end() = 0;
/////////////////////////////////////////////////
/// \brief Call when process is removed.
///
/////////////////////////////////////////////////
virtual void addComponent( T* component )
{
elements.push_back( component );
}
protected:
std::vector<T*> elements;
};
SystemManager code :
class System;
class SystemManager
{
public:
/////////////////////////////////////////////////
/// \brief Default constructor.
///
/////////////////////////////////////////////////
SystemManager();
/////////////////////////////////////////////////
/// \brief Call when system is created.
/// \param system A system to add.
///
/////////////////////////////////////////////////
bool addSystem( System* system);
/////////////////////////////////////////////////
/// \brief Call when system is updated.
///
/////////////////////////////////////////////////
void update();
/////////////////////////////////////////////////
/// \brief Call when system is removed.
/// \param system A system to remove.
///
/////////////////////////////////////////////////
void removeSystem( System* system );
private:
std::vector<System*> systemList;
};
With this, i've got this error in my SystemManager : "Redefinition of 'System' as different kind of symbol" (Pointing on the line "class System" in the SystemManager)
Did you have a solution for this problem ? Did my EntitySystem approch is good ?
Thanks!
In your code System is a template, later in the System manager class you try to use System as if it were not a template. This will not work. You need to either specify the type, make system manager a template and pass the type parameter through to system, or not have system be a template. Also forward declaring templates, as a non template no less, isn't going to work. Take a step back and figure out how templates work in C++.
Further more http://gamedev.stackexchange.com has many questions and answers about entity component designs, you might find it useful.