Entitas 四 Context 上下文

上下文(Context)

上下文是实体的管理数据结构。实体不能单独创建,必须通过 context.CreateEntity() 来创建。这样一来,上下文就可以管理我们创建的所有实体的生命周期。它还是第一个在我们操作实体时被通知的观察者(请参阅实体章节中的实体观察部分)。

实体对象池

为了避免垃圾回收,Entitas-CSharp 中的上下文具有内部对象池。它包含已销毁的实体,在用户创建新实体时将被重用。这样,堆上的内存得到了循环利用。只有当我们确保没有人再持有对该实体的引用时,才能重新使用实体。这就是为什么 Entitas-CSharp 具有内部引用计数机制。如果您仅使用原始的 Entitas,不在自己的代码中持有任何对实体的引用,您不需要考虑它。内部类已经为您处理了所有的引用计数。然而,如果您想要创建像这样的组件:

class Neighbour: IComponent {
    public IEntity reference;
}

或者有一个引用实体的 MonoBehaviour

class EntityLink : MonoBehaviour {
    IEntity _entity;
}

那么当存储引用时,您需要调用 _entity.Retain(this);。在不再对实体感兴趣或存储引用的对象被销毁时,不要忘记调用 _entity.Release(this);。如果您忘记调用 Release,销毁的实体将被保留并永远不会被重用。实际上,这会导致内存泄漏,您可以在 Entitas Visual Debugger 中轻松观察到。如果您忘记调用 Retain,您可能会得到一个被重生的实体版本。这将导致非常奇怪的行为,非常难以调试。

顺便说一下,我们不鼓励具有对另一个实体引用的组件,而更倾向于使用实体索引(请参阅索引章节)。而且 EntityLink 现在是 Entitas.Unity 插件的一部分,所以如果您只需要引用 GameObject 上的实体,就不用担心了。我们替您考虑好了。

多个上下文类型

如果将典型的关系型(基于表的)数据库与 Entitas 进行比较,我们可以得出以下关联。一个组件是一个列,一个实体是一行,上下文本身就是一个表。现在,在关系型数据库中,一个表是由模式定义的。在 Entitas 中,它基于实现了 IComponent 的类。这意味着,当我们定义更多的组件类时,我们的表就变得更广泛了。根据实现细节,这可能会对内存消耗产生影响。在 Entitas-CSharp 的情况下,实际上的确会对内存消耗产生影响,因为实体由 IComponent 数组支持。

为了解决表大小增长的问题,我们可以引入另一个表。
这是 Entitas-Csharp Wiki 中的一个片段:

using Entitas;
using Entitas.CodeGenerator;

[Game, UI]
public class SceneComponent : IComponent
{
    public Scene Value;
}

[Game]
public class Bullet
{
    // Since it doesn't derive from 'IComponent'
    // it will be generated as 'BulletComponent'
}

[Meta]
public struct EditorOnlyVisual
{
    public bool ShowInMode;

    public EditorOnlyVisual(bool show) {
        this.ShowInMode = show;
    }
}

上面组件类声明中的注解告诉代码生成器我们想要哪些上下文类型。在这个特定的示例中,我们有一个 GameMetaUI 上下文。正如您在 SceneComponent 中所看到的,一个组件可以是多个上下文的一部分。这意味着 - 表 Game 和表 UI 都可以拥有列 Scene,如果我们希望将其再次映射到关系型数据库的心智模型。

我应该有多少个上下文类型?

这取决于您的用例。如果您有一个相当小/简单的游戏,您可以只使用一个上下文。这样更简单。您只需要记住,实体由 IComponent 数组支持,这意味着它是一个指针数组,而指针在 64 位架构上占用 8 字节。因此,如果您有 50 个组件,每个实体的大小至少为 400 字节。如果您的游戏中有 100 个实体,它们将占用 40KB。现在由您来决定 40KB 是多还是少。如果您的游戏中有数百个组件和成千上万个实体,最好开始切片。

有时,出于组织目的,将组件切片到不同的上下文中也是有益的。您可能有一些仅在核心游戏上下文中需要的组件,以及一些仅与元游戏相关的组件。如果绝对没有重叠,也就是不会有一个实体需要同时存储组件 A 和组件 Z,那么最好将它们放在不同的 “表” 中。

上下文观察

与实体一样,上下文也可以被观察以检测更改。这也是我们在内部用于组(在其自己的章节中描述)和可视化调试器的方式。
如果您想为 Ent

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值