@vworlds/vecs 1.0.3 → 1.0.5

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.
package/README.md CHANGED
@@ -14,18 +14,21 @@ yarn add @vworlds/vecs
14
14
 
15
15
  | Concept | What it is |
16
16
  |---|---|
17
- | **World** | Central container. Owns all entities, runs all systems. |
17
+ | **World** | Central container. Owns all entities, runs all systems and queries. |
18
18
  | **Component** | A plain data class. Extend `Component` and attach instances to entities. |
19
19
  | **Entity** | An integer id with a set of components. Create via the world. |
20
- | **System** | Reactive logic. Declare which components you need; get called when things change. |
20
+ | **Query** | A reactive, always-updated set of entities that match a predicate. |
21
+ | **System** | A `Query` with per-tick runtime logic (phases, `update`, `each`, `run`). |
22
+ | **Filter** | A non-reactive, one-shot scan: walks all world entities on each `forEach` call. |
23
+ | **Exclusive components** | A group of components where at most one may be present on any entity at a time. |
21
24
 
22
25
  ### Lifecycle in brief
23
26
 
24
27
  ```
25
- registerComponent() × N → system() × N → start() → progress() every frame
28
+ registerComponent() × N → system() / query() × N → start() → progress() every frame
26
29
  ```
27
30
 
28
- After `start()`, no new components or systems can be registered.
31
+ After `start()`, component registration is disabled. Systems and queries can still be created — standalone queries backfill existing matched entities immediately.
29
32
 
30
33
  ---
31
34
 
@@ -112,17 +115,12 @@ world.start(); // freeze registration, sort systems into phases
112
115
  // ─── Create entities ───────────────────────────────────────────────────────
113
116
 
114
117
  const bullet = world.createEntity();
115
- const pos = bullet.add(Position);
116
- pos.x = 0;
117
- pos.y = 0;
118
+ bullet.set(Position, { x: 0, y: 0 });
118
119
 
119
- const vel = bullet.add(Velocity);
120
- vel.vx = 5;
121
- vel.vy = 0;
120
+ const vel = bullet.set(Velocity, { vx: 5, vy: 0 });
122
121
  vel.modified(); // first update: notify Move system
123
122
 
124
- const hp = bullet.add(Health);
125
- hp.hp = 3;
123
+ const hp = bullet.set(Health, { hp: 3 });
126
124
  hp.modified();
127
125
 
128
126
  // ─── Game loop ─────────────────────────────────────────────────────────────
@@ -164,6 +162,23 @@ world.registerComponentType("Position", 1);
164
162
 
165
163
  After `world.start()` any further call to `registerComponent` throws.
166
164
 
165
+ #### Exclusive components
166
+
167
+ Declare a group of components that cannot coexist on the same entity. Adding a member of the group automatically removes any other member that was already present.
168
+
169
+ ```ts
170
+ world.setExclusiveComponents(Walking, Running, Idle);
171
+
172
+ const e = world.createEntity();
173
+ e.add(Walking);
174
+ e.add(Running); // Walking is automatically removed first
175
+ // e.get(Walking) === undefined, e.get(Running) is defined
176
+ ```
177
+
178
+ Each call to `setExclusiveComponents` defines one independent group. Components not in the group are unaffected. A component may belong to at most one exclusivity group (calling `setExclusiveComponents` a second time with the same class overwrites its group).
179
+
180
+ `setExclusiveComponents` may be called before or after `world.start()`.
181
+
167
182
  #### Entity management
168
183
 
169
184
  ```ts
@@ -197,9 +212,54 @@ world.system("MySystem")
197
212
  .update(...)
198
213
  .exit(...);
199
214
 
200
- world.start(); // must be called once, after all systems are set up
215
+ world.start(); // distributes systems to phases, freezes component registration
216
+ ```
217
+
218
+ #### Queries
219
+
220
+ A standalone `Query` is a reactive entity set without a phase or per-tick callbacks. Use it when you need the matched set kept up-to-date automatically — for example to enumerate scene nodes or find the nearest enemy.
221
+
222
+ ```ts
223
+ const enemies = world.query("Enemies")
224
+ .requires(Enemy, Health)
225
+ .enter((e) => console.log("enemy spawned", e.eid))
226
+ .exit((e) => console.log("enemy died", e.eid));
227
+
228
+ world.start();
229
+ // enemies.entities is kept up-to-date automatically
230
+
231
+ // Can also be created after start(); existing matched entities are backfilled:
232
+ const lateQuery = world.query("Walls").requires(Wall);
233
+ // lateQuery.entities immediately contains all current Wall entities
201
234
  ```
