我目前正在制作一个Entity-Component-System程序作为学习C ++的一种方式(我知道这可能不是推荐的方式,但是我很开心)。到目前为止进展顺利,但我希望对此做更多的改进。
每个系统当前都以std::function
的形式添加到ECS管理器中,并带有需要运行哪些组件的签名。我当前的策略是遍历每个系统和实体,如果组件签名匹配,则使用实体id作为参数调用系统功能。
// System function
static Game::runSystem(Manager & mngr, int id) {
ComponentA * a = mngr.getComponent<ComponentA>(id);
ComponentB * b = mngr.getComponent<ComponentB>(id);
// Do something with a and b
}
此功能通过此方法附加到Manager:
// Definition
template<typename...Args>
void Manager::addSystem(std::function<void(XManager & mngr, int id)> f); // A bitmask signature is generated based on the template
// Use
manager.addSystem<ComponentA, ComponentB>(Game::runSystem);
ComponentA
和ComponentB
是简单的通用类型。如果需要,我甚至可以将一个分量设为float
或int
。使用getComponent<T>()
时,这些元素将转换为适当的指针。
这一切都很好,但是最终发生的是,我必须为每个系统都包括Manager的头文件,并且我希望它们不要相互绑定(我想这是关注点分离)。] >
最好每个过程最终看起来都与此类似:
static Game::runSystem(ComponentA * a, ComponentB * b) { // Do something with a and b }
系统唯一需要知道的是它正在处理的特定实体的组件指针。
我目前正在根据其类型的位掩码将组件存储在std::unordered_map
中。当需要组件时,模板提供了一种类型,我可以根据该类型制作位掩码,然后进行投射。我不确定是否可以存储要转换的组件的类型,因此我认为每个组件都必须作为空指针传递给函数。但是C ++不允许我在不知道类型的情况下从void*
隐式转换为另一个指针。有没有一种方法可以存储每个组件的类型,以便以后在需要时进行投射?
我想我可能可以为系统所需的每个组件都定义一个带有void*
的函数定义,但是从直觉上看,这似乎是一个坏主意。它根本不是类型安全的,通过查看函数声明,我将无法知道它需要哪些参数。
如何传递对可以采用任意数量的任何类型的指针的函数的引用?有没有办法通过模板执行此操作,或者我可以在不知道类型的情况下隐式转换一个void指针?我也对其他策略持开放态度。
我目前正在制作一个Entity-Component-System程序作为学习C ++的一种方式(我知道这可能不是推荐的方式,但是我很开心)。到目前为止进展顺利,但我希望提出一些...
ECS的问题在于每个人对他们如何看待ECS都有自己的解释。