ECS:自创建以来查找实体的大小&减少冗余代码

时间:2017-08-16 03:20:37

标签: c++ memory-management entity c++14 game-engine

我正在尝试优化实体组件系统游戏引擎(ECS)。

版本A

目前,通过3个步骤创建船舶实体。

  • SystemShip请求ECS创建新的空白实体
  • SystemShip要求ECS附加ComShip
  • SystemShip要求SystemHP附加任何组件 SystemHP 想要以使某个实体具有HP功能

这是1个实体的记忆布局 (我知道有几种方法,但我决定选择这种布局。)

enter image description here

它运行正常,这是存根(可运行): -

class Entity{};
class ECS{
    public: static Entity createEntity(){
        return Entity();
    }
    public: template<class C> static void attach(Entity e){
        //some logic that extend memory used for "e" 
        //   also placement new (...) C();
        return;
    }
};
class ComHP{};
class SystemHP{
    public: static void addHPFeature(Entity e){
        ECS::attach<ComHP>(e);
        // set some value to the ComHP instance
        return;
    }
};
class ComShip{};
class SystemShip{
    public: static Entity createShip(){
        Entity entity=ECS::createEntity();
        ECS::attach<ComShip>(entity);
        SystemHP::addHPFeature(entity);
        return entity;
    }
};
int main(){
    Entity e=SystemShip::createShip();
}

版本B

我后来发现上述方法对内存管理不太友好。

如果ECS知道实体创建时所需的每个类型组件,那么优化要好得多,如果我知道在程序开头(即使用模板),那就更好了。

使用以下解决方案,它可以保留正确的内存大小。 (标记为##HAPPY##
这是设计的存根: -

class Entity{};
class ECS{
    public: template<class ...C> static Entity createEntity2(){
        //##HAPPY##
        //some logic that extend memory used for "e" 
        //   also placement new (...) ComShip() and ComHP();
        return Entity();
    }
};
class ComHP{};
class SystemHP{
    public: static void addHPFeature(Entity e){
        // set some value to the ComHP instance
        return;
    }
};
class ComShip{};
class SystemShip{
    public: static Entity createShip(){
        Entity entity=ECS::createEntity2<ComShip,ComHP>();
        SystemHP::addHPFeature(entity);
        return entity;
    }
};
int main(){
    Entity e=SystemShip::createShip();
}

问题

虽然它有效,但版本B有三个缺点: -

第一

现在,SystemShip必须识别SystemHP想要的组件类型。

它以某种方式打破了封装,并且维护起来相当困难。

如果SystemHP需要更多组件来实施HP功能,我需要重构SystemShip以及其他调用SystemHP::addHPFeature()的地方。

第二

版本B的代码以某种方式重复: -

 1. Entity entity=ECS::createEntity2<ComShip,ComHP>(); //ComHP <-- forget
 2. SystemHP::addHPFeature(entity);                    //HP again

比较版本A: -

 SystemHP::addHPFeature(entity);                       //one line

这有点容易出错:我可能忘记在创建实体时添加ComHP

第三

SystemShip要求ComHP的完整定义 它可以通过使用std :: function或其族来缓解,但是会受到函数指针(或v表)的影响。

问题

如何减轻B版的缺点?

修改
我认为部分解决方案是让SystemHP具有包类型def 可能SystemHP::allTypesRequired我可以像createEntity3<ComShip,SystemHP::type_allTypesRequired>()一样使用它 我必须找到一种方法来压缩它并将其解压缩回组件类型列表({ComHP})。

0 个答案:

没有答案