202
235
 
236
+ #### Filters
237
+
238
+ A `Filter` is a non-reactive, one-shot scan. It holds no tracked entity set — each `forEach` call walks all world entities at that moment. Use it for ad-hoc lookups that don't need to stay live.
239
+
240
+ ```ts
241
+ // Entity only:
242
+ world.filter([Position]).forEach((e) => console.log(e.eid));
243
+
244
+ // With component injection:
245
+ world.filter([Position, Velocity])
246
+ .forEach([Position, Velocity], (e, [pos, vel]) => {
247
+ pos.x += vel.vx;
248
+ });
249
+
250
+ // Full DSL, with auto-deduced required components:
251
+ world.filter({ AND: [{ HAS: Position }, { HAS: Velocity }] })
252
+ .forEach([Position, Velocity], (e, [pos, vel]) => {
253
+ pos.x += vel.vx; // pos and vel are non-null — deduced from AND of HAS
254
+ });
255
+
256
+ // Manual type hint for queries the extractor can't see through:
257
+ world.filter({ OR: [Position, Velocity] }, [Position])
258
+ .forEach([Position], (e, [pos]) => pos.x);
259
+ ```
260
+
261
+ Unlike `Query`, a `Filter` requires no name, no `world.start()`, and no `destroy()` — create it anywhere and discard it freely.
262
+
203
263
  #### Phases
204
264
 
