I have a simple entity manager with pointers to my component pools. My components are simple POC structs. My component pool is a template class.
Components:
#ifndef COMPONENTS_H
#define COMPONENTS_H
#include "Datatypes/vector3.h"
enum MESH_TYPE
{
STATIC_GROUND_MESH,
ANIMATED_MESH
};
typedef struct
{
Vector3 position;
Vector3 rotation;
} SpatialComponent;
typedef struct
{
float farClipping;
Vector3 target;
} CameraComponent;
typedef struct
{
MESH_TYPE type;
std::string name;
} MeshComponent;
typedef struct
{
Vector3 translate;
Vector3 rotate;
} MovementComponent;
#endif // COMPONENTS_H
ComponentPool:
#ifndef COMPONENTPOOL_H
#define COMPONENTPOOL_H
#include "components.h"
#include "datatypes.h"
#include <boost/container/flat_map.hpp>
#include <algorithm>
#include <vector>
#include <iostream>
#include <climits>
#include <typeinfo>
class ComponentPoolBase
{
};
template <typename T>
class ComponentPool : public ComponentPoolBase, public boost::container::flat_map< EntityId, T >
{
typedef boost::container::flat_map< EntityId, T > Components_t;
public:
ComponentPool()
{
}
T& Get(const EntityId& entityId)
{
return this->at(entityId);
}
int Size()
{
return this->size();
}
bool Has(EntityId entityId)
{
typename Components_t::iterator itr = this->find(entityId);
if(itr == this->end())
{
return false;
}
return true;
}
bool Add(EntityId entityId)
{
try
{
this->insert(boost::container::container_detail::pair< EntityId, T >(entityId, T()));
std::cout << "New component entity id: " << entityId << " Type: " << typeid(T).name() << std::endl;
std::cout << "Count: " << this->size() << std::endl;
return true;
}
catch (std::exception& ex)
{
std::cout << "Exception: " << ex.what() << std::endl;
}
return false;
}
bool Remove(EntityId entityId)
{
try
{
this[entityId] = NULL;
std::cout << "Delete component entity id: " << entityId << " Type: " << typeid(T).name() << std::endl;
return true;
}
catch (std::exception& ex)
{
std::cout << "Exception: " << ex.what() << std::endl;
}
return false;
}
};
#endif // COMPONENTPOOL_H
EntityManager:
#ifndef ENTITYMANAGER_H
#define ENTITYMANAGER_H
#include "Component/componentpool.h"
#include "Component/components.h"
#include "datatypes.h"
#include <iostream>
#include <queue>
class EntityManager
{
typedef std::queue< EntityId > EntityList_t;
public:
EntityManager();
~EntityManager();
void Init();
void Shutdown();
EntityId CreateEntity(const std::string& name);
void DestroyEntity(EntityId entityId);
EntityId GetCreatedEntities();
EntityId GetRemovedEntities();
ComponentPool<SpatialComponent>* m_pSpatialComponents;
ComponentPool<CameraComponent>* m_pCameraComponents;
ComponentPool<MeshComponent>* m_pMeshComponents;
ComponentPool<MovementComponent>* m_pMovementComponents;
private:
EntityList_t* m_pCreatedEntities;
EntityList_t* m_pRemovedEntities;
EntityId getNextId()
{
return ++s_NextId;
}
static EntityId s_NextId;
};
#endif // ENTITYMANAGER_H
My great problem, are the pointers to the ComponentPool. I want to store this in a vector with unique pointer, because the entity manager is the only one, who is responsible for the lifetime of my entites and components.
I thought it should be this way:
std::vector<std::unique_ptr<ComponentPool<ComponentPoolBase*>>> m_ComponentPools;
And I add a unique pointer this way:
m_ComponentPools.push_back(std::unique_ptr<ComponentPool<SpatialComponent>>(new ComponentPool<SpatialComponent>()));
But this doesn't work with a not matching function error in the compiler. Why?
Is there a better solution to implement this component pool and entity manager?