首页 > 解决方案 > 在 ECS 模型中,最合适的观察者容器是什么?

问题描述

我正在为我正在设计的游戏用 C++实现ECS模型。为了处理组件到组件的通信,我正在使用一个观察者系统,其中组件可以订阅(即观察)其他组件。

因为我计划使用对象池,所以我的实体(以及组件)必须占用预先确定的内存量(即在池构建后没有堆内存)。

在观察者模型中实现“主体”类时,主体必须持有对其所有观察者的引用。

鉴于我正在为我的组件使用对象池,因此必须静态分配其中的所有数据,而不是依赖可能对堆进行内存请求调用的容器(例如 std::vector)。

我当前的设计具有一个 std::array ,其中包含指向观察者的指针,但是,我觉得这是一个相当笨重的设计。首先,我无法更改可以订阅主题的最大观察者数量(因为我必须在编译时预先确定数组长度)。其次,从主题中删除观察者很笨拙,因为我必须将每个元素移回以避免 std::array 中的“间隙”。

但是,我确实很欣赏在通知订阅者时快速迭代 std::array 的能力。此外,由于组件订阅者的性质,我不必经常“取消订阅”主题。因此,早先提出的从数组中删除引用的困难有点没有实际意义。

无论如何,我很好奇是否还有其他 STL 容器可能更适合我的应用程序。

标签: c++stlcontainers

解决方案


您可以使用std::vector适当的分配器。

template<typename T>
struct IzzoAllocator
{
    using value_type = T;
    T* allocate( std::size_t n ) { /* do whatever */ }
    void deallocate( T* p, std::size_t n ) { /* do whatever */ }
}

template<typename T>
using IzzoVector = std::vector<T, IzzoAllocator<T>>;

请注意,通过将所有内容放入对象池中,您正在编写一个堆管理器。至少通过这种方式,您可以轻松地将堆实现的性能与平台的性能进行比较


推荐阅读