205
265
  ```ts
@@ -275,6 +335,7 @@ const e = world.createEntity();
275
335
  | `eid` | Unique numeric entity id. |
276
336
  | `world` | The `World` that owns this entity. |
277
337
  | `add(Class)` | Attach a component; returns the typed instance. Idempotent. |
338
+ | `set(Class, props)` | Like `add`, but also assigns the given partial properties onto the instance. Returns the typed instance. |
278
339
  | `get(Class)` | Return the component instance, or `undefined` if not present. |
279
340
  | `remove(Class)` | Detach a component (triggers `onRemove` hooks and `exit` callbacks). |
280
341
  | `destroy()` | Remove all components and unregister the entity. Recurses to children. |
@@ -436,7 +497,9 @@ Iterating `system.entities` after a phase run yields entities in the sorted orde
436
497
 
437
498
  #### `.track()`
438
499
 
439
- Enable entity tracking without an `each` callback — matched entities are exposed via `system.entities` as they enter and leave. `each` and `sort` imply `track` automatically; call this directly only when you need the set without a per-tick callback.
500
+ Enable entity tracking without an `each` callback — matched entities are exposed via `system.entities` (or `query.entities`) as they enter and leave. `each` and `sort` imply `track` automatically; call this directly only when you need the tracked set without a per-tick callback.
501
+
502
+ When called after `world.start()`, `track()` immediately backfills existing entities that satisfy the query predicate.
440
503
 
441
504
  #### `.run(callback)`
442
505
 
@@ -450,6 +513,82 @@ Called every tick when the system's phase runs, regardless of entity state. Use
450
513
 
451
514
  ---
452
515
 
516
+ ### Query
517
+
518
+ A standalone query is created via `world.query(name)` and configured through the same fluent builder API as `System` (`requires`, `query`, `enter`, `exit`, `sort`, `track`, `forEach`, `entities`). It has no phase and no per-tick callbacks.
519
+
520
+ ```ts
521
+ const projectiles = world.query("Projectiles")
522
+ .requires(Position, Velocity)
523
+ .sort([Position], ([a], [b]) => a.z - b.z)
524
+ .enter([Position], (e, [pos]) => { pos.x = spawnX; });
525
+
526
+ world.start();
527
+
528
+ // Anywhere in game code:
529
+ projectiles.forEach((e) => { /* ... */ });
530
+ console.log(projectiles.entities.size, "active projectiles");
531
+ ```
532
+
533
+ | Method | Description |
534
+ |---|---|
535
+ | `.requires(...components)` | Set the membership predicate and start tracking. |
536
+ | `.query(expr)` | Set the membership predicate using the {@link SystemQuery} DSL. |
537
+ | `.enter(callback)` / `.enter(inject, callback)` | Fires when an entity joins the query. |
538
+ | `.exit(callback)` / `.exit(inject, callback)` | Fires when an entity leaves the query. |
539
+ | `.sort(components, compare)` | Store matched entities in sorted order. |
540
+ | `.track()` | Enable tracking (implied by `sort`; backfills when called after `start`). |
541
+ | `.belongs(e)` | Returns `true` if the entity satisfies the predicate. |
542
+ | `.forEach(callback)` | Iterate all currently tracked entities (entity only). |
543
+ | `.forEach(components, callback)` | Iterate with component injection — same signature as `Filter.forEach`. |
544
+ | `.entities` | `ReadonlySet<Entity>` of all currently tracked entities. |
545
+ | `.destroy()` | Remove the query from the world and all entities. See below. |
546
+
547
+ #### `.destroy()`
548
+
549
+ Permanently removes a standalone query from the world. All entity references are silently purged (no exit callbacks fire), the tracked entity set is cleared, and the query's `world` reference is set to `undefined`. After this call, any use of the query object is **undefined behavior**.
550
+
551
+ ```ts
552
+ const q = world.query("Temporary").requires(Position);
553
+ // ... use q.entities ...
554
+ q.destroy(); // unregisters from world and all entities
555
+ ```
556
+
557
+ `System` does **not** support `destroy()` — calling it throws. Systems are owned by the world for the lifetime of the session. Use a standalone `Query` when you need a temporary reactive set.
558
+
559
+ Both `System` and `Query` share the same query DSL, enter/exit callbacks, sort, and `entities` set — `System` extends `Query` and layers phase execution on top.
560
+
561
+ ---
562
+
563
+ ### Filter
564
+
565
+ A `Filter` is created via `world.filter(dsl)` and provides a non-reactive `forEach`. It accepts the same [`QueryDSL`](#-requirescomponents-and-queryq) expressions as systems and queries.
566
+
567
+ ```ts
568
+ const f = world.filter([Position, Velocity]);
569
+ ```
570
+
571
+ | Method | Description |
572
+ |---|---|
573
+ | `.forEach(callback)` | Walk all world entities; invoke callback for each matching one. |
574
+ | `.forEach(components, callback)` | Same, with component injection and non-null types for required components. |
575
+
576
+ **Type inference** works the same way as for `requires()` on systems/queries: component classes extractable from the DSL (`HAS`, `HAS_ONLY`, plain arrays, and `AND` of those) are non-nullable in the callback tuple. Pass a `_guaranteed` second argument to `world.filter()` as a manual override when inference can't reach:
577
+
578
+ ```ts
579
+ // Auto-deduced — both non-null:
580
+ world.filter([Position, Velocity])
581
+ .forEach([Position, Velocity], (e, [pos, vel]) => { ... });
582
+
583
+ // Manual hint for OR / NOT / PARENT / custom function:
584
+ world.filter({ OR: [Position, Velocity] }, [Position])
585
+ .forEach([Position], (e, [pos]) => pos.x);
586
+ ```
587
+
588
+ A `Filter` holds no tracked set, makes no registration calls, and needs no `destroy()`.
589
+
590
+ ---
591
+
453
592
  ## Build & Test
454
593
 
455
594
  ```
