@vworlds/vecs 1.0.9 → 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/.husky/pre-commit +1 -0
- package/README.md +218 -229
- package/dist/command.d.ts +1 -0
- package/dist/command.js +2 -0
- package/dist/command.js.map +1 -0
- 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 +110 -127
- package/dist/entity.js +323 -164
- package/dist/entity.js.map +1 -1
- package/dist/filter.d.ts +31 -23
- package/dist/filter.js +41 -32
- 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 +128 -94
- package/dist/query.js +254 -145
- package/dist/query.js.map +1 -1
- package/dist/system.d.ts +64 -128
- package/dist/system.js +156 -149
- 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 +222 -201
- package/dist/world.js +394 -323
- 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/filter.d.ts
CHANGED
|
@@ -5,49 +5,57 @@ import { type MaybeRequired, type QueryDSL } from "./dsl.js";
|
|
|
5
5
|
/**
|
|
6
6
|
* A non-reactive, one-shot entity filter.
|
|
7
7
|
*
|
|
8
|
-
* Unlike {@link Query}
|
|
9
|
-
* nothing
|
|
10
|
-
* and invokes the callback
|
|
11
|
-
* construction time.
|
|
8
|
+
* Unlike {@link Query} a `Filter` keeps no tracked entity set and registers
|
|
9
|
+
* nothing on the world. Each call to {@link forEach} walks all current world
|
|
10
|
+
* entities and invokes the callback on those that match the predicate captured
|
|
11
|
+
* at construction time.
|
|
12
12
|
*
|
|
13
|
-
* Create
|
|
13
|
+
* Create one through {@link World.filter}:
|
|
14
14
|
*
|
|
15
15
|
* ```ts
|
|
16
16
|
* const f = world.filter([Position, Velocity]);
|
|
17
17
|
*
|
|
18
|
-
* //
|
|
18
|
+
* // Iterate matching entities:
|
|
19
19
|
* f.forEach((e) => console.log(e.eid));
|
|
20
20
|
*
|
|
21
|
-
* //
|
|
21
|
+
* // ...or with component injection:
|
|
22
22
|
* f.forEach([Position, Velocity], (e, [pos, vel]) => {
|
|
23
23
|
* pos.x += vel.vx;
|
|
24
24
|
* });
|
|
25
25
|
* ```
|
|
26
26
|
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
27
|
+
* `forEach` runs the callback inside a {@link World.defer | deferred scope}, so
|
|
28
|
+
* mutations made by the callback are batched and become visible after iteration
|
|
29
|
+
* finishes. Nesting a `forEach` inside an already-deferred block (a system, a
|
|
30
|
+
* `Query.forEach`, an outer `defer`) inherits the outer scope and does not
|
|
31
|
+
* drain on exit.
|
|
32
|
+
*
|
|
33
|
+
* @typeParam R - Component classes guaranteed present on every matched entity.
|
|
34
|
+
* Inferred from the DSL by {@link World.filter} when possible, or supplied
|
|
35
|
+
* manually via the `_guaranteed` argument. Components in `R` are non-nullable
|
|
36
|
+
* in `forEach` callback tuples.
|
|
32
37
|
*/
|
|
33
38
|
export declare class Filter<R extends (typeof Component)[] = []> {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
39
|
+
/** World this filter reads entities from. */
|
|
40
|
+
readonly world: World;
|
|
41
|
+
private readonly _belongs;
|
|
42
|
+
constructor(
|
|
43
|
+
/** World this filter reads entities from. */
|
|
44
|
+
world: World, dsl: QueryDSL);
|
|
37
45
|
/**
|
|
38
|
-
*
|
|
39
|
-
* the
|
|
46
|
+
* Walk all current world entities and call `callback` for each one that
|
|
47
|
+
* satisfies the filter's DSL.
|
|
40
48
|
*
|
|
41
|
-
* @param callback - Receives only the entity.
|
|
49
|
+
* @param callback - Receives only the matching entity.
|
|
42
50
|
*/
|
|
43
51
|
forEach(callback: (e: Entity) => void): void;
|
|
44
52
|
/**
|
|
45
|
-
*
|
|
46
|
-
* the DSL,
|
|
53
|
+
* Walk all current world entities, call `callback` for each one that
|
|
54
|
+
* satisfies the filter's DSL, and inject the requested component instances.
|
|
47
55
|
*
|
|
48
|
-
* Components
|
|
49
|
-
* non-nullable in the resolved tuple; any other
|
|
50
|
-
* `undefined` if the entity
|
|
56
|
+
* Components covered by the filter's DSL or `_guaranteed` hint are
|
|
57
|
+
* non-nullable in the resolved tuple; any other component class may be
|
|
58
|
+
* `undefined` if the entity does not have it.
|
|
51
59
|
*
|
|
52
60
|
* @param components - Component classes to resolve from each matching entity.
|
|
53
61
|
* @param callback - Receives the entity and a tuple of resolved component
|
package/dist/filter.js
CHANGED
|
@@ -1,55 +1,64 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { _buildEntityTest } from "./dsl.js";
|
|
2
2
|
/**
|
|
3
3
|
* A non-reactive, one-shot entity filter.
|
|
4
4
|
*
|
|
5
|
-
* Unlike {@link Query}
|
|
6
|
-
* nothing
|
|
7
|
-
* and invokes the callback
|
|
8
|
-
* construction time.
|
|
5
|
+
* Unlike {@link Query} a `Filter` keeps no tracked entity set and registers
|
|
6
|
+
* nothing on the world. Each call to {@link forEach} walks all current world
|
|
7
|
+
* entities and invokes the callback on those that match the predicate captured
|
|
8
|
+
* at construction time.
|
|
9
9
|
*
|
|
10
|
-
* Create
|
|
10
|
+
* Create one through {@link World.filter}:
|
|
11
11
|
*
|
|
12
12
|
* ```ts
|
|
13
13
|
* const f = world.filter([Position, Velocity]);
|
|
14
14
|
*
|
|
15
|
-
* //
|
|
15
|
+
* // Iterate matching entities:
|
|
16
16
|
* f.forEach((e) => console.log(e.eid));
|
|
17
17
|
*
|
|
18
|
-
* //
|
|
18
|
+
* // ...or with component injection:
|
|
19
19
|
* f.forEach([Position, Velocity], (e, [pos, vel]) => {
|
|
20
20
|
* pos.x += vel.vx;
|
|
21
21
|
* });
|
|
22
22
|
* ```
|
|
23
23
|
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
24
|
+
* `forEach` runs the callback inside a {@link World.defer | deferred scope}, so
|
|
25
|
+
* mutations made by the callback are batched and become visible after iteration
|
|
26
|
+
* finishes. Nesting a `forEach` inside an already-deferred block (a system, a
|
|
27
|
+
* `Query.forEach`, an outer `defer`) inherits the outer scope and does not
|
|
28
|
+
* drain on exit.
|
|
29
|
+
*
|
|
30
|
+
* @typeParam R - Component classes guaranteed present on every matched entity.
|
|
31
|
+
* Inferred from the DSL by {@link World.filter} when possible, or supplied
|
|
32
|
+
* manually via the `_guaranteed` argument. Components in `R` are non-nullable
|
|
33
|
+
* in `forEach` callback tuples.
|
|
29
34
|
*/
|
|
30
35
|
export class Filter {
|
|
31
|
-
constructor(
|
|
36
|
+
constructor(
|
|
37
|
+
/** World this filter reads entities from. */
|
|
38
|
+
world, dsl) {
|
|
32
39
|
this.world = world;
|
|
33
|
-
this.
|
|
40
|
+
this._belongs = _buildEntityTest(world, dsl);
|
|
34
41
|
}
|
|
35
42
|
forEach(componentsOrCallback, callback) {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
43
|
+
this.world.defer(() => {
|
|
44
|
+
if (typeof componentsOrCallback === "function") {
|
|
45
|
+
this.world.entities.forEach((e) => {
|
|
46
|
+
if (this._belongs(e)) {
|
|
47
|
+
componentsOrCallback(e);
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
const types = componentsOrCallback.map((C) => this.world.getComponentType(C));
|
|
53
|
+
this.world.entities.forEach((e) => {
|
|
54
|
+
if (!this._belongs(e)) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
const resolved = types.map((t) => e.get(t));
|
|
58
|
+
callback(e, resolved);
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
});
|
|
53
62
|
}
|
|
54
63
|
}
|
|
55
64
|
//# sourceMappingURL=filter.js.map
|
package/dist/filter.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filter.js","sourceRoot":"","sources":["../src/filter.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"filter.js","sourceRoot":"","sources":["../src/filter.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,gBAAgB,EAA0D,MAAM,UAAU,CAAC;AAEpG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,MAAM,OAAO,MAAM;IAGjB;IACE,6CAA6C;IAC7B,KAAY,EAC5B,GAAa;QADG,UAAK,GAAL,KAAK,CAAO;QAG5B,IAAI,CAAC,QAAQ,GAAG,gBAAgB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAC/C,CAAC;IA2BM,OAAO,CACZ,oBAA6D,EAC7D,QAAoF;QAEpF,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE;YACpB,IAAI,OAAO,oBAAoB,KAAK,UAAU,EAAE;gBAC9C,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE;oBAChC,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE;wBACpB,oBAAoB,CAAC,CAAC,CAAC,CAAC;qBACzB;gBACH,CAAC,CAAC,CAAC;aACJ;iBAAM;gBACL,MAAM,KAAK,GAAG,oBAAoB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC9E,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE;oBAChC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE;wBACrB,OAAO;qBACR;oBACD,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;oBAC5C,QAAS,CAAC,CAAC,EAAE,QAAe,CAAC,CAAC;gBAChC,CAAC,CAAC,CAAC;aACJ;QACH,CAAC,CAAC,CAAC;IACL,CAAC;CACF"}
|
package/dist/index.d.ts
CHANGED
package/dist/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vworlds/vecs",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.11",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"type": "module",
|
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
"test": "vitest run",
|
|
13
13
|
"test:watch": "vitest",
|
|
14
14
|
"lint": "eslint src/ tests/",
|
|
15
|
+
"typecheck": "tsc --noEmit",
|
|
16
|
+
"format:check": "prettier --check \"**/*.{ts,md}\"",
|
|
15
17
|
"prepare": "husky"
|
|
16
18
|
},
|
|
17
19
|
"devDependencies": {
|
package/dist/phase.d.ts
CHANGED
|
@@ -1,32 +1,9 @@
|
|
|
1
|
-
import { type System } from "./system.js";
|
|
2
1
|
import { type World } from "./world.js";
|
|
3
2
|
/**
|
|
4
|
-
*
|
|
5
|
-
* update pipeline.
|
|
3
|
+
* Public interface for a pipeline phase, returned by {@link World.addPhase}.
|
|
6
4
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* pending archetype changes, so `enter` / `exit` callbacks are always
|
|
10
|
-
* delivered before the next system executes.
|
|
11
|
-
*
|
|
12
|
-
* @internal The concrete class is not part of the public API. Use
|
|
13
|
-
* {@link IPhase} to refer to phases in user code.
|
|
14
|
-
*/
|
|
15
|
-
export declare class Phase {
|
|
16
|
-
/** Name used to look up the phase in the pipeline. */
|
|
17
|
-
readonly name: string;
|
|
18
|
-
world: World;
|
|
19
|
-
/** Systems that belong to this phase, in execution order. */
|
|
20
|
-
systems: System[];
|
|
21
|
-
constructor(
|
|
22
|
-
/** Name used to look up the phase in the pipeline. */
|
|
23
|
-
name: string, world: World);
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* Public interface for a pipeline phase returned by {@link World.addPhase}.
|
|
27
|
-
*
|
|
28
|
-
* Pass an `IPhase` to {@link System.phase} to assign a system to that phase,
|
|
29
|
-
* or to {@link World.runPhase} to execute it:
|
|
5
|
+
* Pass an `IPhase` to {@link System.phase} to assign a system to the phase, or
|
|
6
|
+
* to {@link World.runPhase} to execute the phase:
|
|
30
7
|
*
|
|
31
8
|
* ```ts
|
|
32
9
|
* const preUpdate = world.addPhase("preupdate");
|
|
@@ -40,8 +17,8 @@ export declare class Phase {
|
|
|
40
17
|
* ```
|
|
41
18
|
*/
|
|
42
19
|
export interface IPhase {
|
|
43
|
-
/**
|
|
20
|
+
/** Name this phase was registered under. */
|
|
44
21
|
get name(): string;
|
|
45
|
-
/**
|
|
22
|
+
/** World that owns this phase. */
|
|
46
23
|
get world(): World;
|
|
47
24
|
}
|
package/dist/phase.js
CHANGED
|
@@ -1,22 +1,23 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* update pipeline.
|
|
2
|
+
* Concrete implementation of {@link IPhase}: a named, ordered bucket of
|
|
3
|
+
* {@link System | systems} within a world's update pipeline.
|
|
4
4
|
*
|
|
5
|
-
* Created
|
|
6
|
-
* the
|
|
7
|
-
*
|
|
8
|
-
* delivered before the next system executes.
|
|
5
|
+
* Created by {@link World.addPhase}. Systems run in the order they were added
|
|
6
|
+
* to the phase. Between systems the world drains pending commands so each
|
|
7
|
+
* system observes a consistent view of the world.
|
|
9
8
|
*
|
|
10
|
-
* @internal The
|
|
11
|
-
*
|
|
9
|
+
* @internal The class itself is not part of the public API; user code should
|
|
10
|
+
* refer to phases via {@link IPhase}.
|
|
12
11
|
*/
|
|
13
12
|
export class Phase {
|
|
14
13
|
constructor(
|
|
15
14
|
/** Name used to look up the phase in the pipeline. */
|
|
16
|
-
name,
|
|
15
|
+
name,
|
|
16
|
+
/** World that owns this phase. */
|
|
17
|
+
world) {
|
|
17
18
|
this.name = name;
|
|
18
19
|
this.world = world;
|
|
19
|
-
/** Systems
|
|
20
|
+
/** Systems registered in this phase, in execution order. */
|
|
20
21
|
this.systems = [];
|
|
21
22
|
}
|
|
22
23
|
}
|
package/dist/phase.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"phase.js","sourceRoot":"","sources":["../src/phase.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"phase.js","sourceRoot":"","sources":["../src/phase.ts"],"names":[],"mappings":"AA2BA;;;;;;;;;;GAUG;AACH,MAAM,OAAO,KAAK;IAIhB;IACE,sDAAsD;IACtC,IAAY;IAC5B,kCAAkC;IAClB,KAAY;QAFZ,SAAI,GAAJ,IAAI,CAAQ;QAEZ,UAAK,GAAL,KAAK,CAAO;QAP9B,4DAA4D;QACrD,YAAO,GAAa,EAAE,CAAC;IAO3B,CAAC;CACL"}
|
package/dist/query.d.ts
CHANGED
|
@@ -3,81 +3,87 @@ import type { Entity } from "./entity.js";
|
|
|
3
3
|
import { type World } from "./world.js";
|
|
4
4
|
import { type EntityTestFunc, type QueryDSL, type MaybeRequired } from "./dsl.js";
|
|
5
5
|
export type { EntityTestFunc, QueryDSL, MaybeRequired };
|
|
6
|
-
|
|
6
|
+
/** Component class, or `{ parent: ComponentClass }` to resolve from the entity's parent. */
|
|
7
7
|
type ComponentOrParent = typeof Component | {
|
|
8
8
|
parent: typeof Component;
|
|
9
9
|
};
|
|
10
|
+
/** Resolves the component instance type for one element of a `ComponentOrParent` tuple. */
|
|
10
11
|
type ComponentInstance<T> = T extends {
|
|
11
12
|
parent: typeof Component;
|
|
12
13
|
} ? InstanceType<T["parent"]> : T extends typeof Component ? InstanceType<T> : never;
|
|
13
14
|
/**
|
|
14
|
-
* A reactive, always-
|
|
15
|
-
*
|
|
15
|
+
* A reactive, always-up-to-date set of entities matching a {@link QueryDSL}
|
|
16
|
+
* predicate.
|
|
16
17
|
*
|
|
17
|
-
* `Query`
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
* 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}.
|
|
21
22
|
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
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.
|
|
25
26
|
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
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.
|
|
30
35
|
*/
|
|
31
36
|
export declare class Query<R extends (typeof Component)[] = []> {
|
|
32
|
-
/** Unique name
|
|
37
|
+
/** Unique display name; appears in logs and debug output. */
|
|
33
38
|
readonly name: string;
|
|
34
|
-
/**
|
|
39
|
+
/** World that owns this query. */
|
|
35
40
|
readonly world: World;
|
|
36
|
-
protected _entities: Set<Entity> | undefined;
|
|
37
|
-
protected _enterCallback: EntityCallback[];
|
|
38
|
-
protected _exitCallback: EntityCallback[];
|
|
39
|
-
protected _belongs: EntityTestFunc;
|
|
40
|
-
protected hasQuery: boolean;
|
|
41
41
|
constructor(
|
|
42
|
-
/** Unique name
|
|
42
|
+
/** Unique display name; appears in logs and debug output. */
|
|
43
43
|
name: string,
|
|
44
|
-
/**
|
|
44
|
+
/** World that owns this query. */
|
|
45
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>;
|
|
46
55
|
/** Returns the query name. */
|
|
47
56
|
toString(): string;
|
|
48
57
|
/**
|
|
49
58
|
* Enable entity tracking: matched entities are inserted into {@link entities}
|
|
50
59
|
* as they enter and removed as they exit.
|
|
51
60
|
*
|
|
52
|
-
* Idempotent. When called after {@link World.start}, immediately backfills
|
|
53
|
-
* existing
|
|
61
|
+
* Idempotent. When called after {@link World.start}, immediately backfills
|
|
62
|
+
* every existing entity that satisfies the current predicate.
|
|
54
63
|
*
|
|
55
|
-
* @returns
|
|
64
|
+
* @returns This query, for chaining.
|
|
56
65
|
*/
|
|
57
66
|
track(): this;
|
|
58
|
-
|
|
67
|
+
/** Returns `true` when `e` satisfies this query's predicate. */
|
|
68
|
+
belongs(e: Entity): boolean;
|
|
59
69
|
/**
|
|
60
|
-
*
|
|
70
|
+
* Iterate every entity currently tracked by this query.
|
|
61
71
|
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
|
|
66
|
-
get entities(): ReadonlySet<Entity>;
|
|
67
|
-
/**
|
|
68
|
-
* Iterate over every entity currently tracked by this query.
|
|
72
|
+
* Mutations made by `callback` are buffered into the world command queue
|
|
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.
|
|
69
76
|
*
|
|
70
|
-
* @param callback -
|
|
77
|
+
* @param callback - Invoked once per tracked entity, in insertion order
|
|
71
78
|
* (or sort order when {@link sort} is configured).
|
|
72
79
|
*/
|
|
73
80
|
forEach(callback: (e: Entity) => void): void;
|
|
74
81
|
/**
|
|
75
|
-
* Iterate
|
|
76
|
-
* injection.
|
|
82
|
+
* Iterate every tracked entity with component injection.
|
|
77
83
|
*
|
|
78
|
-
* Components
|
|
79
|
-
* {@link query}) are non-nullable in the resolved tuple; any other
|
|
80
|
-
* 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.
|
|
81
87
|
*
|
|
82
88
|
* @param components - Component classes to resolve from each entity.
|
|
83
89
|
* @param callback - Receives the entity and a tuple of resolved component
|
|
@@ -86,22 +92,14 @@ export declare class Query<R extends (typeof Component)[] = []> {
|
|
|
86
92
|
forEach<J extends (typeof Component)[]>(components: readonly [...J], callback: (e: Entity, resolved: {
|
|
87
93
|
[K in keyof J]: MaybeRequired<J[K], R>;
|
|
88
94
|
}) => void): void;
|
|
89
|
-
/** Returns `true` if the entity satisfies this query's predicate. */
|
|
90
|
-
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. */
|
|
94
|
-
_enter(e: Entity): void;
|
|
95
|
-
/** @internal Fires exit callbacks and removes entity from the tracked set. */
|
|
96
|
-
_exit(e: Entity): void;
|
|
97
95
|
/**
|
|
98
|
-
* Register a callback
|
|
99
|
-
*
|
|
96
|
+
* Register a callback invoked when an entity **enters** this query (i.e.
|
|
97
|
+
* first satisfies the predicate), with injected components.
|
|
100
98
|
*
|
|
101
99
|
* @param inject - Ordered list of component classes (or `{ parent: C }`) to
|
|
102
100
|
* resolve from the entering entity and pass to `callback`.
|
|
103
101
|
* @param callback - Receives the entity and the resolved component tuple.
|
|
104
|
-
* @returns
|
|
102
|
+
* @returns This query, for chaining.
|
|
105
103
|
*
|
|
106
104
|
* @example
|
|
107
105
|
* ```ts
|
|
@@ -115,44 +113,81 @@ export declare class Query<R extends (typeof Component)[] = []> {
|
|
|
115
113
|
[K in keyof J]: ComponentInstance<J[K]>;
|
|
116
114
|
}) => void): this;
|
|
117
115
|
/**
|
|
118
|
-
* Register
|
|
116
|
+
* Register an `enter` callback without component injection.
|
|
119
117
|
*
|
|
120
|
-
* @param callback - Receives only the entity
|
|
121
|
-
* @returns
|
|
118
|
+
* @param callback - Receives only the entering entity.
|
|
119
|
+
* @returns This query, for chaining.
|
|
122
120
|
*/
|
|
123
121
|
enter(callback: (e: Entity) => void): this;
|
|
124
122
|
/**
|
|
125
|
-
* Register a callback
|
|
126
|
-
*
|
|
123
|
+
* Register a callback invoked when an entity **exits** this query (its
|
|
124
|
+
* archetype no longer satisfies the predicate, or it was destroyed), with
|
|
127
125
|
* injected components.
|
|
128
126
|
*
|
|
129
|
-
* Components
|
|
130
|
-
*
|
|
131
|
-
* longer in the entity's active component set.
|
|
127
|
+
* Components removed in the same frame as the exit are still resolvable
|
|
128
|
+
* because the runtime snapshots them at routing time.
|
|
132
129
|
*
|
|
133
130
|
* @param inject - Component classes to resolve and inject.
|
|
134
131
|
* @param callback - Receives the entity and the resolved component tuple.
|
|
135
|
-
* @returns
|
|
132
|
+
* @returns This query, for chaining.
|
|
136
133
|
*/
|
|
137
134
|
exit<J extends ComponentOrParent[]>(inject: readonly [...J], callback: (e: Entity, injected: {
|
|
138
135
|
[K in keyof J]: ComponentInstance<J[K]>;
|
|
139
136
|
}) => void): this;
|
|
140
137
|
/**
|
|
141
|
-
* Register
|
|
138
|
+
* Register an `exit` callback without component injection.
|
|
142
139
|
*
|
|
143
|
-
* @param callback - Receives only the entity.
|
|
144
|
-
* @returns
|
|
140
|
+
* @param callback - Receives only the exiting entity.
|
|
141
|
+
* @returns This query, for chaining.
|
|
145
142
|
*/
|
|
146
143
|
exit(callback: (e: Entity) => void): this;
|
|
147
144
|
/**
|
|
148
|
-
*
|
|
149
|
-
*
|
|
150
|
-
*
|
|
145
|
+
* Register a callback invoked when a component of `ComponentClass` is
|
|
146
|
+
* modified on a tracked entity.
|
|
147
|
+
*
|
|
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`.
|
|
152
|
+
*
|
|
153
|
+
* If no other predicate has been set on this query, the watchlist
|
|
154
|
+
* automatically expands so `ComponentClass` is implicitly required (the
|
|
155
|
+
* predicate becomes a `HAS` of every watched type).
|
|
156
|
+
*
|
|
157
|
+
* @param ComponentClass - Component class to watch.
|
|
158
|
+
* @param callback - Receives the modified component instance.
|
|
159
|
+
* @returns This query, for chaining.
|
|
160
|
+
*
|
|
161
|
+
* @example
|
|
162
|
+
* ```ts
|
|
163
|
+
* world.system("RenderPosition")
|
|
164
|
+
* .update(Position, (pos) => sprite.setPosition(pos.x, pos.y));
|
|
165
|
+
* ```
|
|
166
|
+
*/
|
|
167
|
+
update<C extends typeof Component>(ComponentClass: C, callback: (c: InstanceType<C>) => void): this;
|
|
168
|
+
/**
|
|
169
|
+
* Like {@link update}, but with extra components injected from the same
|
|
170
|
+
* entity.
|
|
171
|
+
*
|
|
172
|
+
* @param ComponentClass - Component class to watch.
|
|
173
|
+
* @param inject - Additional component classes to resolve from the entity.
|
|
174
|
+
* @param callback - Receives the modified component and the injected tuple.
|
|
175
|
+
* @returns This query, for chaining.
|
|
176
|
+
*/
|
|
177
|
+
update<C extends typeof Component, J extends (typeof Component)[]>(ComponentClass: C, inject: readonly [...J], callback: (c: InstanceType<C>, injected: {
|
|
178
|
+
[K in keyof J]: MaybeRequired<J[K], R>;
|
|
179
|
+
}) => void): this;
|
|
180
|
+
/**
|
|
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}.
|
|
151
186
|
*
|
|
152
187
|
* @param components - Component classes to resolve and pass to `compare`.
|
|
153
|
-
* @param compare -
|
|
154
|
-
* `a` should sort
|
|
155
|
-
* @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.
|
|
156
191
|
*
|
|
157
192
|
* @example
|
|
158
193
|
* ```ts
|
|
@@ -167,17 +202,18 @@ export declare class Query<R extends (typeof Component)[] = []> {
|
|
|
167
202
|
[K in keyof J]: MaybeRequired<J[K], R>;
|
|
168
203
|
}) => number): this;
|
|
169
204
|
/**
|
|
170
|
-
* Set the entity
|
|
205
|
+
* Set the entity-membership predicate using a {@link QueryDSL} expression.
|
|
171
206
|
*
|
|
172
|
-
* Replaces any previous predicate. The optional `
|
|
173
|
-
* pure type-level hint: it tells {@link sort}
|
|
174
|
-
*
|
|
175
|
-
* 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.
|
|
176
212
|
*
|
|
177
|
-
* @param q -
|
|
213
|
+
* @param q - Query expression.
|
|
178
214
|
* @param _guaranteed - Component classes guaranteed present on every matched
|
|
179
215
|
* entity (type hint only — not validated at runtime).
|
|
180
|
-
* @returns
|
|
216
|
+
* @returns This query, retyped with the guaranteed tuple as its `R`.
|
|
181
217
|
*
|
|
182
218
|
* @example
|
|
183
219
|
* ```ts
|
|
@@ -190,28 +226,26 @@ export declare class Query<R extends (typeof Component)[] = []> {
|
|
|
190
226
|
*/
|
|
191
227
|
query<T extends (typeof Component)[] = []>(q: QueryDSL, _guaranteed?: readonly [...T]): Query<T>;
|
|
192
228
|
/**
|
|
193
|
-
*
|
|
229
|
+
* Shorthand for `query([...components])`: track entities that have **all**
|
|
230
|
+
* of the listed component types.
|
|
194
231
|
*
|
|
195
|
-
*
|
|
196
|
-
*
|
|
197
|
-
*
|
|
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.
|
|
198
235
|
*
|
|
199
|
-
*
|
|
236
|
+
* @param components - Component classes to require.
|
|
237
|
+
* @returns This query, retyped with the required tuple as its `R`.
|
|
200
238
|
*/
|
|
201
|
-
|
|
239
|
+
requires<T extends (typeof Component)[]>(...components: [...T]): Query<T>;
|
|
202
240
|
/**
|
|
203
|
-
*
|
|
204
|
-
* **all** of the listed component types.
|
|
241
|
+
* Permanently remove this query from the world.
|
|
205
242
|
*
|
|
206
|
-
*
|
|
207
|
-
*
|
|
208
|
-
*
|
|
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**.
|
|
209
247
|
*
|
|
210
|
-
* @
|
|
211
|
-
* @returns `this` for chaining.
|
|
248
|
+
* Not supported on {@link System} — calling it on a system throws.
|
|
212
249
|
*/
|
|
213
|
-
|
|
214
|
-
private getComponent;
|
|
215
|
-
private getInjected;
|
|
216
|
-
private mapInjectedClassToTypes;
|
|
250
|
+
destroy(): void;
|
|
217
251
|
}
|