Skip to content

createComponent() ​

创建一个同步 setup 的 Entity-local Component Definition。

签名 ​

ts
interface ComponentContext {
  readonly engine: Engine;
  readonly entity: Entity;
  onDestroy(handler: () => void): void;
}

interface ComponentDefinition<T> {
  readonly name: string;
  readonly setup: (context: ComponentContext) => T;
}

function createComponent<T>(
  name: string,
  setup: (context: ComponentContext) => T,
): ComponentDefinition<T>;

每个 Entity 首次 add 该 Definition 时同步执行一次 setup,并原样保存返回值:

ts
interface Health {
  current: number;
  maximum: number;
}

const Health = createComponent('health', ({ entity, onDestroy }) => {
  const health: Health = { current: 80, maximum: 100 };
  const unsubscribe = observeHealth(entity.object, health);
  onDestroy(unsubscribe);
  return health;
});

const health = entity.addComponent(Health);
health.current -= 10;

entity.addComponent(Health) === health; // true,重复 add 幂等
entity.getComponent(Health) === health; // true,exact identity
entity.hasComponent(Health);            // true
entity.removeComponent(Health);         // true

语义 ​

  • name 只用于诊断;同名调用仍返回互不冲突的 Definition identities。
  • ComponentDefinition 是 structural type,不携带 nominal brand;createComponent() 是负责输入校验与冻结的规范构造入口,Engine 运行时只按传入 Definition 的 object identity 区分 owner,不验证其构造来源。
  • setup 只接收 engine、entity 与 setup 期 onDestroy,没有 installation input、enabled 或 frame hooks。
  • setup 严格同步。Promise 与自定义 thenable result 会使 add 失败,失败候选不会进入 Entity lookup 或 World Query。
  • setup result 可以是对象、undefined marker 或 primitive。Engine 不 clone、freeze、proxy、markRaw 或自动调用其 dispose()。
  • 可变状态应返回 mutable object。primitive 可以读取,但没有 set/replacement API;整体替换需 remove 后重新 add。
  • 重复 addComponent() 返回既有 exact result,不重新执行 setup,也不改变 cleanup 顺序。
  • removeComponent() 对不存在的 Definition 返回 false;存在时先发布 lookup/Query absence,再按 LIFO 尽量执行全部 onDestroy callbacks。
  • Entity subtree destroy 采用 child-before-parent;单个 Entity 内 Script 先于 Component cleanup,Component 又先于 Engine-owned 标准 Three.js 资源释放。
  • Vue 集成不会自动处理动态 Component result;是否使用 reactive、shallowRef 或 markRaw 由业务决定。

相关 ​

基于 MIT 协议发布(内部使用)