@vworlds/vecs 1.0.10 → 1.0.12
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 +299 -228
- 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 +2 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/package.json +3 -1
- package/dist/phase.d.ts +12 -30
- 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 +170 -86
- package/dist/system.js +253 -114
- package/dist/system.js.map +1 -1
- package/dist/timer.d.ts +50 -0
- package/dist/timer.js +154 -0
- package/dist/timer.js.map +1 -0
- 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 +230 -218
- package/dist/world.js +422 -327
- 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,42 +1,49 @@
|
|
|
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
43
|
this.world.defer(() => {
|
|
37
44
|
if (typeof componentsOrCallback === "function") {
|
|
38
45
|
this.world.entities.forEach((e) => {
|
|
39
|
-
if (this.
|
|
46
|
+
if (this._belongs(e)) {
|
|
40
47
|
componentsOrCallback(e);
|
|
41
48
|
}
|
|
42
49
|
});
|
|
@@ -44,7 +51,7 @@ export class Filter {
|
|
|
44
51
|
else {
|
|
45
52
|
const types = componentsOrCallback.map((C) => this.world.getComponentType(C));
|
|
46
53
|
this.world.entities.forEach((e) => {
|
|
47
|
-
if (!this.
|
|
54
|
+
if (!this._belongs(e)) {
|
|
48
55
|
return;
|
|
49
56
|
}
|
|
50
57
|
const resolved = types.map((t) => e.get(t));
|
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
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
export { type System } from "./system.js";
|
|
1
|
+
export { type System, type SystemQuery } from "./system.js";
|
|
2
2
|
export { Query } from "./query.js";
|
|
3
3
|
export { World } from "./world.js";
|
|
4
4
|
export { Filter } from "./filter.js";
|
|
5
5
|
export { Component, type ComponentMeta } from "./component.js";
|
|
6
6
|
export { type Entity } from "./entity.js";
|
|
7
7
|
export { type IPhase } from "./phase.js";
|
|
8
|
+
export { IntervalTickSource, RateTickSource, type ITickSource } from "./timer.js";
|
|
8
9
|
export { Bitset } from "./util/bitset.js";
|
package/dist/index.js
CHANGED
|
@@ -2,5 +2,6 @@ export { Query } from "./query.js";
|
|
|
2
2
|
export { World } from "./world.js";
|
|
3
3
|
export { Filter } from "./filter.js";
|
|
4
4
|
export { Component } from "./component.js";
|
|
5
|
+
export { IntervalTickSource, RateTickSource } from "./timer.js";
|
|
5
6
|
export { Bitset } from "./util/bitset.js";
|
|
6
7
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,SAAS,EAAsB,MAAM,gBAAgB,CAAC;AAG/D,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,SAAS,EAAsB,MAAM,gBAAgB,CAAC;AAG/D,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAoB,MAAM,YAAY,CAAC;AAClF,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC"}
|
package/dist/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vworlds/vecs",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.12",
|
|
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");
|
|
@@ -35,13 +12,18 @@ export declare class Phase {
|
|
|
35
12
|
* world.system("NetworkUpdate").phase(preUpdate).run(tick);
|
|
36
13
|
*
|
|
37
14
|
* // each frame:
|
|
38
|
-
* world.
|
|
39
|
-
*
|
|
15
|
+
* world.beginFrame(now, delta);
|
|
16
|
+
* try {
|
|
17
|
+
* world.runPhase(preUpdate, now, delta);
|
|
18
|
+
* world.runPhase(send, now, delta);
|
|
19
|
+
* } finally {
|
|
20
|
+
* world.endFrame();
|
|
21
|
+
* }
|
|
40
22
|
* ```
|
|
41
23
|
*/
|
|
42
24
|
export interface IPhase {
|
|
43
|
-
/**
|
|
25
|
+
/** Name this phase was registered under. */
|
|
44
26
|
get name(): string;
|
|
45
|
-
/**
|
|
27
|
+
/** World that owns this phase. */
|
|
46
28
|
get world(): World;
|
|
47
29
|
}
|
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":"AAgCA;;;;;;;;;;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"}
|