【发布时间】:2013-07-02 03:53:08
【问题描述】:
我在为实体组件系统设计内存管理时遇到了一些问题,并且在设计细节方面遇到了一些问题。这是我想要做的(请注意,除了Entity 之外的所有这些类实际上都是虚拟的,因此会有许多不同的具体实现):
Program 类将有一个 Entity 的容器。 Program 将循环通过Entity 并在每个上调用更新。它还会有几个SubSystem,它还会在每个循环中更新。
每个Entity 将包含两种类型的Component。它们都将由Entity 内的unique_ptr 拥有,因为它们的生命周期与实体直接相关。一种类型,UpdateableComponent,将在调用Entity.update() 方法时更新。第二种类型SubSystemComponent 将从它们各自的SubSystem 中更新。
现在这是我的两个问题。首先是一些Component 将控制其父Entity 的生命周期。我目前对此的想法是Component 将能够调用函数parent.die(),这将更改Entity 中的内部标志。然后在Program 完成循环更新后,它会第二次循环并删除在上次更新期间标记为删除的每个Entity。我不知道这是否是一种有效或聪明的方法,尽管它应该避免Entity 在其Component 仍在更新时死亡的问题。
第二个问题是我不确定如何从SubSystem 中引用SubSystemComponent。因为它们是由Entity 内部的unique_ptr 引用的,所以我不能使用shared_ptr 或weak_ptr,并且当拥有组件的Entity 死亡时,标准指针最终会悬空。我可以为这些切换到Entity 中的shared_ptr,然后在SubSystem 中使用weak_ptr,但是我不想这样做,因为重点是Entity 完全拥有它Component 的。
所以两件事:
- 能否以有意义的方式改进我的第一个想法?
- 有没有一种简单的方法可以用
unique_ptr实现weak_ptr类型的功能,或者我应该切换到shared_ptr并确保不要创建多个shared_ptr到SubSystemComponent' s
【问题讨论】:
-
我认为你可能想对内存管理做更多的研究,除非你对这个设计死心塌地;多次循环遍历整个分配的内存空间将不可扩展。智能指针始终是一种很好且简单的初始启动方式。此外,已经有一些完善的 C++ 库可以执行garbage collection。
-
@Aggieboy 我已经考虑过缩放问题,并且已经解决了仅将部分数据加载到
Entity的问题,这将我限制在几千个(最多可能 10-20 个)一次。如果我简单地调用一个 bool getter,并且可以选择从容器中删除Entity,那么第二个循环真的会那么低效吗?这样的设计更多是为了提高代码的复用性而不是性能,后期我可以轻松优化瓶颈。 -
您可以在尝试更新组件之前简单地检查
hasToDie标志,这不是问题。但是,unique_ptrs 明确设计用于单一、严格的所有权。只要不止一个对象需要引用(保证始终有效或至少可检查),您就不会超过shared_ptr和可能的weak_ptr,正如您已经指出的那样。 -
@arne 我在更新循环期间检查的一个问题是想象更新检测到冲突。第一个实体将能够与“死”对象发生碰撞,而最后一个实体则不会。虽然,如果我首先循环更新,检查死亡,然后进行子系统更新,其中包括碰撞之类的交互。 . .也许这会简化它。
标签: c++ memory-management