将系统与C ++中的ECS(实体组件系统)管理器分开

问题描述 投票:0回答:1

我目前正在制作一个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);

ComponentAComponentB是简单的通用类型。如果需要,我甚至可以将一个分量设为floatint。使用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 ++的一种方式(我知道这可能不是推荐的方式,但是我很开心)。到目前为止进展顺利,但我希望提出一些...

c++ pointers types void-pointers entity-component-system
1个回答
0
投票

ECS的问题在于每个人对他们如何看待ECS都有自己的解释。

© www.soinside.com 2019 - 2024. All rights reserved.