C++ | Storing different types in a unordered_map

This topic is 1237 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

Hi,

for my current project I need a fast data-oriented yet flexible entity component system which integrates good with my build system (Qt Build Suite, CMake's syntax gives me cancer).

I looked for some projects, came across "EntityX" and "Anax" and few more, but none was easy to integrate into my project.

So I had to implement my own one. I thought it won't be as hard as it appears now.

My naiv approach was to create an "std::unordered_map" with an RTTI-ID as key and an "std::vector<IBaseComponent>" as a value.

Well, today I learned the principle of "object slicing".

I want my "Scene" class (aka "World" in some implementations) to hold every component in a contiguous memory block.

P.S: Are there any baseclasses for a "std::vector" ? :)

Edited by Techieman

Share on other sites
You can use a thin template. Usually you'd want to keep the components strongly separated into a structure-of-arrays, though.

Share on other sites

I haven't written any ECS architectures myself, I've just read alot about them.

Bearing my inexperience in mind, why do your components have a base class?

Why can't you do:

class Scene
{
std::vector<GraphicsComponent> graphicComponents;
std::vector<PhysicsComponent> physicsComponents;
//...etc...
};


But I guess another question is, why does the Scene own the components? Aren't Systems supposed to own their own components?

class GraphicSystem
{
public:
void Render();
private:
std::vector<GraphicsComponent> graphicComponents;
};

class PhysicsSystem
{
public:
void HandlePhysics();
private:
std::vector<PhysicsComponent> physicsComponents;
};

Share on other sites
Although I agree that this is probably not the solution you are looking for, there are ways to make containers of polymorphic objects. You need to use some sort of pointer to a base class to get polymorphic behavior and no slicing. A good first choice is `std::vector<std::unique_ptr<BaseComponent>>' (in C++11).

Share on other sites
Currently the only solution that comes to mind, is to preallocate some storage. Instances are then being created using placement new syntax. I could still use pointers but in a DOD manner.

Are there any alternatives?

Share on other sites

Not that I'd suggest using them for an ECS system, but there are options for dynamic types beyond standard inheritance.  boost::variant and boost::any are two examples.

Share on other sites

Thanks @ServantOfTheLord,

but I think I've got you wrong at some point.

I am not going to store every component in one array. Instead I wanted to

have an dictionary of vectors. Every vector belongs to exactly one component type

as they're indexed by the component id.

Is there actually a reference for creating an ECS that is data oriented?

"Anax" & "EntityX" aren't or probably not sure. I'll give it one more look for sure.

Thanks to everybody who replied ;)

Share on other sites
A dictionary of vectors makes no sense to me. How do you envision using such a container?

Share on other sites

There already exist standard containers for what you are doing yourself:

std::multimap and std::unordered_multimap

The other points still hold true though. This is usually not how ECS are implemented.

• What is your GameDev Story?

In 2019 we are celebrating 20 years of GameDev.net! Share your GameDev Story with us.

• 28
• 16
• 10
• 10
• 11
• Forum Statistics

• Total Topics
634113
• Total Posts
3015569
×