0

我正在为组件创建实现工厂模式,并希望为工厂创建的每种类型的所有实例实现一个单例容器。理想情况下,这将是工厂中创建的每种类型的一个向量。

如果我可以将基类指针保留在向量中,这将非常容易,但是我的用例非常希望所有实例都连续存储,而不是 new 将它们放在任何地方以获得尽可能多的缓存命中。

我正在考虑为工厂地图做这样的事情:

Map<string,pair<constructorFnPtr, vector<baseClass>>

这具有丢失派生类中的数据的问题,因为它被强制转换为基类。

我还认为将指向向量的指针作为该对的第二个成员将是一个很好的方法,但我不确定如何在每个向量中存储不同的数据类型的同时实现这一点。我认为这是不可能的,因为模板化的向量在技术上都是不同的类。

有什么办法可以做我想做的事吗?在过去的几天里,我一直试图弄清楚一些事情,但没有运气。

或者,如果有另一种存储向量的好方法(即作为组件类的静态成员),我也愿意接受任何类似的建议!

4

2 回答 2

2

我不会考虑将工厂模式用于组件,而是使用对象池模式,因为您可能希望使用工厂模式来管理实体的创建。

我为所有组件使用一个基Component类。这使我能够管理每个组件的一些静态运行时类型信息并公开一组常用方法。然后我实现了一个接口IComponentPool,它是我的组件对象池的契约。然后我定义了一个ComponentPool<T>IComponentPool. 在这个模板类里面是我管理两个向量/数组的地方。然后有一个ComponentPoolMap暴露一些类似地图的行为来查找ComponentPool<T>基于组件类型的。

现在在ComponentPool<T>类中,第一个数组是用作查找的稀疏数组。它保存了一个索引偏移量,该偏移量指向组件在第二个密集压缩数组中的位置。稀疏数组可能只是一种获取 EntityId 并将其转换为组件所在位置的方法。如果您愿意,可以在此类框架之上轻松实现更复杂的句柄系统。

这里的想法是,打包密集充当您的连续内存缓冲区,您可以在紧密循环中轻松地在缓存友好的庄园中进行迭代,但稀疏数组在每个实体的基础上为组件提供单级间接查找。

现在,工厂模式是您创建EntityEntityId处理实体并创建构成 Orc、Zombie 或任何游戏的所有必要方面的地方。工厂充当位于游戏对象系统之上的层,您ComponentPoolMap可能只是该系统的一小部分。

于 2014-10-03T02:23:54.050 回答
0

你不能用 std::vector 的连续对象来做到这一点。

原因是:工厂应该构建对象,然后返回指向它们的指针。问题是指针将存储在您的应用程序中,而下一次调用your_vector.push_back()可能会使它们无效,正如 C++ 文档所说:

如果新的 size() 大于 capacity() 则所有迭代器和引用(包括过去的迭代器)都将失效。否则只有过去的迭代器无效。

因此,您下次致电工厂可能会使您之前的所有电话无效。

于 2014-10-01T15:20:14.797 回答