我一直在使用组件实体系统 很久以前,我想改进它以使用内存池。
为简单起见,这是我的古老代码: -
Entity* entity =new Entity();
Com_Physic* comPhys =new Com_Physic();
这是重构的结果: -
Ptr<Entity> entity=centerPool()->createEntity(); //use pool
Ptr<Com_Physic> comPhys=centerPool()->create<Com_Physic>(entity); //use pool
它的效果非常好。 (每次使用的时间 - = 10%)
现在我强烈希望在任何地方都能适应记忆池概念 但是,在涉及某些数据结构的情况下,这很难。
这是一个返回某个实体的所有(默认)物理主体的示例函数 它不是一个真正的完整代码,但足以显示有问题的部分: -
class SystemPhysic : public basicSystem {
//..... other function / field .....
public: MyArray<PhysicObject*> getAllPhysicBody(Ptr<Entity> entity){
Ptr<Com_Physic> comPhysic=entity->get<Com_Physic>();
MyArray<PhysicObject*> allPhy=comPhysic->physicsList;
//^ #problem
return allPhy;
}
};
MyArray<T>
是一个类似于std::vector
的自定义数组。它使用自己的分配器。
这是它的核心: -
void reserve(int expectedSize){
//......
void* databaseNew=operator new [](expectedSize*sizeof(T));
//......
}
因此,每当我致电MyArray<PhysicObject*>::operator=()
时,
...粗略地说,operator new[]
将被召唤。 (#problem
)
记忆再次破碎。
一般数据结构是否应使用内存池概念? 如果是这样,如何将内存池概念专业地集成到数据结构中?
我只是想要一个粗略的想法 完全不包含代码的解决方案是可以接受的。
MyArray<T>
有两种类型的问题: -
MyArray<T>
作为组件的字段(例如Com_Physic
)。MyArray<T>
作为从系统传递到另一个系统的临时消息。它创建速度快,删除速度快。 (&gt; 70%,生命时间= 1个时间步)我有一个想法,将其分为两种情况,ShortLife_MyArray<T>
&amp; LongLife_MyArray<T>
,
......但我认为我太复杂,难以维护。
为了使问题更严重,在真实游戏中,除MyArray<T>
之外还有许多种数据结构,例如MyArray<T1,T2>
,MyMap<T1,T2>
,MySet<T1,&FunctionPointer>
等
这只是显示了我到目前为止的猜测列表。
在MyArray<T>
,MyArray<T1,T2>
,MyMap<T1,T2>
等处创建静态池字段。
所有类型的数据结构都必须使用该静态池在需要时分配内存。
GlobalDataStructure::staticPool=topLevel()->poolPtr;
//called only once before everything start
缺点: -
mutex
来锁定游泳池。在MyArray<T>
,MyArray<T1,T2>
,MyMap<T1,T2>
等中创建非静态池字段。
每当我想创建一个新的数据结构时,
...我必须 传递 共享池(来自顶级游戏逻辑)。
MyArray<T> arr=MyArray<T>(topLevel()->poolPtr); //messy
对于不同的情况,可以有许多池。这可能很好。
当数据结构想要分配时,它必须使用该池。
缺点: -
mutex
锁定池。 不要做任何事情,实体和组件的池应该足够了 其他解决方案是过度工程。