@vworlds/vecs 1.0.15 → 1.0.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (181) hide show
  1. package/README.md +249 -119
  2. package/dist/component.d.ts +52 -76
  3. package/dist/component.js +60 -45
  4. package/dist/component.js.map +1 -1
  5. package/dist/component_meta.d.ts +98 -0
  6. package/dist/component_meta.js +65 -0
  7. package/dist/component_meta.js.map +1 -0
  8. package/dist/dsl.d.ts +46 -34
  9. package/dist/dsl.js +459 -61
  10. package/dist/dsl.js.map +1 -1
  11. package/dist/entity/entity.base.d.ts +57 -0
  12. package/dist/entity/entity.base.js +81 -0
  13. package/dist/entity/entity.base.js.map +1 -0
  14. package/dist/entity/entity.components.d.ts +117 -0
  15. package/dist/entity/entity.components.js +244 -0
  16. package/dist/entity/entity.components.js.map +1 -0
  17. package/dist/entity/entity.d.ts +35 -0
  18. package/dist/entity/entity.identity.d.ts +8 -0
  19. package/dist/entity/entity.identity.js +15 -0
  20. package/dist/entity/entity.identity.js.map +1 -0
  21. package/dist/entity/entity.js +33 -0
  22. package/dist/entity/entity.js.map +1 -0
  23. package/dist/entity/entity.lifecycle.d.ts +12 -0
  24. package/dist/entity/entity.lifecycle.js +111 -0
  25. package/dist/entity/entity.lifecycle.js.map +1 -0
  26. package/dist/entity/entity.queries.d.ts +3 -0
  27. package/dist/entity/entity.queries.js +33 -0
  28. package/dist/entity/entity.queries.js.map +1 -0
  29. package/dist/entity/entity.relationships.d.ts +9 -0
  30. package/dist/entity/entity.relationships.js +74 -0
  31. package/dist/entity/entity.relationships.js.map +1 -0
  32. package/dist/entity/index.d.ts +2 -0
  33. package/dist/entity/index.js +3 -0
  34. package/dist/entity/index.js.map +1 -0
  35. package/dist/filter.d.ts +27 -8
  36. package/dist/filter.js +33 -18
  37. package/dist/filter.js.map +1 -1
  38. package/dist/index.d.ts +13 -5
  39. package/dist/index.js +13 -2
  40. package/dist/index.js.map +1 -1
  41. package/dist/inject.d.ts +80 -0
  42. package/dist/inject.js +270 -0
  43. package/dist/inject.js.map +1 -0
  44. package/dist/module.d.ts +23 -0
  45. package/dist/module.js +17 -0
  46. package/dist/module.js.map +1 -0
  47. package/dist/modules/identity.d.ts +15 -0
  48. package/dist/modules/identity.js +41 -0
  49. package/dist/modules/identity.js.map +1 -0
  50. package/dist/modules/singleton.d.ts +26 -0
  51. package/dist/modules/singleton.js +41 -0
  52. package/dist/modules/singleton.js.map +1 -0
  53. package/dist/package.json +12 -1
  54. package/dist/phase.d.ts +2 -2
  55. package/dist/query/index.d.ts +6 -0
  56. package/dist/query/index.js +5 -0
  57. package/dist/query/index.js.map +1 -0
  58. package/dist/query/query.00.base.d.ts +23 -0
  59. package/dist/query/query.00.base.js +77 -0
  60. package/dist/query/query.00.base.js.map +1 -0
  61. package/dist/query/query.01.reactive.d.ts +7 -0
  62. package/dist/query/query.01.reactive.js +58 -0
  63. package/dist/query/query.01.reactive.js.map +1 -0
  64. package/dist/query/query.02.lifecycle.d.ts +6 -0
  65. package/dist/query/query.02.lifecycle.js +63 -0
  66. package/dist/query/query.02.lifecycle.js.map +1 -0
  67. package/dist/query/query.03.tracking.d.ts +15 -0
  68. package/dist/query/query.03.tracking.js +31 -0
  69. package/dist/query/query.03.tracking.js.map +1 -0
  70. package/dist/query/query.04.callbacks.d.ts +14 -0
  71. package/dist/query/query.04.callbacks.js +65 -0
  72. package/dist/query/query.04.callbacks.js.map +1 -0
  73. package/dist/query/query.05.updates.d.ts +14 -0
  74. package/dist/query/query.05.updates.js +81 -0
  75. package/dist/query/query.05.updates.js.map +1 -0
  76. package/dist/query/query.06.predicate.d.ts +13 -0
  77. package/dist/query/query.06.predicate.js +40 -0
  78. package/dist/query/query.06.predicate.js.map +1 -0
  79. package/dist/query/query.07.groups.d.ts +41 -0
  80. package/dist/query/query.07.groups.js +110 -0
  81. package/dist/query/query.07.groups.js.map +1 -0
  82. package/dist/query/query.d.ts +53 -0
  83. package/dist/query/query.js +138 -0
  84. package/dist/query/query.js.map +1 -0
  85. package/dist/relationship.d.ts +19 -0
  86. package/dist/relationship.js +18 -0
  87. package/dist/relationship.js.map +1 -0
  88. package/dist/system.d.ts +37 -23
  89. package/dist/system.js +80 -64
  90. package/dist/system.js.map +1 -1
  91. package/dist/terms/all_term.d.ts +32 -0
  92. package/dist/terms/all_term.js +41 -0
  93. package/dist/terms/all_term.js.map +1 -0
  94. package/dist/terms/any_term.d.ts +33 -0
  95. package/dist/terms/any_term.js +42 -0
  96. package/dist/terms/any_term.js.map +1 -0
  97. package/dist/terms/build.d.ts +62 -0
  98. package/dist/terms/build.js +382 -0
  99. package/dist/terms/build.js.map +1 -0
  100. package/dist/terms/component_term.d.ts +37 -0
  101. package/dist/terms/component_term.js +49 -0
  102. package/dist/terms/component_term.js.map +1 -0
  103. package/dist/terms/empty_term.d.ts +6 -0
  104. package/dist/terms/empty_term.js +12 -0
  105. package/dist/terms/empty_term.js.map +1 -0
  106. package/dist/terms/index.d.ts +11 -0
  107. package/dist/terms/index.js +12 -0
  108. package/dist/terms/index.js.map +1 -0
  109. package/dist/terms/not_term.d.ts +35 -0
  110. package/dist/terms/not_term.js +47 -0
  111. package/dist/terms/not_term.js.map +1 -0
  112. package/dist/terms/only_term.d.ts +47 -0
  113. package/dist/terms/only_term.js +79 -0
  114. package/dist/terms/only_term.js.map +1 -0
  115. package/dist/terms/predicate_term.d.ts +80 -0
  116. package/dist/terms/predicate_term.js +109 -0
  117. package/dist/terms/predicate_term.js.map +1 -0
  118. package/dist/terms/target_term.d.ts +43 -0
  119. package/dist/terms/target_term.js +87 -0
  120. package/dist/terms/target_term.js.map +1 -0
  121. package/dist/terms/term.d.ts +94 -0
  122. package/dist/terms/term.js +202 -0
  123. package/dist/terms/term.js.map +1 -0
  124. package/dist/terms/world_term.d.ts +68 -0
  125. package/dist/terms/world_term.js +99 -0
  126. package/dist/terms/world_term.js.map +1 -0
  127. package/dist/timer.js +2 -2
  128. package/dist/timer.js.map +1 -1
  129. package/dist/util/array_map.js +12 -0
  130. package/dist/util/array_map.js.map +1 -1
  131. package/dist/util/bitset.js +107 -22
  132. package/dist/util/bitset.js.map +1 -1
  133. package/dist/util/dense_set.d.ts +1 -0
  134. package/dist/util/dense_set.js +90 -0
  135. package/dist/util/dense_set.js.map +1 -0
  136. package/dist/util/id_pool.d.ts +30 -0
  137. package/dist/util/id_pool.js +222 -0
  138. package/dist/util/id_pool.js.map +1 -0
  139. package/dist/world/index.d.ts +3 -0
  140. package/dist/world/index.js +3 -0
  141. package/dist/world/index.js.map +1 -0
  142. package/dist/world/world.base.d.ts +6 -0
  143. package/dist/world/world.base.js +21 -0
  144. package/dist/world/world.base.js.map +1 -0
  145. package/dist/world/world.components.d.ts +67 -0
  146. package/dist/world/world.components.js +93 -0
  147. package/dist/world/world.components.js.map +1 -0
  148. package/dist/world/world.d.ts +29 -0
  149. package/dist/world/world.deferred.d.ts +13 -0
  150. package/dist/world/world.deferred.js +93 -0
  151. package/dist/world/world.deferred.js.map +1 -0
  152. package/dist/world/world.entities.d.ts +18 -0
  153. package/dist/world/world.entities.js +97 -0
  154. package/dist/world/world.entities.js.map +1 -0
  155. package/dist/world/world.js +39 -0
  156. package/dist/world/world.js.map +1 -0
  157. package/dist/world/world.modules.d.ts +12 -0
  158. package/dist/world/world.modules.js +21 -0
  159. package/dist/world/world.modules.js.map +1 -0
  160. package/dist/world/world.pipeline.d.ts +21 -0
  161. package/dist/world/world.pipeline.js +106 -0
  162. package/dist/world/world.pipeline.js.map +1 -0
  163. package/dist/world/world.pools.d.ts +9 -0
  164. package/dist/world/world.pools.js +63 -0
  165. package/dist/world/world.pools.js.map +1 -0
  166. package/dist/world/world.queries.d.ts +18 -0
  167. package/dist/world/world.queries.js +101 -0
  168. package/dist/world/world.queries.js.map +1 -0
  169. package/dist/world/world.storage.d.ts +7 -0
  170. package/dist/world/world.storage.js +26 -0
  171. package/dist/world/world.storage.js.map +1 -0
  172. package/package.json +12 -1
  173. package/dist/entity.d.ts +0 -215
  174. package/dist/entity.js +0 -457
  175. package/dist/entity.js.map +0 -1
  176. package/dist/query.d.ts +0 -251
  177. package/dist/query.js +0 -353
  178. package/dist/query.js.map +0 -1
  179. package/dist/world.d.ts +0 -389
  180. package/dist/world.js +0 -631
  181. package/dist/world.js.map +0 -1
