Jump to content
  • Advertisement
Sign in to follow this  
Techieman

C++ | Storing different types in a unordered_map

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

If you intended to correct an error in the post then please contact us.

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".

 

So, how do I go about this?

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

How do I go about this?

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

Edited by Techieman

Share this post


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

Share this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!