@vworlds/vecs 1.0.10 → 1.0.11
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 +218 -229
- package/dist/command.d.ts +1 -46
- package/dist/component.d.ts +51 -59
- package/dist/component.js +31 -25
- package/dist/component.js.map +1 -1
- package/dist/dsl.d.ts +34 -26
- package/dist/dsl.js +46 -20
- package/dist/dsl.js.map +1 -1
- package/dist/entity.d.ts +96 -106
- package/dist/entity.js +261 -190
- package/dist/entity.js.map +1 -1
- package/dist/filter.d.ts +31 -23
- package/dist/filter.js +24 -17
- package/dist/filter.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/package.json +3 -1
- package/dist/phase.d.ts +5 -28
- package/dist/phase.js +11 -10
- package/dist/phase.js.map +1 -1
- package/dist/query.d.ts +107 -144
- package/dist/query.js +200 -169
- package/dist/query.js.map +1 -1
- package/dist/system.d.ts +59 -87
- package/dist/system.js +114 -114
- package/dist/system.js.map +1 -1
- package/dist/util/array_map.d.ts +4 -55
- package/dist/util/array_map.js +35 -37
- package/dist/util/array_map.js.map +1 -1
- package/dist/util/bitset.d.ts +40 -50
- package/dist/util/bitset.js +76 -62
- package/dist/util/bitset.js.map +1 -1
- package/dist/util/events.d.ts +14 -18
- package/dist/util/events.js +24 -3
- package/dist/util/events.js.map +1 -1
- package/dist/util/ordered_set.d.ts +1 -17
- package/dist/util/ordered_set.js +74 -25
- package/dist/util/ordered_set.js.map +1 -1
- package/dist/world.d.ts +212 -224
- package/dist/world.js +368 -330
- package/dist/world.js.map +1 -1
- package/eslint-rules/internal-underscore.js +60 -0
- package/eslint.config.js +5 -0
- package/package.json +3 -1
package/dist/query.d.ts
CHANGED
|
@@ -1,97 +1,89 @@
|
|
|
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 type { Entity } from "./entity.js";
|
|
5
3
|
import { type World } from "./world.js";
|
|
6
4
|
import { type EntityTestFunc, type QueryDSL, type MaybeRequired } from "./dsl.js";
|
|
7
5
|
export type { EntityTestFunc, QueryDSL, MaybeRequired };
|
|
8
|
-
|
|
9
|
-
type ComponentCallback = (c: Component) => void;
|
|
6
|
+
/** Component class, or `{ parent: ComponentClass }` to resolve from the entity's parent. */
|
|
10
7
|
type ComponentOrParent = typeof Component | {
|
|
11
8
|
parent: typeof Component;
|
|
12
9
|
};
|
|
10
|
+
/** Resolves the component instance type for one element of a `ComponentOrParent` tuple. */
|
|
13
11
|
type ComponentInstance<T> = T extends {
|
|
14
12
|
parent: typeof Component;
|
|
15
13
|
} ? InstanceType<T["parent"]> : T extends typeof Component ? InstanceType<T> : never;
|
|
16
14
|
/**
|
|
17
|
-
* A reactive, always-
|
|
18
|
-
*
|
|
15
|
+
* A reactive, always-up-to-date set of entities matching a {@link QueryDSL}
|
|
16
|
+
* predicate.
|
|
19
17
|
*
|
|
20
|
-
* `Query`
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
* set is exposed via {@link entities} and {@link forEach}.
|
|
18
|
+
* `Query` listens to entity / component mutations through the world's command
|
|
19
|
+
* queue and tracks which entities currently satisfy its predicate. It fires
|
|
20
|
+
* `enter`, `exit`, and `update` callbacks as the matched set changes. The
|
|
21
|
+
* tracked set is exposed via {@link entities} and {@link forEach}.
|
|
24
22
|
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
23
|
+
* Callbacks fire **synchronously** when the world routes a command — so
|
|
24
|
+
* mutations made inside one of these callbacks are themselves observed
|
|
25
|
+
* immediately by other queries / systems.
|
|
28
26
|
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
27
|
+
* {@link System} extends `Query` and queues callbacks into an inbox replayed
|
|
28
|
+
* during `_run` instead of firing them immediately. Use `Query` directly when
|
|
29
|
+
* you want a reactive entity set without pipeline integration.
|
|
30
|
+
*
|
|
31
|
+
* @typeParam R - Component classes guaranteed present on every matched entity
|
|
32
|
+
* (declared via {@link requires} or the `_guaranteed` hint of {@link query}).
|
|
33
|
+
* Components in `R` appear as non-nullable in {@link sort}, {@link forEach},
|
|
34
|
+
* and {@link update} callback tuples.
|
|
33
35
|
*/
|
|
34
36
|
export declare class Query<R extends (typeof Component)[] = []> {
|
|
35
|
-
/** Unique name
|
|
37
|
+
/** Unique display name; appears in logs and debug output. */
|
|
36
38
|
readonly name: string;
|
|
37
|
-
/**
|
|
39
|
+
/** World that owns this query. */
|
|
38
40
|
readonly world: World;
|
|
39
|
-
protected _entities: Set<Entity> | undefined;
|
|
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;
|
|
44
|
-
protected _belongs: EntityTestFunc;
|
|
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;
|
|
50
41
|
constructor(
|
|
51
|
-
/** Unique name
|
|
42
|
+
/** Unique display name; appears in logs and debug output. */
|
|
52
43
|
name: string,
|
|
53
|
-
/**
|
|
44
|
+
/** World that owns this query. */
|
|
54
45
|
world: World, track?: boolean);
|
|
46
|
+
/**
|
|
47
|
+
* Read-only view of the entities currently tracked by this query.
|
|
48
|
+
*
|
|
49
|
+
* Populated as entities enter and removed as they exit. Empty unless
|
|
50
|
+
* tracking is enabled — that is the default for standalone queries created
|
|
51
|
+
* via {@link World.query}, but {@link System} requires an explicit
|
|
52
|
+
* {@link track}, {@link sort}, or `each` call.
|
|
53
|
+
*/
|
|
54
|
+
get entities(): ReadonlySet<Entity>;
|
|
55
55
|
/** Returns the query name. */
|
|
56
56
|
toString(): string;
|
|
57
57
|
/**
|
|
58
58
|
* Enable entity tracking: matched entities are inserted into {@link entities}
|
|
59
59
|
* as they enter and removed as they exit.
|
|
60
60
|
*
|
|
61
|
-
* Idempotent. When called after {@link World.start}, immediately backfills
|
|
62
|
-
* existing
|
|
61
|
+
* Idempotent. When called after {@link World.start}, immediately backfills
|
|
62
|
+
* every existing entity that satisfies the current predicate.
|
|
63
63
|
*
|
|
64
|
-
* @returns
|
|
64
|
+
* @returns This query, for chaining.
|
|
65
65
|
*/
|
|
66
66
|
track(): this;
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
* Read-only view of the entities currently tracked by this query.
|
|
70
|
-
*
|
|
71
|
-
* Populated as entities enter (and removed as they exit). Empty unless
|
|
72
|
-
* tracking is enabled (default for standalone queries; requires an explicit
|
|
73
|
-
* {@link track} call on {@link System | systems}).
|
|
74
|
-
*/
|
|
75
|
-
get entities(): ReadonlySet<Entity>;
|
|
67
|
+
/** Returns `true` when `e` satisfies this query's predicate. */
|
|
68
|
+
belongs(e: Entity): boolean;
|
|
76
69
|
/**
|
|
77
|
-
* Iterate
|
|
70
|
+
* Iterate every entity currently tracked by this query.
|
|
78
71
|
*
|
|
79
72
|
* Mutations made by `callback` are buffered into the world command queue
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
73
|
+
* and only become visible after iteration finishes. Nested iteration inside
|
|
74
|
+
* an already-deferred context (a system, an outer `forEach`) inherits the
|
|
75
|
+
* outer scope and does not drain on exit.
|
|
83
76
|
*
|
|
84
|
-
* @param callback -
|
|
77
|
+
* @param callback - Invoked once per tracked entity, in insertion order
|
|
85
78
|
* (or sort order when {@link sort} is configured).
|
|
86
79
|
*/
|
|
87
80
|
forEach(callback: (e: Entity) => void): void;
|
|
88
81
|
/**
|
|
89
|
-
* Iterate
|
|
90
|
-
* injection.
|
|
82
|
+
* Iterate every tracked entity with component injection.
|
|
91
83
|
*
|
|
92
|
-
* Components
|
|
93
|
-
* {@link query}) are non-nullable in the resolved tuple; any other
|
|
94
|
-
* component may be `undefined` if the entity lacks it.
|
|
84
|
+
* Components covered by {@link requires} (or the `_guaranteed` hint of
|
|
85
|
+
* {@link query}) are non-nullable in the resolved tuple; any other
|
|
86
|
+
* requested component may be `undefined` if the entity lacks it.
|
|
95
87
|
*
|
|
96
88
|
* @param components - Component classes to resolve from each entity.
|
|
97
89
|
* @param callback - Receives the entity and a tuple of resolved component
|
|
@@ -100,37 +92,14 @@ export declare class Query<R extends (typeof Component)[] = []> {
|
|
|
100
92
|
forEach<J extends (typeof Component)[]>(components: readonly [...J], callback: (e: Entity, resolved: {
|
|
101
93
|
[K in keyof J]: MaybeRequired<J[K], R>;
|
|
102
94
|
}) => void): void;
|
|
103
|
-
/** Returns `true` if the entity satisfies this query's predicate. */
|
|
104
|
-
belongs(e: Entity): boolean;
|
|
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
95
|
/**
|
|
113
|
-
*
|
|
114
|
-
*
|
|
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
|
-
*/
|
|
119
|
-
_enter(e: Entity): void;
|
|
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
|
-
*/
|
|
125
|
-
_exit(e: Entity): void;
|
|
126
|
-
/**
|
|
127
|
-
* Register a callback that fires when an entity **enters** this query
|
|
128
|
-
* (i.e. first satisfies the predicate) with injected components.
|
|
96
|
+
* Register a callback invoked when an entity **enters** this query (i.e.
|
|
97
|
+
* first satisfies the predicate), with injected components.
|
|
129
98
|
*
|
|
130
99
|
* @param inject - Ordered list of component classes (or `{ parent: C }`) to
|
|
131
100
|
* resolve from the entering entity and pass to `callback`.
|
|
132
101
|
* @param callback - Receives the entity and the resolved component tuple.
|
|
133
|
-
* @returns
|
|
102
|
+
* @returns This query, for chaining.
|
|
134
103
|
*
|
|
135
104
|
* @example
|
|
136
105
|
* ```ts
|
|
@@ -144,86 +113,81 @@ export declare class Query<R extends (typeof Component)[] = []> {
|
|
|
144
113
|
[K in keyof J]: ComponentInstance<J[K]>;
|
|
145
114
|
}) => void): this;
|
|
146
115
|
/**
|
|
147
|
-
* Register
|
|
116
|
+
* Register an `enter` callback without component injection.
|
|
148
117
|
*
|
|
149
|
-
* @param callback - Receives only the entity
|
|
150
|
-
* @returns
|
|
118
|
+
* @param callback - Receives only the entering entity.
|
|
119
|
+
* @returns This query, for chaining.
|
|
151
120
|
*/
|
|
152
121
|
enter(callback: (e: Entity) => void): this;
|
|
153
122
|
/**
|
|
154
|
-
* Register a callback
|
|
155
|
-
*
|
|
123
|
+
* Register a callback invoked when an entity **exits** this query (its
|
|
124
|
+
* archetype no longer satisfies the predicate, or it was destroyed), with
|
|
156
125
|
* injected components.
|
|
157
126
|
*
|
|
127
|
+
* Components removed in the same frame as the exit are still resolvable
|
|
128
|
+
* because the runtime snapshots them at routing time.
|
|
129
|
+
*
|
|
158
130
|
* @param inject - Component classes to resolve and inject.
|
|
159
131
|
* @param callback - Receives the entity and the resolved component tuple.
|
|
160
|
-
* @returns
|
|
132
|
+
* @returns This query, for chaining.
|
|
161
133
|
*/
|
|
162
134
|
exit<J extends ComponentOrParent[]>(inject: readonly [...J], callback: (e: Entity, injected: {
|
|
163
135
|
[K in keyof J]: ComponentInstance<J[K]>;
|
|
164
136
|
}) => void): this;
|
|
165
137
|
/**
|
|
166
|
-
* Register
|
|
138
|
+
* Register an `exit` callback without component injection.
|
|
167
139
|
*
|
|
168
|
-
* @param callback - Receives only the entity.
|
|
169
|
-
* @returns
|
|
140
|
+
* @param callback - Receives only the exiting entity.
|
|
141
|
+
* @returns This query, for chaining.
|
|
170
142
|
*/
|
|
171
143
|
exit(callback: (e: Entity) => void): this;
|
|
172
144
|
/**
|
|
173
|
-
* Register a callback
|
|
174
|
-
*
|
|
145
|
+
* Register a callback invoked when a component of `ComponentClass` is
|
|
146
|
+
* modified on a tracked entity.
|
|
175
147
|
*
|
|
176
|
-
* On a {@link Query}
|
|
177
|
-
*
|
|
178
|
-
* the event is buffered in the
|
|
179
|
-
*
|
|
148
|
+
* On a {@link Query} the callback fires **immediately** when the world
|
|
149
|
+
* routes the corresponding `Set` / `Modified` command. On a {@link System}
|
|
150
|
+
* the event is buffered in the inbox and the callback fires during the
|
|
151
|
+
* system's next `_run`.
|
|
180
152
|
*
|
|
181
153
|
* If no other predicate has been set on this query, the watchlist
|
|
182
|
-
* automatically expands
|
|
183
|
-
*
|
|
154
|
+
* automatically expands so `ComponentClass` is implicitly required (the
|
|
155
|
+
* predicate becomes a `HAS` of every watched type).
|
|
184
156
|
*
|
|
185
|
-
* @param ComponentClass -
|
|
157
|
+
* @param ComponentClass - Component class to watch.
|
|
186
158
|
* @param callback - Receives the modified component instance.
|
|
187
|
-
* @returns
|
|
159
|
+
* @returns This query, for chaining.
|
|
188
160
|
*
|
|
189
161
|
* @example
|
|
190
162
|
* ```ts
|
|
191
163
|
* world.system("RenderPosition")
|
|
192
|
-
* .update(Position, (pos) =>
|
|
193
|
-
* sprite.setPosition(pos.x, pos.y);
|
|
194
|
-
* });
|
|
164
|
+
* .update(Position, (pos) => sprite.setPosition(pos.x, pos.y));
|
|
195
165
|
* ```
|
|
196
166
|
*/
|
|
197
167
|
update<C extends typeof Component>(ComponentClass: C, callback: (c: InstanceType<C>) => void): this;
|
|
198
168
|
/**
|
|
199
|
-
*
|
|
200
|
-
*
|
|
169
|
+
* Like {@link update}, but with extra components injected from the same
|
|
170
|
+
* entity.
|
|
201
171
|
*
|
|
202
|
-
* @param ComponentClass -
|
|
172
|
+
* @param ComponentClass - Component class to watch.
|
|
203
173
|
* @param inject - Additional component classes to resolve from the entity.
|
|
204
174
|
* @param callback - Receives the modified component and the injected tuple.
|
|
205
|
-
* @returns
|
|
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
|
-
* ```
|
|
175
|
+
* @returns This query, for chaining.
|
|
214
176
|
*/
|
|
215
177
|
update<C extends typeof Component, J extends (typeof Component)[]>(ComponentClass: C, inject: readonly [...J], callback: (c: InstanceType<C>, injected: {
|
|
216
178
|
[K in keyof J]: MaybeRequired<J[K], R>;
|
|
217
179
|
}) => void): this;
|
|
218
180
|
/**
|
|
219
|
-
*
|
|
220
|
-
*
|
|
221
|
-
* component instances for each pair
|
|
181
|
+
* Switch the tracked set to a sorted ordering: matched entities are stored
|
|
182
|
+
* in the position determined by `compare`, which receives a tuple of
|
|
183
|
+
* resolved component instances for each pair being ordered.
|
|
184
|
+
*
|
|
185
|
+
* Implies {@link track}.
|
|
222
186
|
*
|
|
223
187
|
* @param components - Component classes to resolve and pass to `compare`.
|
|
224
|
-
* @param compare -
|
|
225
|
-
* `a` should sort
|
|
226
|
-
* @returns
|
|
188
|
+
* @param compare - Negative when `a` should sort before `b`, zero for
|
|
189
|
+
* equality, positive when `a` should sort after `b`.
|
|
190
|
+
* @returns This query, for chaining.
|
|
227
191
|
*
|
|
228
192
|
* @example
|
|
229
193
|
* ```ts
|
|
@@ -238,17 +202,18 @@ export declare class Query<R extends (typeof Component)[] = []> {
|
|
|
238
202
|
[K in keyof J]: MaybeRequired<J[K], R>;
|
|
239
203
|
}) => number): this;
|
|
240
204
|
/**
|
|
241
|
-
* Set the entity
|
|
205
|
+
* Set the entity-membership predicate using a {@link QueryDSL} expression.
|
|
242
206
|
*
|
|
243
|
-
* Replaces any previous predicate. The optional `
|
|
244
|
-
* pure type-level hint: it tells {@link sort}
|
|
245
|
-
*
|
|
246
|
-
* those positions. It has no
|
|
207
|
+
* Replaces any previous predicate. The optional `_guaranteed` tuple is a
|
|
208
|
+
* pure type-level hint: it tells {@link sort} / {@link forEach} /
|
|
209
|
+
* {@link update} callbacks which components are guaranteed present on every
|
|
210
|
+
* matched entity, eliminating `| undefined` from those positions. It has no
|
|
211
|
+
* effect at runtime.
|
|
247
212
|
*
|
|
248
|
-
* @param q -
|
|
213
|
+
* @param q - Query expression.
|
|
249
214
|
* @param _guaranteed - Component classes guaranteed present on every matched
|
|
250
215
|
* entity (type hint only — not validated at runtime).
|
|
251
|
-
* @returns
|
|
216
|
+
* @returns This query, retyped with the guaranteed tuple as its `R`.
|
|
252
217
|
*
|
|
253
218
|
* @example
|
|
254
219
|
* ```ts
|
|
@@ -261,28 +226,26 @@ export declare class Query<R extends (typeof Component)[] = []> {
|
|
|
261
226
|
*/
|
|
262
227
|
query<T extends (typeof Component)[] = []>(q: QueryDSL, _guaranteed?: readonly [...T]): Query<T>;
|
|
263
228
|
/**
|
|
264
|
-
*
|
|
229
|
+
* Shorthand for `query([...components])`: track entities that have **all**
|
|
230
|
+
* of the listed component types.
|
|
265
231
|
*
|
|
266
|
-
*
|
|
267
|
-
*
|
|
268
|
-
*
|
|
232
|
+
* Equivalent to `query({ HAS: components })`. Unlike `query`, the listed
|
|
233
|
+
* components are also recorded in the type parameter `R`, so {@link sort}
|
|
234
|
+
* and {@link forEach} callbacks see them as non-nullable.
|
|
269
235
|
*
|
|
270
|
-
*
|
|
236
|
+
* @param components - Component classes to require.
|
|
237
|
+
* @returns This query, retyped with the required tuple as its `R`.
|
|
271
238
|
*/
|
|
272
|
-
|
|
239
|
+
requires<T extends (typeof Component)[]>(...components: [...T]): Query<T>;
|
|
273
240
|
/**
|
|
274
|
-
*
|
|
275
|
-
* **all** of the listed component types.
|
|
241
|
+
* Permanently remove this query from the world.
|
|
276
242
|
*
|
|
277
|
-
*
|
|
278
|
-
*
|
|
279
|
-
*
|
|
243
|
+
* Every entity that currently belongs to this query has the membership
|
|
244
|
+
* silently purged (no `exit` callbacks fire), the tracked set is cleared,
|
|
245
|
+
* and the `world` reference is forced to `undefined`. Calling any method on
|
|
246
|
+
* the query afterwards is **undefined behavior**.
|
|
280
247
|
*
|
|
281
|
-
* @
|
|
282
|
-
* @returns `this` for chaining.
|
|
248
|
+
* Not supported on {@link System} — calling it on a system throws.
|
|
283
249
|
*/
|
|
284
|
-
|
|
285
|
-
private getComponent;
|
|
286
|
-
private getInjected;
|
|
287
|
-
private mapInjectedClassToTypes;
|
|
250
|
+
destroy(): void;
|
|
288
251
|
}
|