@@ -0,0 +1,81 @@
1
+ import { ComponentMeta } from "../component_meta.js";
2
+ import { ArrayMap } from "../util/array_map.js";
3
+ import { Bitset } from "../util/bitset.js";
4
+ import { Events } from "../util/events.js";
5
+ export class Base {
6
+ constructor(
7
+ /** World that owns this entity. */
8
+ world,
9
+ /** Unique numeric entity id assigned at creation. */
10
+ eid, ownComponentClass) {
11
+ this.world = world;
12
+ this.eid = eid;
13
+ /** @internal Maps component eid to component instance. */
14
+ this._components = new ArrayMap();
15
+ /** @internal Component eids with pending modified delivery. */
16
+ this._dirtyComponentBitmask = new Bitset();
17
+ /** @internal Set of queries this entity currently belongs to. */
18
+ this._queries = new Set();
19
+ /**
20
+ * Bitmask of component type ids currently attached to this entity. Used by
21
+ * the world for fast archetype matching against query predicates.
22
+ */
23
+ this.componentBitmask = new Bitset();
24
+ /**
25
+ * Free-form property bag. Modules can use it to associate arbitrary data with
26
+ * an entity without registering a dedicated component.
27
+ */
28
+ this.properties = new Map();
29
+ /** @internal Set to `true` after the world has fully torn down this entity. */
30
+ this._destroyed = false;
31
+ if (ownComponentClass !== undefined) {
32
+ this._ownMeta = new ComponentMeta(ownComponentClass, eid);
33
+ }
34
+ }
35
+ /**
36
+ * Read-only view of all components currently attached to this entity, keyed
37
+ * by numeric component type id.
38
+ *
39
+ * The mutating methods (`set`, `delete`, `clear`) are not exposed. Use
40
+ * `entity.add`, `entity.attach`, `entity.set`, and `entity.remove` to change
41
+ * the component set.
42
+ *
43
+ * ```ts
44
+ * entity.components.forEach((c) => console.log(c.constructor.name));
45
+ * ```
46
+ */
47
+ get components() {
48
+ return this._components;
49
+ }
50
+ /** `true` when no components are currently attached to this entity. */
51
+ get empty() {
52
+ return this._components.size == 0;
53
+ }
54
+ /**
55
+ * Typed event emitter for entity-level lifecycle events. Currently only the
56
+ * `"destroy"` event is emitted, just before the entity is fully torn down.
57
+ *
58
+ * The emitter is created lazily on first access.
59
+ */
60
+ get events() {
61
+ if (!this._events) {
62
+ this._events = new Events();
63
+ }
64
+ return this._events;
65
+ }
66
+ /** Metadata for using this entity's eid as a component key. Created lazily for plain entities. */
67
+ get ownMeta() {
68
+ return (this._ownMeta ?? (this._ownMeta = new ComponentMeta(Object, this.eid)));
69
+ }
70
+ /** Number of live component instances currently attached for this entity's component key. */
71
+ instanceCount() {
72
+ return this._ownMeta?.usageCount ?? 0;
73
+ }
74
+ /** Returns `"EntityN"` where N is the entity id. */
75
+ toString() {
76
+ return `Entity${this.eid}`;
77
+ }
78
+ }
79
+ /** @internal Empty incoming set used when no entities target this one. */
80
+ Base._emptyIncoming = new Set();
81
+ //# sourceMappingURL=entity.base.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entity.base.js","sourceRoot":"","sources":["../../src/entity/entity.base.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAA8C,MAAM,sBAAsB,CAAC;AAEjG,OAAO,EAAE,QAAQ,EAAyB,MAAM,sBAAsB,CAAC;AACvE,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAE3C,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAM3C,MAAM,OAAO,IAAI;IAmCf;IACE,mCAAmC;IACnB,KAAY;IAC5B,qDAAqD;IACrC,GAAW,EAC3B,iBAAiC;QAHjB,UAAK,GAAL,KAAK,CAAO;QAEZ,QAAG,GAAH,GAAG,CAAQ;QAnC7B,0DAA0D;QAChD,gBAAW,GAAG,IAAI,QAAQ,EAAqB,CAAC;QAC1D,+DAA+D;QAC5C,2BAAsB,GAAG,IAAI,MAAM,EAAE,CAAC;QACzD,iEAAiE;QAC9C,aAAQ,GAAG,IAAI,GAAG,EAAS,CAAC;QAQ/C;;;WAGG;QACa,qBAAgB,GAAG,IAAI,MAAM,EAAE,CAAC;QAEhD;;;WAGG;QACI,eAAU,GAAG,IAAI,GAAG,EAAe,CAAC;QAE3C,+EAA+E;QACxE,eAAU,GAAY,KAAK,CAAC;QAYjC,IAAI,iBAAiB,KAAK,SAAS,EAAE,CAAC;YACpC,IAAI,CAAC,QAAQ,GAAG,IAAI,aAAa,CAAC,iBAAiB,EAAE,GAAG,CAAC,CAAC;QAC5D,CAAC;IACH,CAAC;IAED;;;;;;;;;;;OAWG;IACH,IAAW,UAAU;QACnB,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IAED,uEAAuE;IACvE,IAAW,KAAK;QACd,OAAO,IAAI,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC,CAAC;IACpC,CAAC;IAED;;;;;OAKG;IACH,IAAW,MAAM;QACf,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YAClB,IAAI,CAAC,OAAO,GAAG,IAAI,MAAM,EAAE,CAAC;QAC9B,CAAC;QACD,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED,kGAAkG;IAClG,IAAW,OAAO;QAChB,OAAO,CAAC,IAAI,CAAC,QAAQ,KAAb,IAAI,CAAC,QAAQ,GAAK,IAAI,aAAa,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,EAAC,CAAC;IACjE,CAAC;IAED,6FAA6F;IACtF,aAAa;QAClB,OAAO,IAAI,CAAC,QAAQ,EAAE,UAAU,IAAI,CAAC,CAAC;IACxC,CAAC;IAED,oDAAoD;IAC7C,QAAQ;QACb,OAAO,SAAS,IAAI,CAAC,GAAG,EAAE,CAAC;IAC7B,CAAC;;AAnFD,0EAA0E;AAChD,mBAAc,GAAwB,IAAI,GAAG,EAAE,AAAjC,CAAkC"}
@@ -0,0 +1,117 @@
1
+ import { type ComponentClass, type ComponentInstance, type ComponentRef, type ComponentType } from "../component_meta.js";
2
+ import { Relationships } from "./entity.relationships.js";
3
+ import type { Entity } from "./entity.js";
4
+ export declare class Components extends Relationships {
5
+ /**
6
+ * Attach a component to this entity if it is not already present.
7
+ *
8
+ * Idempotent. Does not fire `onSet` -- use {@link set} when you want to apply
9
+ * data and notify watchers.
10
+ *
11
+ * @param Class - Component class to instantiate.
12
+ * @returns This entity, for chaining.
13
+ */
14
+ add<C extends ComponentClass>(Class: C): this;
15
+ /**
16
+ * Attach a component by numeric type id.
17
+ *
18
+ * @param type - Numeric component type id.
19
+ * @returns This entity, for chaining.
20
+ */
21
+ add(eid: number): this;
22
+ add(entity: Entity): this;
23
+ /**
24
+ * Attach an existing component instance to this entity and store that exact
25
+ * object. If a component of the same registered class already exists, it is
26
+ * replaced rather than assigned into.
27
+ *
28
+ * By default `attach` uses the instance constructor to resolve component
29
+ * metadata. Pass an explicit class when the instance should be stored under
30
+ * a base component key. The constructor must already be registered in this
31
+ * world. The operation fires hooks and query updates like a `set` operation.
32
+ *
33
+ * @param component - Existing component instance to store on the entity.
34
+ * @returns This entity, for chaining.
35
+ */
36
+ attach(component: ComponentInstance): this;
37
+ attach<C extends ComponentInstance>(Class: ComponentType<C>, component: C): this;
38
+ /**
39
+ * Look up a component on this entity as a readonly value.
40
+ *
41
+ * @param typeOrClass - Component class or numeric type id.
42
+ * @returns The component instance, or `undefined` when it is not attached.
43
+ */
44
+ get<C extends ComponentType>(Class: C): Readonly<InstanceType<C>> | undefined;
45
+ /** Look up a component by numeric type id as a readonly value. */
46
+ get(eid: number): Readonly<ComponentInstance> | undefined;
47
+ get(entity: Entity): Readonly<ComponentInstance> | undefined;
48
+ /**
49
+ * Look up a component on this entity for mutation in deferred mode.
50
+ *
51
+ * When the component is present, this marks the component modified before
52
+ * returning the mutable instance. Outside deferred mode, pass a callback so
53
+ * the component can be marked modified after the mutation callback returns.
54
+ *
55
+ * @param typeOrClass - Component class or numeric type id.
56
+ * @returns The component instance, or `undefined` when it is not attached.
57
+ */
58
+ getMut<C extends ComponentType>(Class: C): InstanceType<C> | undefined;
59
+ /** Look up a component, mutate it in `callback`, then mark it modified. */
60
+ getMut<C extends ComponentType>(Class: C, callback: (component: InstanceType<C>) => void): Readonly<InstanceType<C>> | undefined;
61
+ /** Look up a component by numeric type id for mutation. */
62
+ getMut(eid: number): ComponentInstance | undefined;
63
+ /** Look up a component by numeric type id, mutate it in `callback`, then mark it modified. */
64
+ getMut(eid: number, callback: (component: ComponentInstance) => void): Readonly<ComponentInstance> | undefined;
65
+ getMut(entity: Entity): ComponentInstance | undefined;
66
+ getMut(entity: Entity, callback: (component: ComponentInstance) => void): Readonly<ComponentInstance> | undefined;
67
+ /**
68
+ * Mark a component type as having changed, queueing the corresponding `onSet` / `update`
69
+ * notifications.
70
+ *
71
+ * Repeated calls before the world routes the modified command are coalesced via
72
+ * the entity's dirty component bitset.
73
+ *
74
+ * @param typeOrClass - Component class or numeric type id whose data changed.
75
+ * @returns This entity, for chaining.
76
+ */
77
+ modified(ref: ComponentRef): this;
78
+ /**
79
+ * Detach a component from this entity.
80
+ *
81
+ * In deferred mode the removal is queued; `get(C)` continues to return the
82
+ * component until the queue drains. When applied, queries fire `exit`
83
+ * callbacks first and the `onRemove` hook fires last.
84
+ *
85
+ * @param Class - Component class to detach.
86
+ */
87
+ remove<C extends ComponentType>(Class: C): void;
88
+ /**
89
+ * Detach a component by numeric type id.
90
+ *
91
+ * @param type - Numeric component type id.
92
+ */
93
+ remove(eid: number): void;
94
+ remove(entity: Entity): void;
95
+ /**
96
+ * Attach a component (creating it if necessary), copy `props` onto the
97
+ * instance, and fire the `onSet` hook plus any `update` callbacks for the
98
+ * component type.
99
+ *
100
+ * In deferred mode `props` are not applied until the queued `Set` command is
101
+ * routed.
102
+ *
103
+ * @param Class - Component class to instantiate.
104
+ * @param props - Properties to assign onto the component instance.
105
+ * @returns This entity, for chaining.
106
+ */
107
+ set<C extends ComponentClass>(Class: C, props: Partial<InstanceType<C>>): this;
108
+ /**
109
+ * Attach a component by numeric type id and copy `props` onto it.
110
+ *
111
+ * @param type - Numeric component type id.
112
+ * @param props - Properties to assign onto the component instance.
113
+ * @returns This entity, for chaining.
114
+ */
115
+ set(eid: number, props: Partial<ComponentInstance>): this;
116
+ set(entity: Entity, props: Partial<ComponentInstance>): this;
117
+ }
@@ -0,0 +1,244 @@
1
+ import { Relationships } from "./entity.relationships.js";
2
+ export class Components extends Relationships {
3
+ /**
4
+ * @internal Apply an `Attach` command: store the provided component instance,
5
+ * replacing any previous instance for this type. Events are fired as if the
6
+ * caller had performed a `set` operation.
7
+ */
8
+ _attach(meta, component) {
9
+ if (this._destroyed) {
10
+ return;
11
+ }
12
+ const existing = this._components.get(meta.eid);
13
+ const oldTarget = meta.isRelationship
14
+ ? existing?.target
15
+ : undefined;
16
+ this._storeComponent(meta, component, existing === undefined);
17
+ this._updateIncoming(meta, oldTarget, component.target);
18
+ this._notifyComponentSet(meta, component, existing !== undefined);
19
+ }
20
+ /**
21
+ * @internal Look up a component instance by component eid.
22
+ *
23
+ * Faster than {@link get} because no class to type id resolution is needed.
24
+ */
25
+ _get(eid) {
26
+ return this._components.get(eid);
27
+ }
28
+ /**
29
+ * @internal Apply a `Modified` command: fire `onSet` and route modified
30
+ * events to every query that watches the component type.
31
+ */
32
+ _modified(meta) {
33
+ if (this._destroyed) {
34
+ return;
35
+ }
36
+ const c = this._components.get(meta.eid);
37
+ if (!c) {
38
+ return;
39
+ }
40
+ this._notifyComponentSet(meta, c, true);
41
+ }
42
+ /**
43
+ * @internal Apply a `Remove` command: clear the type bit, route exits,
44
+ * detach the component, and fire `onRemove`.
45
+ */
46
+ _remove(meta) {
47
+ if (this._destroyed) {
48
+ return;
49
+ }
50
+ const c = this._components.get(meta.eid);
51
+ if (!c) {
52
+ return;
53
+ }
54
+ if (meta.isRelationship) {
55
+ this._removeIncoming(c.target, meta.eid);
56
+ }
57
+ this._dirtyComponentBitmask.deleteBit(meta.bitPtr);
58
+ this.componentBitmask.deleteBit(meta.bitPtr);
59
+ this.world._notifyComponentRemoved(meta.eid, this);
60
+ this._components.delete(meta.eid);
61
+ this.world._notifyComponentChanged(meta.eid, this);
62
+ meta._decrementUsage();
63
+ const removeHandlers = meta._onRemoveHandlers;
64
+ if (removeHandlers) {
65
+ removeHandlers.forEach((handler) => handler(this, c));
66
+ }
67
+ }
68
+ /**
69
+ * @internal Apply a `Set` command: create the component if missing, assign
70
+ * `props` if provided, fire `onSet`, and route modified events to every
71
+ * query that watches the component type.
72
+ */
73
+ _set(meta, props) {
74
+ if (this._destroyed) {
75
+ return;
76
+ }
77
+ const existing = this._components.get(meta.eid);
78
+ const oldTarget = meta.isRelationship
79
+ ? existing?.target
80
+ : undefined;
81
+ const c = existing ?? this._new(meta, props);
82
+ if (props !== undefined) {
83
+ if (existing) {
84
+ Object.assign(c, props);
85
+ }
86
+ const newTarget = c.target;
87
+ this._updateIncoming(meta, oldTarget, newTarget);
88
+ this._notifyComponentSet(meta, c, existing !== undefined);
89
+ }
90
+ }
91
+ add(ref) {
92
+ const meta = this.world.entity(ref).ownMeta;
93
+ if (this.world.deferred) {
94
+ this.world._enqueue({
95
+ kind: 1 /* CommandKind.Set */,
96
+ entity: this,
97
+ meta,
98
+ props: undefined,
99
+ });
100
+ }
101
+ else {
102
+ this._set(meta, undefined);
103
+ }
104
+ return this;
105
+ }
106
+ attach(classOrComponent, component) {
107
+ const ComponentKey = component === undefined ? classOrComponent.constructor : classOrComponent;
108
+ const instance = component ?? classOrComponent;
109
+ const meta = this.world.entity(ComponentKey).ownMeta;
110
+ if (this.world.deferred) {
111
+ this.world._enqueue({
112
+ kind: 5 /* CommandKind.Attach */,
113
+ entity: this,
114
+ meta,
115
+ component: instance,
116
+ });
117
+ }
118
+ else {
119
+ this._attach(meta, instance);
120
+ }
121
+ return this;
122
+ }
123
+ get(ref) {
124
+ const eid = this.world.entity(ref).eid;
125
+ return this._get(eid);
126
+ }
127
+ getMut(ref, callback) {
128
+ if (callback === undefined && !this.world.deferred) {
129
+ throw new Error("Entity.getMut without a callback is only allowed in deferred mode");
130
+ }
131
+ const meta = this.world.entity(ref).ownMeta;
132
+ if (meta.isRelationship) {
133
+ throw new Error("Entity.getMut cannot mutate Relationship components; retarget with set");
134
+ }
135
+ const component = this._get(meta.eid);
136
+ if (!component) {
137
+ return undefined;
138
+ }
139
+ callback?.(component);
140
+ this._markModified(meta);
141
+ return component;
142
+ }
143
+ /**
144
+ * Mark a component type as having changed, queueing the corresponding `onSet` / `update`
145
+ * notifications.
146
+ *
147
+ * Repeated calls before the world routes the modified command are coalesced via
148
+ * the entity's dirty component bitset.
149
+ *
150
+ * @param typeOrClass - Component class or numeric type id whose data changed.
151
+ * @returns This entity, for chaining.
152
+ */
153
+ modified(ref) {
154
+ const meta = this.world.entity(ref).ownMeta;
155
+ return this._markModified(meta);
156
+ }
157
+ /** @internal Mark a component changed, coalescing duplicate pending notifications. */
158
+ _markModified(meta) {
159
+ if (this._dirtyComponentBitmask.hasBit(meta.bitPtr)) {
160
+ return this;
161
+ }
162
+ this._dirtyComponentBitmask.addBit(meta.bitPtr);
163
+ if (this.world.deferred) {
164
+ this.world._enqueue({ kind: 2 /* CommandKind.Modified */, entity: this, meta });
165
+ }
166
+ else {
167
+ this._modified(meta);
168
+ }
169
+ return this;
170
+ }
171
+ remove(ref) {
172
+ const meta = this.world.entity(ref).ownMeta;
173
+ if (this.world.deferred) {
174
+ this.world._enqueue({ kind: 3 /* CommandKind.Remove */, entity: this, meta });
175
+ }
176
+ else {
177
+ this._remove(meta);
178
+ }
179
+ }
180
+ set(ref, props) {
181
+ const meta = this.world.entity(ref).ownMeta;
182
+ if (this.world.deferred) {
183
+ this.world._enqueue({
184
+ kind: 1 /* CommandKind.Set */,
185
+ entity: this,
186
+ meta,
187
+ props,
188
+ });
189
+ }
190
+ else {
191
+ this._set(meta, props);
192
+ }
193
+ return this;
194
+ }
195
+ /**
196
+ * @internal
197
+ *
198
+ * Construct a fresh component of `type`, apply `props`, store it on this
199
+ * entity, fire the `onAdd` hook, and route query updates.
200
+ *
201
+ * If the component type belongs to an exclusivity group, any conflicting
202
+ * component already on this entity is removed first.
203
+ */
204
+ _new(meta, props) {
205
+ const c = new meta.Class();
206
+ if (props !== undefined) {
207
+ Object.assign(c, props);
208
+ }
209
+ this._storeComponent(meta, c, true);
210
+ return c;
211
+ }
212
+ /** @internal Perform the shared set-side hook and query update routing. */
213
+ _notifyComponentSet(meta, instance, isUpdate) {
214
+ meta._onSetHandlers?.forEach((handler) => handler(this, instance));
215
+ this._dirtyComponentBitmask.deleteBit(meta.bitPtr);
216
+ if (isUpdate) {
217
+ this.world._notifyComponentChanged(meta.eid, this);
218
+ this._queries.forEach((q) => q._notifyModified(this, meta, instance));
219
+ }
220
+ }
221
+ /** @internal Store a component instance and perform the shared add-side bookkeeping. */
222
+ _storeComponent(meta, instance, isAdd) {
223
+ if (meta._exclusive) {
224
+ for (const exclusiveMeta of meta._exclusive) {
225
+ if (this._components.has(exclusiveMeta.eid)) {
226
+ this._remove(exclusiveMeta);
227
+ }
228
+ }
229
+ }
230
+ const existing = this._components.has(meta.eid);
231
+ this._components.set(meta.eid, instance);
232
+ this.componentBitmask.addBit(meta.bitPtr);
233
+ if (!existing) {
234
+ meta._incrementUsage();
235
+ }
236
+ if (isAdd && !existing) {
237
+ meta._onAddHandlers?.forEach((handler) => handler(this, instance));
238
+ }
239
+ if (!existing) {
240
+ this.world._notifyComponentAdded(meta.eid, this);
241
+ }
242
+ }
243
+ }
244
+ //# sourceMappingURL=entity.components.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entity.components.js","sourceRoot":"","sources":["../../src/entity/entity.components.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ import { type ComponentType } from "../component_meta.js";
2
+ import { type World } from "../world/index.js";
3
+ import { IdentityEntity } from "./entity.identity.js";
4
+ export type EntityClass<T extends Entity = Entity> = new (world: World, eid: number, ownComponentClass?: ComponentType) => T;
5
+ /**
6
+ * A game object: a unique numeric id with an arbitrary set of
7
+ * {@link ComponentInstance | components} attached.
8
+ *
9
+ * Never instantiate `Entity` directly. Use {@link World.entity} for an
10
+ * auto-assigned id, or {@link World.getOrCreateEntity} when the id comes from
11
+ * an external authority such as a game server:
12
+ *
13
+ * ```ts
14
+ * const e = world.entity();
15
+ * e.set(Position, { x: 100 });
16
+ * ```
17
+ *
18
+ * ## Deferred semantics
19
+ *
20
+ * Inside a system body or `forEach` iteration the world is in **deferred
21
+ * mode**: `add` / `attach` / `set` / `modified` / `remove` / `destroy` only
22
+ * enqueue commands. The data layer (the components map and
23
+ * `componentBitmask`) is mutated when the world drains its queue. Concretely,
24
+ * while deferred:
25
+ *
26
+ * - `entity.get(C)` / `entity.getMut(C)` returns `undefined` after `entity.add(C)` (no instance yet).
27
+ * - `entity.get(C)` / `entity.getMut(C)` returns `undefined` after `entity.attach(instance)` if C was absent.
28
+ * - `entity.get(C)` / `entity.getMut(C)` returns the previous value after `entity.set(C, props)`.
29
+ * - `entity.get(C)` / `entity.getMut(C)` still returns the component after `entity.remove(C)`.
30
+ *
31
+ * Outside deferred mode the same calls execute inline and mutations are
32
+ * visible immediately.
33
+ */
34
+ export declare class Entity extends IdentityEntity {
35
+ }
@@ -0,0 +1,8 @@
1
+ import { Lifecycle } from "./entity.lifecycle.js";
2
+ export declare class Identity {
3
+ name: string;
4
+ }
5
+ export declare class IdentityEntity extends Lifecycle {
6
+ get name(): string | undefined;
7
+ set name(n: string);
8
+ }
@@ -0,0 +1,15 @@
1
+ import { Lifecycle } from "./entity.lifecycle.js";
2
+ export class Identity {
3
+ constructor() {
4
+ this.name = "";
5
+ }
6
+ }
7
+ export class IdentityEntity extends Lifecycle {
8
+ get name() {
9
+ return this.get(Identity)?.name;
10
+ }
11
+ set name(n) {
12
+ this.set(Identity, { name: n });
13
+ }
14
+ }
15
+ //# sourceMappingURL=entity.identity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entity.identity.js","sourceRoot":"","sources":["../../src/entity/entity.identity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAElD,MAAM,OAAO,QAAQ;IAArB;QACS,SAAI,GAAG,EAAE,CAAC;IACnB,CAAC;CAAA;AAED,MAAM,OAAO,cAAe,SAAQ,SAAS;IAC3C,IAAW,IAAI;QACb,OAAO,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC;IAClC,CAAC;IAED,IAAW,IAAI,CAAC,CAAS;QACvB,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;IAClC,CAAC;CACF"}
@@ -0,0 +1,33 @@
1
+ import { IdentityEntity } from "./entity.identity.js";
2
+ /**
3
+ * A game object: a unique numeric id with an arbitrary set of
4
+ * {@link ComponentInstance | components} attached.
5
+ *
6
+ * Never instantiate `Entity` directly. Use {@link World.entity} for an
7
+ * auto-assigned id, or {@link World.getOrCreateEntity} when the id comes from
8
+ * an external authority such as a game server:
9
+ *
10
+ * ```ts
11
+ * const e = world.entity();
12
+ * e.set(Position, { x: 100 });
13
+ * ```
14
+ *
15
+ * ## Deferred semantics
16
+ *
17
+ * Inside a system body or `forEach` iteration the world is in **deferred
18
+ * mode**: `add` / `attach` / `set` / `modified` / `remove` / `destroy` only
19
+ * enqueue commands. The data layer (the components map and
20
+ * `componentBitmask`) is mutated when the world drains its queue. Concretely,
21
+ * while deferred:
22
+ *
23
+ * - `entity.get(C)` / `entity.getMut(C)` returns `undefined` after `entity.add(C)` (no instance yet).
24
+ * - `entity.get(C)` / `entity.getMut(C)` returns `undefined` after `entity.attach(instance)` if C was absent.
25
+ * - `entity.get(C)` / `entity.getMut(C)` returns the previous value after `entity.set(C, props)`.
26
+ * - `entity.get(C)` / `entity.getMut(C)` still returns the component after `entity.remove(C)`.
27
+ *
28
+ * Outside deferred mode the same calls execute inline and mutations are
29
+ * visible immediately.
30
+ */
31
+ export class Entity extends IdentityEntity {
32
+ }
33
+ //# sourceMappingURL=entity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entity.js","sourceRoot":"","sources":["../../src/entity/entity.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAQtD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,OAAO,MAAO,SAAQ,cAAc;CAAG"}
@@ -0,0 +1,12 @@
1
+ import { Components } from "./entity.components.js";
2
+ export declare class Lifecycle extends Components {
3
+ /**
4
+ * Destroy this entity.
5
+ *
6
+ * Each component fires its `onRemove` hook, the `"destroy"` event is emitted
7
+ * just before teardown, and the entity is unregistered from the world.
8
+ * After destruction the entity must not be used.
9
+ */
10
+ destroy(): void;
11
+ private _applyOnDelete;
12
+ }