@@ -68,6 +68,11 @@ export declare class ComponentMeta implements Hook<Component> {
68
68
  private onAddHandler;
69
69
  private onRemoveHandler;
70
70
  private onSetHandler;
71
+ /**
72
+ * Type ids of components that cannot coexist with this one on the same entity.
73
+ * Set via {@link World.setExclusiveComponents}. `undefined` means no restrictions.
74
+ */
75
+ exclusive: number[] | undefined;
71
76
  constructor(Class: typeof Component, type: number, componentName: string);
72
77
  /** @inheritdoc */
73
78
  onAdd(handler: (c: Component) => void): ComponentMeta;
package/dist/component.js CHANGED
@@ -11,6 +11,11 @@ import { BitPtr, Bitset } from "./util/bitset.js";
11
11
  */
12
12
  export class ComponentMeta {
13
13
  constructor(Class, type, componentName) {
14
+ /**
15
+ * Type ids of components that cannot coexist with this one on the same entity.
16
+ * Set via {@link World.setExclusiveComponents}. `undefined` means no restrictions.
17
+ */
18
+ this.exclusive = undefined;
14
19
  this.Class = Class;
15
20
  this.type = type;
16
21
  this.componentName = componentName;
@@ -1 +1 @@
1
- {"version":3,"file":"component.js","sourceRoot":"","sources":["../src/component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAoDlD;;;;;;;;;GASG;AACH,MAAM,OAAO,aAAa;IAaxB,YAAY,KAAuB,EAAE,IAAY,EAAE,aAAqB;QACtE,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;QACnC,IAAI,CAAC,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC;IAED,kBAAkB;IACX,KAAK,CAAC,OAA+B;QAC1C,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC;QAC5B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,kBAAkB;IACX,QAAQ,CAAC,OAA+B;QAC7C,IAAI,CAAC,eAAe,GAAG,OAAO,CAAC;QAC/B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,kBAAkB;IACX,KAAK,CAAC,OAA+B;QAC1C,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC;QAC5B,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AAQD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,OAAO,SAAS;IAGpB;IACE,4CAA4C;IAC5B,MAAc;IAC9B,0DAA0D;IAC1C,IAAmB;QAFnB,WAAM,GAAN,MAAM,CAAQ;QAEd,SAAI,GAAJ,IAAI,CAAe;QAN7B,UAAK,GAAY,KAAK,CAAC;IAO5B,CAAC;IAEJ,wDAAwD;IACxD,IAAW,IAAI;QACb,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;IACxB,CAAC;IAED,mEAAmE;IACnE,IAAW,MAAM;QACf,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;IAC1B,CAAC;IAED;;;;;;OAMG;IACI,QAAQ;QACb,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,sBAAsB,CAAC,IAAI,CAAC,CAAC;IACjD,CAAC;IAED,kEAAkE;IAC3D,QAAQ;QACb,OAAO,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC;IACjC,CAAC;CACF;AAED;;;;;GAKG;AACH,MAAM,UAAU,yBAAyB,CACvC,OAA4B,EAC5B,KAAY;IAEZ,MAAM,OAAO,GAAG,IAAI,MAAM,EAAE,CAAC;IAC7B,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE;QACpB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;IACH,OAAO,OAAO,CAAC;AACjB,CAAC"}
1
+ {"version":3,"file":"component.js","sourceRoot":"","sources":["../src/component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAoDlD;;;;;;;;;GASG;AACH,MAAM,OAAO,aAAa;IAkBxB,YAAY,KAAuB,EAAE,IAAY,EAAE,aAAqB;QANxE;;;WAGG;QACI,cAAS,GAAyB,SAAS,CAAC;QAGjD,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;QACnC,IAAI,CAAC,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC;IAED,kBAAkB;IACX,KAAK,CAAC,OAA+B;QAC1C,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC;QAC5B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,kBAAkB;IACX,QAAQ,CAAC,OAA+B;QAC7C,IAAI,CAAC,eAAe,GAAG,OAAO,CAAC;QAC/B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,kBAAkB;IACX,KAAK,CAAC,OAA+B;QAC1C,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC;QAC5B,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AAQD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,OAAO,SAAS;IAGpB;IACE,4CAA4C;IAC5B,MAAc;IAC9B,0DAA0D;IAC1C,IAAmB;QAFnB,WAAM,GAAN,MAAM,CAAQ;QAEd,SAAI,GAAJ,IAAI,CAAe;QAN7B,UAAK,GAAY,KAAK,CAAC;IAO5B,CAAC;IAEJ,wDAAwD;IACxD,IAAW,IAAI;QACb,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;IACxB,CAAC;IAED,mEAAmE;IACnE,IAAW,MAAM;QACf,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;IAC1B,CAAC;IAED;;;;;;OAMG;IACI,QAAQ;QACb,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,sBAAsB,CAAC,IAAI,CAAC,CAAC;IACjD,CAAC;IAED,kEAAkE;IAC3D,QAAQ;QACb,OAAO,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC;IACjC,CAAC;CACF;AAED;;;;;GAKG;AACH,MAAM,UAAU,yBAAyB,CACvC,OAA4B,EAC5B,KAAY;IAEZ,MAAM,OAAO,GAAG,IAAI,MAAM,EAAE,CAAC;IAC7B,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE;QACpB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;IACH,OAAO,OAAO,CAAC;AACjB,CAAC"}
package/dist/dsl.d.ts ADDED
@@ -0,0 +1,71 @@
1
+ import { Component, ComponentClassArray, ComponentClassOrType } from "./component.js";
2
+ import type { Entity } from "./entity.js";
3
+ import type { World } from "./world.js";
4
+ /** A function that tests whether a given entity belongs to a query. */
5
+ export type EntityTestFunc = (e: Entity) => boolean;
6
+ /**
7
+ * A composable query expression used to declare which entities a
8
+ * {@link Query} or {@link System} should track.
9
+ *
10
+ * Queries can be nested arbitrarily:
11
+ *
12
+ * ```ts
13
+ * // Entities that have Position AND (Sprite OR Container):
14
+ * world.system("render").query({
15
+ * AND: [Position, { OR: [Sprite, Container] }]
16
+ * });
17
+ *
18
+ * // Entities that have a parent with Player AND Container:
19
+ * world.system("attach").query({
20
+ * PARENT: { AND: [Player, Container] }
21
+ * });
22
+ * ```
23
+ *
24
+ * Short forms:
25
+ * - A single class or type id is equivalent to `{ HAS: [C] }`.
26
+ * - An array `[A, B]` is equivalent to `{ HAS: [A, B] }`.
27
+ * - Pass an {@link EntityTestFunc} directly for fully custom membership logic.
28
+ */
29
+ export type QueryDSL = ComponentClassArray | ComponentClassOrType | EntityTestFunc | {
30
+ HAS: ComponentClassArray | ComponentClassOrType;
31
+ } | {
32
+ HAS_ONLY: ComponentClassArray | ComponentClassOrType;
33
+ } | {
34
+ AND: readonly QueryDSL[];
35
+ } | {
36
+ OR: readonly QueryDSL[];
37
+ } | {
38
+ NOT: QueryDSL;
39
+ } | {
40
+ PARENT: QueryDSL;
41
+ };
42
+ export declare function HAS(world: World, ...components: ComponentClassArray): EntityTestFunc;
43
+ /**
44
+ * Resolves component nullability based on what was declared in `requires` (or
45
+ * the `_guaranteed` hint). Components in `R` are non-nullable; others are
46
+ * `InstanceType<C> | undefined`.
47
+ */
48
+ export type MaybeRequired<C, R extends (typeof Component)[]> = C extends typeof Component ? C extends R[number] ? InstanceType<C> : InstanceType<C> | undefined : never;
49
+ /**
50
+ * Statically extracts the component classes that are **guaranteed present** on
51
+ * every entity matched by a {@link QueryDSL} expression.
52
+ *
53
+ * Rules:
54
+ * - Plain class `C` → `[C]`
55
+ * - Plain array `[A, B]` → `[A, B]`
56
+ * - `{HAS: ...}` / `{HAS_ONLY: ...}` → recurse into the payload
57
+ * - `{AND: [q1, q2, ...]}` → concatenation of each branch's extraction
58
+ * - `{OR: ...}` / `{NOT: ...}` / `{PARENT: ...}` → `[]` (no guarantee)
59
+ * - `EntityTestFunc` / numeric type id → `[]` (opaque)
60
+ */
61
+ export type ExtractRequired<Q> = Q extends typeof Component ? [Q] : Q extends readonly (typeof Component)[] ? Q : Q extends {
62
+ HAS: infer H;
63
+ } ? ExtractRequired<H> : Q extends {
64
+ HAS_ONLY: infer H;
65
+ } ? ExtractRequired<H> : Q extends {
66
+ AND: infer A extends readonly QueryDSL[];
67
+ } ? ExtractAndChain<A> : [];
68
+ type ExtractAndChain<A extends readonly QueryDSL[]> = A extends readonly [infer First, ...infer Rest extends readonly QueryDSL[]] ? [...ExtractRequired<First>, ...ExtractAndChain<Rest>] : [];
69
+ /** Convert a {@link QueryDSL} expression into a runtime entity-test predicate. */
70
+ export declare function buildEntityTest(world: World, q: QueryDSL): EntityTestFunc;
71
+ export {};
package/dist/dsl.js ADDED
@@ -0,0 +1,58 @@
1
+ import { Component, calculateComponentBitmask, } from "./component.js";
2
+ export function HAS(world, ...components) {
3
+ const testBitmask = calculateComponentBitmask(components, world);
4
+ return (e) => e.componentBitmask.hasBitset(testBitmask);
5
+ }
6
+ function HAS_ONLY(world, ...components) {
7
+ const testBitmask = calculateComponentBitmask(components, world);
8
+ return (e) => e.componentBitmask.equal(testBitmask);
9
+ }
10
+ function NOT(func) {
11
+ return (e) => !func(e);
12
+ }
13
+ function AND(...funcs) {
14
+ return (e) => funcs.every((f) => f(e));
15
+ }
16
+ function OR(...funcs) {
17
+ return (e) => funcs.some((f) => f(e));
18
+ }
19
+ function PARENT(func) {
20
+ return (e) => (e.parent && func(e.parent)) || false;
21
+ }
22
+ /** Convert a {@link QueryDSL} expression into a runtime entity-test predicate. */
23
+ export function buildEntityTest(world, q) {
24
+ if (typeof q === "number" ||
25
+ (typeof q === "function" && q.prototype instanceof Component)) {
26
+ return HAS(world, q);
27
+ }
28
+ else if (typeof q === "function") {
29
+ return q;
30
+ }
31
+ if (q instanceof Array) {
32
+ return HAS(world, ...q);
33
+ }
34
+ if ("HAS" in q) {
35
+ return buildEntityTest(world, q.HAS);
36
+ }
37
+ if ("HAS_ONLY" in q) {
38
+ const v = q.HAS_ONLY;
39
+ if (v instanceof Array) {
40
+ return HAS_ONLY(world, ...v);
41
+ }
42
+ return HAS_ONLY(world, v);
43
+ }
44
+ if ("AND" in q) {
45
+ return AND(...q.AND.map((sq) => buildEntityTest(world, sq)));
46
+ }
47
+ if ("OR" in q) {
48
+ return OR(...q.OR.map((sq) => buildEntityTest(world, sq)));
49
+ }
50
+ if ("NOT" in q) {
51
+ return NOT(buildEntityTest(world, q.NOT));
52
+ }
53
+ if ("PARENT" in q) {
54
+ return PARENT(buildEntityTest(world, q.PARENT));
55
+ }
56
+ throw "Unrecognized query term";
57
+ }
58
+ //# sourceMappingURL=dsl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dsl.js","sourceRoot":"","sources":["../src/dsl.ts"],"names":[],"mappings":"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"}
package/dist/entity.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { Component } from "./component.js";
2
2
  import type { World } from "./world.js";
3
- import { type System } from "./system.js";
3
+ import { type Query } from "./query.js";
4
4
  import { Events } from "./util/events.js";
5
5
  import { Bitset } from "./util/bitset.js";
6
6
  type EntityEvents = Events<{
@@ -33,12 +33,12 @@ export declare class Entity {
33
33
  private deletedComponents;
34
34
  /**
35
35
  * Bitmask representing the set of component types currently attached to this
36
- * entity. Used by the world to efficiently match entities against system
37
- * queries.
36
+ * entity. Used by the world to efficiently match entities against query
37
+ * predicates.
38
38
  */
39
39
  readonly componentBitmask: Bitset;
40
- private readonly systems;
41
- private readonly newSystems;
40
+ private readonly queries;
41
+ private readonly newQueries;
42
42
  /**
43
43
  * A free-form property bag that modules can use to associate arbitrary data
44
44
  * with an entity without registering a component.
@@ -63,6 +63,7 @@ export declare class Entity {
63
63
  * both will keep the parent–child links consistent.
64
64
  */
65
65
  get children(): Set<Entity>;
66
+ private getComponentInstance;
66
67
  /**
67
68
  * Add a component of type `Class` to this entity and return the instance.
68
69
  *
@@ -86,6 +87,22 @@ export declare class Entity {
86
87
  * @param markAsModified - Whether to queue an update notification.
87
88
  */
88
89
  add(type: number, markAsModified?: boolean): Component;
90
+ /**
91
+ * Add a component of type `Class` (if not already present) and assign the
92
+ * provided properties onto the instance, then return it.
93
+ *
94
+ * @param Class - The component class to instantiate.
95
+ * @param props - Optional properties to assign onto the component instance.
96
+ * @returns The new (or existing) component instance with the given properties applied.
97
+ */
98
+ set<C extends typeof Component>(Class: C, props: Partial<InstanceType<C>>): InstanceType<C>;
99
+ /**
100
+ * Add a component by its numeric type id and assign the provided properties.
101
+ *
102
+ * @param type - Numeric component type id.
103
+ * @param props - Optional properties to assign onto the component instance.
104
+ */
105
+ set(type: number, props: Partial<Component>): Component;
89
106
  /**
90
107
  * Remove the component of the given class from this entity.
91
108
  *
@@ -102,7 +119,7 @@ export declare class Entity {
102
119
  * @param type - Numeric component type id.
103
120
  */
104
121
  remove(type: number): void;
105
- /** @internal Called by systems to deliver update notifications. */
122
+ /** @internal Called by queries to deliver update notifications. */
106
123
  _notifyModified(component: Component): void;
107
124
  /**
108
125
  * Retrieve the component of type `Class`, or `undefined` if not present.
@@ -124,13 +141,15 @@ export declare class Entity {
124
141
  */
125
142
  get events(): EntityEvents;
126
143
  /** @internal */
127
- _hasSystem(s: System): boolean;
144
+ _hasQuery(q: Query): boolean;
145
+ /** @internal Removes a query from this entity's tracking sets without firing any callbacks. */
146
+ _purgeQuery(q: Query): void;
128
147
  /** @internal */
129
- _addSystem(s: System): void;
148
+ _addQuery(q: Query): void;
130
149
  /** @internal */
131
- _removeSystem(s: System): void;
150
+ _removeQuery(q: Query): void;
132
151
  /** @internal */
133
- _updateSystems(): void;
152
+ _updateQueries(): void;
134
153
  /** `true` when the entity has no components attached. */
135
154
  get empty(): boolean;
136
155
  private _destroy;
package/dist/entity.js CHANGED
@@ -31,12 +31,12 @@ export class Entity {
31
31
  this.deletedComponents = new ArrayMap(); //maps deleted component types to Components
32
32
  /**
33
33
  * Bitmask representing the set of component types currently attached to this
34
- * entity. Used by the world to efficiently match entities against system
35
- * queries.
34
+ * entity. Used by the world to efficiently match entities against query
35
+ * predicates.
36
36
  */
37
37
  this.componentBitmask = new Bitset();
38
- this.systems = new Set();
39
- this.newSystems = [];
38
+ this.queries = new Set();
39
+ this.newQueries = [];
40
40
  /**
41
41
  * A free-form property bag that modules can use to associate arbitrary data
42
42
  * with an entity without registering a component.
@@ -57,13 +57,28 @@ export class Entity {
57
57
  this._children = new Set();
58
58
  return this._children;
59
59
  }
60
+ getComponentInstance(meta) {
61
+ const c = new meta.Class(this, meta);
62
+ const hook = meta["onAddHandler"];
63
+ if (hook)
64
+ hook(c);
65
+ return c;
66
+ }
60
67
  add(typeOrClass, markAsModified = true) {
61
68
  const type = this.world.getComponentType(typeOrClass);
62
69
  let c = this.components.get(type);
63
70
  if (c) {
64
71
  return c;
65
72
  }
66
- c = this.world["getComponentInstance"](typeOrClass, this);
73
+ const meta = this.world.getComponentMeta(typeOrClass);
74
+ if (meta.exclusive) {
75
+ for (const exclusiveType of meta.exclusive) {
76
+ if (this.components.has(exclusiveType)) {
77
+ this.remove(exclusiveType);
78
+ }
79
+ }
80
+ }
81
+ c = this.getComponentInstance(meta);
67
82
  this.components.set(type, c);
68
83
  this.componentBitmask.add(type);
69
84
  this.world._notifyComponentAdded(this, c);
@@ -71,6 +86,10 @@ export class Entity {
71
86
  this.world._queueUpdatedComponent(c);
72
87
  return c;
73
88
  }
89
+ set(typeOrClass, props) {
90
+ const c = this.add(typeOrClass);
91
+ return Object.assign(c, props);
92
+ }
74
93
  remove(typeOrClass) {
75
94
  const type = this.world.getComponentType(typeOrClass);
76
95
  const c = this.components.get(type);
@@ -81,10 +100,10 @@ export class Entity {
81
100
  this.world._notifyComponentRemoved(this, c);
82
101
  }
83
102
  }
84
- /** @internal Called by systems to deliver update notifications. */
103
+ /** @internal Called by queries to deliver update notifications. */
85
104
  _notifyModified(component) {
86
- this.systems.forEach((s) => {
87
- s.notifyModified(component);
105
+ this.queries.forEach((q) => {
106
+ q.notifyModified(component);
88
107
  });
89
108
  }
90
109
  /**
@@ -119,28 +138,35 @@ export class Entity {
119
138
  return this._events;
120
139
  }
121
140
  /** @internal */
122
- _hasSystem(s) {
123
- return this.systems.has(s);
141
+ _hasQuery(q) {
142
+ return this.queries.has(q);
143
+ }
144
+ /** @internal Removes a query from this entity's tracking sets without firing any callbacks. */
145
+ _purgeQuery(q) {
146
+ this.queries.delete(q);
147
+ const idx = this.newQueries.indexOf(q);
148
+ if (idx !== -1)
149
+ this.newQueries.splice(idx, 1);
124
150
  }
125
151
  /** @internal */
126
- _addSystem(s) {
127
- if (!this.systems.has(s)) {
128
- this.newSystems.push(s);
129
- s._enter(this);
152
+ _addQuery(q) {
153
+ if (!this.queries.has(q)) {
154
+ this.newQueries.push(q);
155
+ q._enter(this);
130
156
  }
131
157
  }
132
158
  /** @internal */
133
- _removeSystem(s) {
134
- if (this.systems.delete(s)) {
135
- s._exit(this);
159
+ _removeQuery(q) {
160
+ if (this.queries.delete(q)) {
161
+ q._exit(this);
136
162
  }
137
163
  }
138
164
  /** @internal */
139
- _updateSystems() {
140
- this.newSystems.forEach((s) => {
141
- this.systems.add(s);
165
+ _updateQueries() {
166
+ this.newQueries.forEach((q) => {
167
+ this.queries.add(q);
142
168
  });
143
- this.newSystems.length = 0;
169
+ this.newQueries.length = 0;
144
170
  }
145
171
  /** `true` when the entity has no components attached. */
146
172
  get empty() {
@@ -150,10 +176,10 @@ export class Entity {
150
176
  if (this.destroyed)
151
177
  return;
152
178
  this.destroyed = true;
153
- this.systems.forEach((s) => {
154
- s._exit(this);
179
+ this.queries.forEach((q) => {
180
+ q._exit(this);
155
181
  });
156
- this.systems.clear();
182
+ this.queries.clear();
157
183
  if (this._events) {
158
184
  this._events.emit("destroy");
159
185
  this._events.removeAllListeners("destroy");
@@ -1 +1 @@
1
- {"version":3,"file":"entity.js","sourceRoot":"","sources":["../src/entity.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"entity.js","sourceRoot":"","sources":["../src/entity.ts"],"names":[],"mappings":"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"}