The intro to this problem is a bit of a long one so my apologies in advance. In short I am asking for suggestion as to what type of collection I should use to store data for a particular part of my system.
I have an entity component system in place where a static EntityManager creates and stores components within vectors of their own type, and creates Entities storing them in either a vector for dynamic entities or a vector for static entities. Something like this:
#define COMPONENTS X(MeshComponent) X(CameraComponent) X(PointLightComponent) X(DirectionLightComponent)
#define X(ARG) std::vector<ARG>,
using ComponentTuple = std::tuple<COMPONENTS Empty>;
#undef X
class EntityManager {
static ComponentTuple components;
vector<Entity>& getDynamicEntities() {
static vector<Entity> entities;
return entities;
}
vector<Entity>& getStaticEntities() {
static vector<Entity> entities;
return entities;
}
}
Without getting into too much detail each Entity has an id (stored as a short
which determines its dynamic or static status and its index within the respective vector).
Each Component has its own id (an unsigned short
referring to its index in its respective vector) and an Entity id, referring to the entity it is "attached" to.
At this point all the Entity object is, is an ID and useful functions. To make it more useful I decided to let the Entity object store a collection of id's (unsigned shorts) of its own components (to make searching for the entities specific components faster). My initial plan was to use an unordered_map
data structure it like so:
class Entity {
friend class EntityManager;
private:
short id = SHRT_MAX;
std::unordered_map<std::type_index, vector<unsigned short>> components;
}
Thinking on it though, this introduces at least two (from what I can see) levels of indirection. One to the hash table produced by the unordered map and another to the vector storing the actual id's. With this in mind I was wondering if anyone else would be able to suggest a more cache friendly data structure. If not a simple reassurance that my choice was a correct one will also suffice (as right now I can't help but feel that there is a better way).
Some of the things that I would like the collection to do:
1) I would like to be able to search the collection by ComponentType (because components may share the same ID but be stored in different vectors)
2) I would like the collection to be expansive (not all entities will have the same components and it just seems wasteful to have an array for all potential Component Types when the entity may only have one)
3) I would like the potential to have multiple Components of the same Component Type in the collection (in the example given above maybe some Components have two PointLightComponent
s)
Any suggestions or comments would be greatly appreciated as I've been wracking my brain on this one for some time now. Thanks in advance.
unordered_map
is implemented internally, yet you're wracking your brain? Get on with your game, and optimise much later on. It won't be the end of the world to replace theunordered_map
if you have to. But until you see the game design underperforming in a real-world use-case, you won't know what to address. Address it now, and you almost certainly won't be addressing that which you'll have ultimately needed to address. Facepalm when you then realise the time you wasted on this. There's little point in optimisation that is uninformed. Use what works, for now. \$\endgroup\$