Can I gain access to a “component” by type?

2019-05-15 12:32发布

I have a class like this:

class Component1 {...};
class Component2 {...};
class Component3 {...};

class Entity
{
  Component1 c1;
  Component2 c2;
  Component3 c3;
public:
  Component1& get_c1() { return c1;}
  Component2& get_c2() { return c2;}
  Component3& get_c3() { return c3;}
};

Basically the Entity is a container of all possible types of components (with other stuff, too). My problem is that I have more than 15 different components and I don't like to copy&paste lines this way. I'm looking for something like:

myEntity.get<Component1>();

to obtain the component I need. I took a look at boost::tuple which is cool but it allows access using an integer as key. I could use a public static const integer in each Component* class and gain access like this:

myEntity.get<Component1::id>();

but then I have to make sure to use different ids for each component and that's bad for mantainance.

Is there a way to "map" a type to a value of that type using magic (i.e. templates), so that myEntity.get<Component1>() works as expected?

I'd also like to have O(1) access to a component since the myEntity::get<T> is used very often (not that with 15-20 components makes sense talking about complexity anyway) but that's not mandatory.

8条回答
Bombasti
2楼-- · 2019-05-15 13:19

Consider using a boost::fusion::map, this allows you to map types to values, for example:

typedef fusion::map<pair<Component1, Component1>, pair<Component2, Component2> etc.> map_t;
map_t m(make_pair<Component1>(Component()), make_pair<Component2>(Component2()));
// to access
at_key<Component1>(m); // reference to instance of Component1

I think the above is correct, sorry about brevity, not easy on iPhone!

EDIT: Actually, as pointed out by @Eugine below, boost::fusion::set is a better match, similar thing to above:

typedef fusion::set<Component1, Component2, etc.> set_t;
set_t s(Component1(), Component2());
// to access
at_key<Component1>(s); // reference to instance of Component1
查看更多
forever°为你锁心
3楼-- · 2019-05-15 13:20

I might be wrong, but it seems to me what you're looking for is Boost.Variant

But, if you want ALL the components to be available and have one instance of each component, then variants are not for you.

查看更多
登录 后发表回答