我想实现实体组件系统,其中每个实体都有一个组件列表。每个组件都来自BaseComponent类。实体中的每个组件都是唯一的--例如,实体不可能有两个TransformComponent组件。我希望能够使用getComponent()方法对实体中的组件进行快速和类型安全的访问:
template <typename T>
T * getComponent();在实体中实现组件容器的最佳方法是什么?
PS:我有很多实体(大约10-20,000),每个实体大约有2-3个组件,10是最大的。所以我担心unordered_map对我的任务来说太重了。
发布于 2015-02-19 16:34:37
我建议使用元组方法来确定您的其他需求是什么:
#include <utility>
template <typename...Components>
class Entity : private Components... {
public:
Entity() = default;
Entity(Components...components) :
Components(std::move(components))... {}
template <typename T>
T& get() {
return *this;
}
template <typename T>
const T& get() const {
return *this;
}
};
#include <iostream>
struct ComponentA { void f() const { std::cout << "I'm a ComponentA\n"; } };
struct ComponentB { void f() const { std::cout << "I'm a ComponentB\n"; } };
struct ComponentC { void f() const { std::cout << "I'm a ComponentC\n"; } };
int main() {
{
Entity<ComponentA, ComponentB, ComponentC> e;
e.get<ComponentC>().f();
e.get<ComponentB>().f();
e.get<ComponentA>().f();
}
{
ComponentA a;
Entity<ComponentA, ComponentB> e{a, {}};
}
{
// error: duplicate base type
// Entity<ComponentA, ComponentA> invalid_entity;
}
}它的优点是所有类型都是具体的,甚至不需要关联Component类型。
发布于 2015-02-20 08:19:35
我决定使用简单的方法在实体中包含数组*BaseComponent m_compsMAX_COMPONENTS,并为每种组件类型分配唯一的id。因为组件类型的数量限制在20-30个。通过这种方式,我可以最快地访问组件,在实体中存储20-30个指针的开销很小(并且它们将在一个块中分配,实体本身允许良好的缓存局部性)。
我使用此代码进行类型安全访问:
template <typename T>
T * Entity::getComp()
{
return (T*)m_comps[T::idCompType];
}每个组件都应该声明const静态成员idCompType
https://stackoverflow.com/questions/28609329
复制相似问题