我有一个名为Component
的班级。
看起来有点像(PSEUDO CODE):
template <class t>
class Component{
private:
map<Entity, List<t>> attachedEntities;
public:
//Some other stuff like constructors, setters and getters etc.
template<typename... Args>
void addTo(const Entity &en, Args...args)
{
this->addTo(en,std::make_shared<t>(std::forward<Args>(args)...));
}
template < typename U, typename std::enable_if< std::is_base_of<t, U>::value, U>::type* = nullptr >
void addTo( const Entity &en,U* ptr)
{
this->addTo(en,shared_ptr<t>(ptr));
}
void addTo(const Entity &en,const std::shared_ptr<t> ptr)
{
/*
Does the actual adding to the map
*/
}
}
(对于任何想知道实体与此问题的上一版本中的目标相同的人。实体在第二个想法上更有意义)
出于教育目的,我不愿意为传递的变量编写包装器。
如您所见,类Component有3个addTo函数。现在我的系统是一个简单的组件实体系统,其中实体表示一个UUID,用作地图中的键。当这些地图与单个UUID一起进入上下文时,可以“形成”一个完整的实体。
例如,实体可能在
中有一个条目当一个函数遍历所有模型并查找拟合字符串和纹理时,它将呈现我们想要的东西。例如,与模型组件中的实体关联的模型可以是胸部模型,纹理是胸部模型的漫反射纹理,字符串可以简单地说出玩家在与之交互之前应该看到的内容。
这在我的程序中已经很好用!然而,我正在努力的是为对象制作某种模板,然后一遍又一遍地实例化。对于此示例,我可以说我想创建一个代表Bullet
子弹可能有:
这再次起作用,但是现在只是让Enitity免于被删除,只是让其他子弹成为该实体的副本。这很糟糕,原因如下:
我现在要做的是写一个Blueprint
课程
这门课应该只是:
以下是我的想法:
class Blueprint{
private:
vector<function<???>> frozenAddFunctions; //Some way of storing all the functions with the init paramters but WITHOUT the entity specified;
public:
template<t,typename... Args>
void addTo(Component<t>, Args...args){
//Somehow binding the approperate addTo overload to the arguments
}
void applyOnto(Entity &en){
for(function f:this->frozenAddFunctions){
f(en); //somehow invoke the addTo functions onto the Entity.
}
}
如果这是不可能的,请帮助我找到实现这一目标的方法,同时避免我列出的负面因素。
提前致谢。
我希望这种表现更好。
答案 0 :(得分:1)
似乎你想要:
class Blueprint
{
private:
std::vector<std::function<void(Entity &)>> functions;
public:
template<typename T, typename... Args>
void addTo(Component<T>& component, Args...args)
{
functions.emplace_back([=, &component](Entity& ent)
{
component.AddTo(ent, args...);
});
}
void applyOnto(Entity &en)
{
for(const auto& f : functions){
f(en);
}
}
};