@vworlds/vecs 1.0.8 → 1.0.10

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/dist/query.d.ts CHANGED
@@ -1,9 +1,12 @@
1
+ import { ArrayMap } from "./util/array_map.js";
2
+ import { Bitset } from "./util/bitset.js";
1
3
  import { Component } from "./component.js";
2
4
  import type { Entity } from "./entity.js";
3
5
  import { type World } from "./world.js";
4
6
  import { type EntityTestFunc, type QueryDSL, type MaybeRequired } from "./dsl.js";
5
7
  export type { EntityTestFunc, QueryDSL, MaybeRequired };
6
- type EntityCallback = (e: Entity) => void;
8
+ type EntityCallback = (e: Entity, snapshot?: Map<number, Component>) => void;
9
+ type ComponentCallback = (c: Component) => void;
7
10
  type ComponentOrParent = typeof Component | {
8
11
  parent: typeof Component;
9
12
  };
@@ -15,18 +18,18 @@ type ComponentInstance<T> = T extends {
15
18
  * expression.
16
19
  *
17
20
  * `Query` tracks every entity whose component set satisfies the predicate set
18
- * via {@link requires} or {@link query}. Entry and exit callbacks fire
19
- * automatically as entities gain or lose matching components. The tracked set
20
- * is exposed via {@link entities} and {@link forEach}.
21
+ * via {@link requires} or {@link query}. Entry, exit, and update callbacks
22
+ * fire automatically when the world's command queue is processed. The tracked
23
+ * set is exposed via {@link entities} and {@link forEach}.
21
24
  *
22
- * {@link System} extends `Query` and adds per-tick runtime concerns
23
- * (`update`, `each`, `run`). Use `Query` directly when you only need the
24
- * reactive entity set without pipeline integration.
25
+ * {@link System} extends `Query` and queues callbacks for its next `_run`
26
+ * rather than firing them immediately. Use `Query` directly when you want
27
+ * synchronous reactive callbacks without pipeline integration.
25
28
  *
26
29
  * ### Type parameter `R`
27
30
  * Tracks which component classes are "required" (declared via {@link requires}
28
31
  * or the `_guaranteed` hint of {@link query}). Those components appear as
29
- * non-nullable in {@link sort} callbacks.
32
+ * non-nullable in {@link sort}, {@link forEach}, and {@link update} callbacks.
30
33
  */
31
34
  export declare class Query<R extends (typeof Component)[] = []> {
32
35
  /** Unique name for this query, used in logs and debug output. */
@@ -34,10 +37,16 @@ export declare class Query<R extends (typeof Component)[] = []> {
34
37
  /** The world that owns this query. */
35
38
  readonly world: World;
36
39
  protected _entities: Set<Entity> | undefined;
37
- protected _enterCallback: EntityCallback[];
38
- protected _exitCallback: EntityCallback[];
40
+ protected _enterCallback: EntityCallback | undefined;
41
+ protected _exitCallback: EntityCallback | undefined;
42
+ /** @internal Direct component type ids that the exit callback injects; undefined when no injection. */
43
+ protected _exitSnapshotTypes: number[] | undefined;
39
44
  protected _belongs: EntityTestFunc;
40
45
  protected hasQuery: boolean;
46
+ /** @internal Per-component-type update callbacks. */
47
+ protected componentUpdateCallbacks: ArrayMap<ComponentCallback>;
48
+ /** @internal Bitmask of component types this query is watching for updates. */
49
+ protected watchlistBitmask: Bitset;
41
50
  constructor(
42
51
  /** Unique name for this query, used in logs and debug output. */
43
52
  name: string,
@@ -67,6 +76,11 @@ export declare class Query<R extends (typeof Component)[] = []> {
67
76
  /**
68
77
  * Iterate over every entity currently tracked by this query.
69
78
  *
79
+ * Mutations made by `callback` are buffered into the world command queue
80
+ * (deferred mode) and only become visible after iteration finishes. Nested
81
+ * iteration inside an already-deferred context (a system, another forEach)
82
+ * inherits the outer deferred scope and does not drain on exit.
83
+ *
70
84
  * @param callback - Called once per tracked entity, in insertion order
71
85
  * (or sort order when {@link sort} is configured).
72
86
  */
@@ -88,11 +102,26 @@ export declare class Query<R extends (typeof Component)[] = []> {
88
102
  }) => void): void;
89
103
  /** Returns `true` if the entity satisfies this query's predicate. */
90
104
  belongs(e: Entity): boolean;
91
- /** Hook for subclasses — called when a component on an entity in this query changes. */
92
- notifyModified(_c: Component): void;
93
- /** @internal Fires enter callbacks and adds entity to the tracked set. */
105
+ /**
106
+ * @internal Called by the world during command-queue routing when a Set
107
+ * command targets an entity that this query currently tracks. Default:
108
+ * fires the user-registered `update` callback for the component's type.
109
+ * `System` overrides this to push into its inbox instead.
110
+ */
111
+ notifyModified(c: Component): void;
112
+ /**
113
+ * @internal Adds the entity to the tracked set, registers query membership
114
+ * on the entity, fires registered enter callbacks, then bridges any
115
+ * already-attached watched components through `notifyModified` so that
116
+ * `update` callbacks see the entity once on entry. `System` overrides this
117
+ * to push inbox events (events fire later in `_run`).
118
+ */
94
119
  _enter(e: Entity): void;
95
- /** @internal Fires exit callbacks and removes entity from the tracked set. */
120
+ /**
121
+ * @internal Removes the entity from the tracked set, deregisters query
122
+ * membership, and fires registered exit callbacks. `System` overrides this
123
+ * to also push an inbox event.
124
+ */
96
125
  _exit(e: Entity): void;
97
126
  /**
98
127
  * Register a callback that fires when an entity **enters** this query
@@ -126,10 +155,6 @@ export declare class Query<R extends (typeof Component)[] = []> {
126
155
  * (its components no longer satisfy the predicate, or it was destroyed) with
127
156
  * injected components.
128
157
  *
129
- * Components that were just removed are still accessible via `get_deleted`
130
- * semantics — the injected tuple includes them even though they are no
131
- * longer in the entity's active component set.
132
- *
133
158
  * @param inject - Component classes to resolve and inject.
134
159
  * @param callback - Receives the entity and the resolved component tuple.
135
160
  * @returns `this` for chaining.
@@ -144,6 +169,52 @@ export declare class Query<R extends (typeof Component)[] = []> {
144
169
  * @returns `this` for chaining.
145
170
  */
146
171
  exit(callback: (e: Entity) => void): this;
172
+ /**
173
+ * Register a callback that fires when a component of type `ComponentClass`
174
+ * is modified on any entity tracked by this query.
175
+ *
176
+ * On a {@link Query}, callbacks fire **immediately** when the world's
177
+ * command queue routes the corresponding `Set` command. On a {@link System},
178
+ * the event is buffered in the system's inbox and the callback fires during
179
+ * the system's next `_run`.
180
+ *
181
+ * If no other predicate has been set on this query, the watchlist
182
+ * automatically expands to require `ComponentClass` (equivalent to adding
183
+ * it to a `requires` / `HAS` query).
184
+ *
185
+ * @param ComponentClass - The component class to watch.
186
+ * @param callback - Receives the modified component instance.
187
+ * @returns `this` for chaining.
188
+ *
189
+ * @example
190
+ * ```ts
191
+ * world.system("RenderPosition")
192
+ * .update(Position, (pos) => {
193
+ * sprite.setPosition(pos.x, pos.y);
194
+ * });
195
+ * ```
196
+ */
197
+ update<C extends typeof Component>(ComponentClass: C, callback: (c: InstanceType<C>) => void): this;
198
+ /**
199
+ * Register a callback that fires when `ComponentClass` is modified, with
200
+ * additional components injected from the same entity.
201
+ *
202
+ * @param ComponentClass - The component class to watch.
203
+ * @param inject - Additional component classes to resolve from the entity.
204
+ * @param callback - Receives the modified component and the injected tuple.
205
+ * @returns `this` for chaining.
206
+ *
207
+ * @example
208
+ * ```ts
209
+ * world.system("SyncSprite")
210
+ * .update(Position, [Sprite], (pos, [sprite]) => {
211
+ * sprite.sprite.setPosition(pos.x, pos.y);
212
+ * });
213
+ * ```
214
+ */
215
+ update<C extends typeof Component, J extends (typeof Component)[]>(ComponentClass: C, inject: readonly [...J], callback: (c: InstanceType<C>, injected: {
216
+ [K in keyof J]: MaybeRequired<J[K], R>;
217
+ }) => void): this;
147
218
  /**
148
219
  * Enable sorted entity tracking: matched entities are stored in insertion
149
220
  * order determined by `compare`, which receives a tuple of resolved
package/dist/query.js CHANGED
@@ -1,23 +1,25 @@
1
1
  import { OrderedSet } from "./util/ordered_set.js";
2
- import { buildEntityTest } from "./dsl.js";
2
+ import { ArrayMap } from "./util/array_map.js";
3
+ import { Bitset } from "./util/bitset.js";
4
+ import { HAS, buildEntityTest, } from "./dsl.js";
3
5
  const EMPTY_ENTITIES = new Set();
4
6
  /**
5
7
  * A reactive, always-updated list of entities that match a given query
6
8
  * expression.
7
9
  *
8
10
  * `Query` tracks every entity whose component set satisfies the predicate set
9
- * via {@link requires} or {@link query}. Entry and exit callbacks fire
10
- * automatically as entities gain or lose matching components. The tracked set
11
- * is exposed via {@link entities} and {@link forEach}.
11
+ * via {@link requires} or {@link query}. Entry, exit, and update callbacks
12
+ * fire automatically when the world's command queue is processed. The tracked
13
+ * set is exposed via {@link entities} and {@link forEach}.
12
14
  *
13
- * {@link System} extends `Query` and adds per-tick runtime concerns
14
- * (`update`, `each`, `run`). Use `Query` directly when you only need the
15
- * reactive entity set without pipeline integration.
15
+ * {@link System} extends `Query` and queues callbacks for its next `_run`
16
+ * rather than firing them immediately. Use `Query` directly when you want
17
+ * synchronous reactive callbacks without pipeline integration.
16
18
  *
17
19
  * ### Type parameter `R`
18
20
  * Tracks which component classes are "required" (declared via {@link requires}
19
21
  * or the `_guaranteed` hint of {@link query}). Those components appear as
20
- * non-nullable in {@link sort} callbacks.
22
+ * non-nullable in {@link sort}, {@link forEach}, and {@link update} callbacks.
21
23
  */
22
24
  export class Query {
23
25
  constructor(
@@ -27,10 +29,16 @@ export class Query {
27
29
  world, track = true) {
28
30
  this.name = name;
29
31
  this.world = world;
30
- this._enterCallback = [];
31
- this._exitCallback = [];
32
+ this._enterCallback = undefined;
33
+ this._exitCallback = undefined;
34
+ /** @internal Direct component type ids that the exit callback injects; undefined when no injection. */
35
+ this._exitSnapshotTypes = undefined;
32
36
  this._belongs = (_e) => false;
33
37
  this.hasQuery = false;
38
+ /** @internal Per-component-type update callbacks. */
39
+ this.componentUpdateCallbacks = new ArrayMap();
40
+ /** @internal Bitmask of component types this query is watching for updates. */
41
+ this.watchlistBitmask = new Bitset();
34
42
  world._addQuery(this);
35
43
  if (track) {
36
44
  this.track();
@@ -58,11 +66,12 @@ export class Query {
58
66
  if (this._entities === undefined) {
59
67
  return;
60
68
  }
61
- this.world._forEachEntity((e) => {
62
- if (this.belongs(e) && !this._entities.has(e)) {
63
- e._addQuery(this);
64
- e._updateQueries();
65
- }
69
+ this.world.defer(() => {
70
+ this.world.entities.forEach((e) => {
71
+ if (this.belongs(e) && !e.isInQuery(this)) {
72
+ this._enter(e);
73
+ }
74
+ });
66
75
  });
67
76
  }
68
77
  /**
@@ -76,57 +85,128 @@ export class Query {
76
85
  return this._entities ?? EMPTY_ENTITIES;
77
86
  }
78
87
  forEach(componentsOrCallback, callback) {
79
- if (typeof componentsOrCallback === "function") {
80
- this._entities?.forEach(componentsOrCallback);
81
- }
82
- else {
83
- if (!this._entities || !this.world) {
84
- return;
88
+ this.world.beginDefer();
89
+ try {
90
+ if (typeof componentsOrCallback === "function") {
91
+ this._entities?.forEach(componentsOrCallback);
85
92
  }
86
- const types = componentsOrCallback.map((C) => this.world.getComponentType(C));
87
- this._entities.forEach((e) => {
88
- const resolved = types.map((t) => e.get(t));
89
- callback(e, resolved);
90
- });
93
+ else {
94
+ if (!this._entities || !this.world) {
95
+ return;
96
+ }
97
+ const types = componentsOrCallback.map((C) => this.world.getComponentType(C));
98
+ this._entities.forEach((e) => {
99
+ const resolved = types.map((t) => e.get(t));
100
+ callback(e, resolved);
101
+ });
102
+ }
103
+ }
104
+ finally {
105
+ this.world.endDefer();
91
106
  }
92
107
  }
93
108
  /** Returns `true` if the entity satisfies this query's predicate. */
94
109
  belongs(e) {
95
110
  return this._belongs(e);
96
111
  }
97
- /** Hook for subclasses — called when a component on an entity in this query changes. */
98
- notifyModified(_c) { }
99
- /** @internal Fires enter callbacks and adds entity to the tracked set. */
112
+ /**
113
+ * @internal Called by the world during command-queue routing when a Set
114
+ * command targets an entity that this query currently tracks. Default:
115
+ * fires the user-registered `update` callback for the component's type.
116
+ * `System` overrides this to push into its inbox instead.
117
+ */
118
+ notifyModified(c) {
119
+ if (!this.watchlistBitmask.hasBit(c.bitPtr)) {
120
+ return;
121
+ }
122
+ const callback = this.componentUpdateCallbacks.get(c.type);
123
+ if (callback) {
124
+ callback(c);
125
+ }
126
+ }
127
+ /**
128
+ * @internal Adds the entity to the tracked set, registers query membership
129
+ * on the entity, fires registered enter callbacks, then bridges any
130
+ * already-attached watched components through `notifyModified` so that
131
+ * `update` callbacks see the entity once on entry. `System` overrides this
132
+ * to push inbox events (events fire later in `_run`).
133
+ */
100
134
  _enter(e) {
101
- this._enterCallback.forEach((cb) => cb(e));
102
135
  this._entities?.add(e);
136
+ e._addQueryMembership(this);
137
+ this._enterCallback?.(e);
138
+ // Bridge: surface the entity's already-attached watched components as
139
+ // update events so `update` handlers fire once on entry without the user
140
+ // having to call `modified()` explicitly.
141
+ e.forEachComponent((c) => {
142
+ if (this.watchlistBitmask.hasBit(c.bitPtr)) {
143
+ this.notifyModified(c);
144
+ }
145
+ });
103
146
  }
104
- /** @internal Fires exit callbacks and removes entity from the tracked set. */
147
+ /**
148
+ * @internal Removes the entity from the tracked set, deregisters query
149
+ * membership, and fires registered exit callbacks. `System` overrides this
150
+ * to also push an inbox event.
151
+ */
105
152
  _exit(e) {
106
- this._exitCallback.forEach((cb) => cb(e));
153
+ this._exitCallback?.(e);
107
154
  this._entities?.delete(e);
155
+ e._removeQueryMembership(this);
108
156
  }
109
157
  enter(injectOrCallback, callback) {
110
158
  if (typeof injectOrCallback === "function") {
111
- this._enterCallback.push(injectOrCallback);
159
+ this._enterCallback = injectOrCallback;
112
160
  }
113
161
  else {
114
162
  const inject = this.mapInjectedClassToTypes(injectOrCallback);
115
- this._enterCallback.push((e) => {
163
+ this._enterCallback = (e) => {
116
164
  callback(e, this.getInjected(e, inject));
117
- });
165
+ };
118
166
  }
119
167
  return this;
120
168
  }
121
169
  exit(injectOrCallback, callback) {
122
170
  if (typeof injectOrCallback === "function") {
123
- this._exitCallback.push(injectOrCallback);
171
+ this._exitCallback = injectOrCallback;
172
+ this._exitSnapshotTypes = undefined;
124
173
  }
125
174
  else {
126
175
  const inject = this.mapInjectedClassToTypes(injectOrCallback);
127
- this._exitCallback.push((e) => {
128
- callback(e, this.getInjected(e, inject, true));
129
- });
176
+ // Only direct (non-parent) types need snapshotting; parent refs are read
177
+ // from e.parent at callback time, which is still alive.
178
+ this._exitSnapshotTypes = inject.filter((t) => typeof t === "number");
179
+ this._exitCallback = (e, exitSnapshot) => {
180
+ callback(e, this.getInjected(e, inject, exitSnapshot));
181
+ };
182
+ }
183
+ return this;
184
+ }
185
+ update(ComponentClass, injectOrCallback, callback) {
186
+ const type = this.world.getComponentType(ComponentClass);
187
+ if (typeof injectOrCallback === "function") {
188
+ callback = injectOrCallback;
189
+ this.componentUpdateCallbacks.set(type, callback);
190
+ }
191
+ else {
192
+ const inject = injectOrCallback;
193
+ const injectedComponentTypes = inject.map((C) => this.world.getComponentType(C));
194
+ const cb = (c) => {
195
+ const injected = [];
196
+ injectedComponentTypes.forEach((InjectedComponentType) => {
197
+ injected.push(c.entity.get(InjectedComponentType));
198
+ });
199
+ if (callback) {
200
+ callback(c, injected);
201
+ }
202
+ };
203
+ this.componentUpdateCallbacks.set(type, cb);
204
+ }
205
+ this.watchlistBitmask.add(type);
206
+ if (!this.hasQuery) {
207
+ const watchlist = this.watchlistBitmask.indices();
208
+ this._belongs = HAS(this.world, ...watchlist);
209
+ this.backfill();
130
210
  }
131
211
  return this;
132
212
  }
@@ -149,7 +229,7 @@ export class Query {
149
229
  */
150
230
  sort(components, compare) {
151
231
  const types = components.map((C) => this.world.getComponentType(C));
152
- this._entities = new OrderedSet((a, b) => compare(types.map((t) => a.get(t, true)), types.map((t) => b.get(t, true))));
232
+ this._entities = new OrderedSet((a, b) => compare(types.map((t) => a.get(t)), types.map((t) => b.get(t))));
153
233
  this.backfill();
154
234
  return this;
155
235
  }
@@ -210,20 +290,18 @@ export class Query {
210
290
  this.query(components);
211
291
  return this;
212
292
  }
213
- getComponent(e, C, considerDeleted) {
214
- let c;
293
+ getComponent(e, C, exitSnapshot) {
215
294
  if (typeof C === "number") {
216
- c = e.get(C, considerDeleted);
295
+ return exitSnapshot?.get(C) ?? e.get(C);
217
296
  }
218
297
  else {
219
- c = e.parent && e.parent.get(C.parent, considerDeleted);
298
+ return e.parent?.get(C.parent);
220
299
  }
221
- return c;
222
300
  }
223
- getInjected(e, inject, considerDeleted = false) {
301
+ getInjected(e, inject, exitSnapshot) {
224
302
  const injected = [];
225
303
  inject.forEach((C) => {
226
- const c = this.getComponent(e, C, considerDeleted);
304
+ const c = this.getComponent(e, C, exitSnapshot);
227
305
  if (!c) {
228
306
  throw "query does not contain component";
229
307
  }
package/dist/query.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"query.js","sourceRoot":"","sources":["../src/query.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"query.js","sourceRoot":"","sources":["../src/query.ts"],"names":[],"mappings":"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"}
package/dist/system.d.ts CHANGED
@@ -1,5 +1,3 @@
1
- import { ArrayMap } from "./util/array_map.js";
2
- import { Bitset } from "./util/bitset.js";
3
1
  import { Component } from "./component.js";
4
2
  import { Query } from "./query.js";
5
3
  import { type QueryDSL, type MaybeRequired } from "./dsl.js";
@@ -7,7 +5,6 @@ import type { Entity } from "./entity.js";
7
5
  import { Phase, type IPhase } from "./phase.js";
8
6
  import { type World } from "./world.js";
9
7
  export type { QueryDSL as SystemQuery, EntityTestFunc } from "./dsl.js";
10
- type ComponentCallback = (c: Component) => void;
11
8
  type RunCallback = (now: number, delta: number) => void;
12
9
  /**
13
10
  * A reactive processor that operates on a filtered subset of world entities.
@@ -27,6 +24,11 @@ type RunCallback = (now: number, delta: number) => void;
27
24
  * once all systems are registered; after that, drive the loop with
28
25
  * {@link World.runPhase}.
29
26
  *
27
+ * Internally each system holds a single ordered **inbox** of routed events
28
+ * (`enter`, `exit`, `update`). The world appends to it during command-queue
29
+ * routing; the system replays the inbox at the top of every `_run` so
30
+ * callbacks observe events in arrival order.
31
+ *
30
32
  * ### Component injection and type inference
31
33
  *
32
34
  * `enter`, `exit`, `update`, `each`, and `sort` all accept an array of
@@ -40,13 +42,11 @@ type RunCallback = (now: number, delta: number) => void;
40
42
  * non-nullable; any component not in `R` remains `Type | undefined`.
41
43
  */
42
44
  export declare class System<R extends (typeof Component)[] = []> extends Query<R> {
43
- protected componentUpdateCallbacks: ArrayMap<ComponentCallback>;
44
45
  protected eachCallback: ((e: Entity) => void) | undefined;
45
46
  private _runCallback;
46
- private readonly updateQueue;
47
+ private readonly inbox;
47
48
  /** @internal */
48
49
  _phase: string | Phase | undefined;
49
- protected watchlistBitmask: Bitset;
50
50
  constructor(name: string, world: World);
51
51
  /**
52
52
  * Assign this system to a pipeline phase.
@@ -60,13 +60,18 @@ export declare class System<R extends (typeof Component)[] = []> extends Query<R
60
60
  * @returns `this` for chaining.
61
61
  */
62
62
  phase(p: string | IPhase): this;
63
- /** @internal Delivers a component-modified notification to this system. */
64
- notifyModified(c: Component): void;
65
- /** @internal Fires enter callbacks, adds entity to tracked set, queues component updates. */
63
+ /** @internal Routing entry: register membership and enqueue an enter event. */
66
64
  _enter(e: Entity): void;
67
- /** @internal Fires exit callbacks, removes entity from tracked set, drains update queue. */
65
+ /** @internal Routing entry: deregister membership and enqueue an exit event. */
68
66
  _exit(e: Entity): void;
69
- /** @internal Execute one tick: run `run`, fire `each`, then drain the update queue. */
67
+ /** @internal Routing entry: enqueue an update event if the watchlist matches. */
68
+ notifyModified(c: Component): void;
69
+ /**
70
+ * @internal Execute one tick: drain the inbox in arrival order, then run
71
+ * `runCallback` and `eachCallback`. The whole body runs in a deferred
72
+ * scope; any mutations made by callbacks land in the world queue and are
73
+ * processed by the world after `_run` returns.
74
+ */
70
75
  _run(now: number, delta: number): void;
71
76
  /**
72
77
  * Register a per-tick callback that runs every time this system's phase
@@ -80,47 +85,6 @@ export declare class System<R extends (typeof Component)[] = []> extends Query<R
80
85
  * @returns `this` for chaining.
81
86
  */
82
87
  run(callback: RunCallback): this;
83
- /**
84
- * Register a callback that fires when a component of type `ComponentClass`
85
- * is modified on any entity in this system.
86
- *
87
- * The system will automatically begin tracking entities that have this
88
- * component type (equivalent to adding it to a `requires` / `HAS` query)
89
- * unless a custom {@link query} was already set.
90
- *
91
- * @param ComponentClass - The component class to watch.
92
- * @param callback - Receives the modified component instance.
93
- * @returns `this` for chaining.
94
- *
95
- * @example
96
- * ```ts
97
- * world.system("RenderPosition")
98
- * .update(Position, (pos) => {
99
- * sprite.setPosition(pos.x, pos.y);
100
- * });
101
- * ```
102
- */
103
- update<C extends typeof Component>(ComponentClass: C, callback: (c: InstanceType<C>) => void): this;
104
- /**
105
- * Register a callback that fires when `ComponentClass` is modified, with
106
- * additional components injected from the same entity.
107
- *
108
- * @param ComponentClass - The component class to watch.
109
- * @param inject - Additional component classes to resolve from the entity.
110
- * @param callback - Receives the modified component and the injected tuple.
111
- * @returns `this` for chaining.
112
- *
113
- * @example
114
- * ```ts
115
- * world.system("SyncSprite")
116
- * .update(Position, [Sprite], (pos, [sprite]) => {
117
- * sprite.sprite.setPosition(pos.x, pos.y);
118
- * });
119
- * ```
120
- */
121
- update<C extends typeof Component, J extends (typeof Component)[]>(ComponentClass: C, inject: readonly [...J], callback: (c: InstanceType<C>, injected: {
122
- [K in keyof J]: MaybeRequired<J[K], R>;
123
- }) => void): this;
124
88
  /**
125
89
  * Register a callback that fires **every tick** for every entity currently
126
90
  * tracked by this system, with the listed components resolved from each