@vworlds/vecs 1.0.54 → 1.0.55
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 +9 -0
- package/dist/entity/entity.components.js +4 -2
- package/dist/entity/entity.components.js.map +1 -1
- package/dist/entity/entity.lifecycle.d.ts +2 -0
- package/dist/entity/entity.lifecycle.js +9 -4
- package/dist/entity/entity.lifecycle.js.map +1 -1
- package/dist/geometry.d.ts +5 -0
- package/dist/geometry.js +2 -0
- package/dist/geometry.js.map +1 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/package.json +1 -1
- package/dist/system.d.ts +10 -0
- package/dist/system.js +19 -2
- package/dist/system.js.map +1 -1
- package/dist/timer.d.ts +15 -1
- package/dist/timer.js +24 -4
- package/dist/timer.js.map +1 -1
- package/dist/world/destroy-order.d.ts +8 -0
- package/dist/world/destroy-order.js +60 -0
- package/dist/world/destroy-order.js.map +1 -0
- package/dist/world/stats.d.ts +51 -0
- package/dist/world/stats.js +88 -0
- package/dist/world/stats.js.map +1 -0
- package/dist/world/world.base.js +2 -0
- package/dist/world/world.base.js.map +1 -1
- package/dist/world/world.components.d.ts +2 -0
- package/dist/world/world.components.js +4 -0
- package/dist/world/world.components.js.map +1 -1
- package/dist/world/world.disposal.d.ts +34 -36
- package/dist/world/world.disposal.js +89 -94
- package/dist/world/world.disposal.js.map +1 -1
- package/dist/world/world.entities.d.ts +21 -1
- package/dist/world/world.entities.js +54 -7
- package/dist/world/world.entities.js.map +1 -1
- package/dist/world/world.js +17 -11
- package/dist/world/world.js.map +1 -1
- package/dist/world/world.modules.d.ts +8 -0
- package/dist/world/world.modules.js +22 -1
- package/dist/world/world.modules.js.map +1 -1
- package/dist/world/world.pipeline.d.ts +15 -1
- package/dist/world/world.pipeline.js +40 -4
- package/dist/world/world.pipeline.js.map +1 -1
- package/docs/README.md +21 -19
- package/docs/components.md +9 -0
- package/docs/concepts.md +4 -0
- package/docs/design-guide.md +7 -3
- package/docs/entities.md +36 -25
- package/docs/glossary.md +3 -3
- package/docs/modules.md +62 -0
- package/docs/systems.md +108 -2
- package/package.json +1 -1
- package/tsconfig.types.json +6 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"destroy-order.js","sourceRoot":"","sources":["../../src/world/destroy-order.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,QAAkB,EAAE,UAAgB;IAChE,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;IAClC,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAClC,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC3B,KAAK,MAAM,OAAO,IAAI,GAAG,CAAC,IAAI,CAAC,SAAS,IAAI,EAAE,EAAE,CAAC;YAC/C,IAAI,OAAO,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC7C,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YACvB,CAAC;QACH,CAAC;QACD,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;YAC7B,KAAK,MAAM,KAAK,IAAI,GAAG,CAAC,cAAc,CAAC,UAAU,CAAC,IAAI,EAAE,EAAE,CAAC;gBACzD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;oBACxB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;gBACrB,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IACD,IAAI,UAAU,GAAG,IAAI,CAAC;IACtB,OAAO,UAAU,EAAE,CAAC;QAClB,UAAU,GAAG,KAAK,CAAC;QACnB,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;YAC1B,MAAM,MAAM,GAAG,CAAC,SAAiB,EAAW,EAAE,CAC5C,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YACnD,IACE,CAAC,SAAS,CAAC,GAAG,EAAE,MAAM,CAAC;gBACvB,CAAC,UAAU,KAAK,SAAS,IAAI,CAAC,gBAAgB,CAAC,GAAG,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC,EACxE,CAAC;gBACD,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBAClB,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBACpB,UAAU,GAAG,IAAI,CAAC;YACpB,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,SAAS,CAAC,GAAW,EAAE,SAAuC,GAAG,EAAE,CAAC,IAAI;IACtF,KAAK,MAAM,OAAO,IAAI,GAAG,CAAC,IAAI,CAAC,SAAS,IAAI,EAAE,EAAE,CAAC;QAC/C,IAAI,OAAO,KAAK,GAAG,IAAI,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;YACvC,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,yEAAyE;AACzE,SAAS,gBAAgB,CACvB,MAAc,EACd,UAAe,EACf,MAAkC;IAElC,MAAM,QAAQ,GAAG,MAAM,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;IACnD,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,OAAO,KAAK,CAAC;IACf,CAAC;IACD,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;QAC7B,IAAI,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;YAClB,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { System } from "../system.js";
|
|
2
|
+
/** Accumulated synchronous execution time, in milliseconds, since the last reset. */
|
|
3
|
+
export interface Timing {
|
|
4
|
+
/** Number of admitted executions (not entity callbacks). */
|
|
5
|
+
runs: number;
|
|
6
|
+
/** Sum of execution durations in milliseconds. */
|
|
7
|
+
totalMs: number;
|
|
8
|
+
/** Longest execution duration in milliseconds. */
|
|
9
|
+
maxMs: number;
|
|
10
|
+
}
|
|
11
|
+
/** A system's timing; read its identity and cadence from the original system. */
|
|
12
|
+
export interface SystemTiming extends Timing {
|
|
13
|
+
/** The original system, not a descriptor copy. */
|
|
14
|
+
system: System;
|
|
15
|
+
}
|
|
16
|
+
/** A named timing breakdown supplied by a world extension. */
|
|
17
|
+
export interface OperationTiming extends Timing {
|
|
18
|
+
/** Stable operation name, for example `replication:encode`. */
|
|
19
|
+
name: string;
|
|
20
|
+
}
|
|
21
|
+
/** Opt-in world timing. Reading allocates snapshots; ticking reuses slots. */
|
|
22
|
+
export declare class WorldStats {
|
|
23
|
+
private readonly _pipeline;
|
|
24
|
+
private _enabled;
|
|
25
|
+
private readonly _systems;
|
|
26
|
+
private readonly _operations;
|
|
27
|
+
private _generation;
|
|
28
|
+
/** Whether system and extension timing is enabled. Off by default. */
|
|
29
|
+
get systemsEnabled(): boolean;
|
|
30
|
+
/** Stop measuring without discarding accumulated results. */
|
|
31
|
+
disableSystems(): void;
|
|
32
|
+
/** Start measuring systems and extension operations on subsequent ticks. */
|
|
33
|
+
enableSystems(): void;
|
|
34
|
+
/** Read extension-operation snapshots in first-seen order; empty before measurement. */
|
|
35
|
+
operations(): OperationTiming[];
|
|
36
|
+
/**
|
|
37
|
+
* Record one completed extension operation, reusing its first-seen named slot.
|
|
38
|
+
* World extensions select their instrumented path with `systemsEnabled` once
|
|
39
|
+
* per frame, then call this method with a finite, non-negative duration in ms.
|
|
40
|
+
* This method neither reads a clock nor checks the switch again, so an in-flight
|
|
41
|
+
* measured frame can finish even if a callback changes the switch.
|
|
42
|
+
* Throws `RangeError` for a negative or non-finite duration.
|
|
43
|
+
*/
|
|
44
|
+
recordOperation(name: string, elapsedMs: number): void;
|
|
45
|
+
/** Clear all system and operation totals without changing the enabled state. */
|
|
46
|
+
resetSystems(): void;
|
|
47
|
+
/** Read system snapshots in current pipeline order, including zero-run systems. */
|
|
48
|
+
systems(): SystemTiming[];
|
|
49
|
+
private _clear;
|
|
50
|
+
private _operationSlot;
|
|
51
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/** Opt-in world timing. Reading allocates snapshots; ticking reuses slots. */
|
|
2
|
+
export class WorldStats {
|
|
3
|
+
/** @internal Constructed by the owning world. */
|
|
4
|
+
constructor(_pipeline) {
|
|
5
|
+
this._pipeline = _pipeline;
|
|
6
|
+
this._enabled = false;
|
|
7
|
+
this._systems = new WeakMap();
|
|
8
|
+
this._operations = new Map();
|
|
9
|
+
this._generation = 0;
|
|
10
|
+
}
|
|
11
|
+
/** Whether system and extension timing is enabled. Off by default. */
|
|
12
|
+
get systemsEnabled() {
|
|
13
|
+
return this._enabled;
|
|
14
|
+
}
|
|
15
|
+
/** Stop measuring without discarding accumulated results. */
|
|
16
|
+
disableSystems() {
|
|
17
|
+
this._enabled = false;
|
|
18
|
+
}
|
|
19
|
+
/** Start measuring systems and extension operations on subsequent ticks. */
|
|
20
|
+
enableSystems() {
|
|
21
|
+
this._enabled = true;
|
|
22
|
+
}
|
|
23
|
+
/** Read extension-operation snapshots in first-seen order; empty before measurement. */
|
|
24
|
+
operations() {
|
|
25
|
+
return Array.from(this._operations.values(), (slot) => ({ ...slot }));
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Record one completed extension operation, reusing its first-seen named slot.
|
|
29
|
+
* World extensions select their instrumented path with `systemsEnabled` once
|
|
30
|
+
* per frame, then call this method with a finite, non-negative duration in ms.
|
|
31
|
+
* This method neither reads a clock nor checks the switch again, so an in-flight
|
|
32
|
+
* measured frame can finish even if a callback changes the switch.
|
|
33
|
+
* Throws `RangeError` for a negative or non-finite duration.
|
|
34
|
+
*/
|
|
35
|
+
recordOperation(name, elapsedMs) {
|
|
36
|
+
if (!Number.isFinite(elapsedMs) || elapsedMs < 0) {
|
|
37
|
+
throw new RangeError("operation duration must be finite and non-negative");
|
|
38
|
+
}
|
|
39
|
+
this._record(this._operationSlot(name), elapsedMs);
|
|
40
|
+
}
|
|
41
|
+
/** Clear all system and operation totals without changing the enabled state. */
|
|
42
|
+
resetSystems() {
|
|
43
|
+
this._generation++;
|
|
44
|
+
for (const slot of this._operations.values()) {
|
|
45
|
+
this._clear(slot);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/** Read system snapshots in current pipeline order, including zero-run systems. */
|
|
49
|
+
systems() {
|
|
50
|
+
return this._pipeline().map((system) => {
|
|
51
|
+
const { runs, totalMs, maxMs } = this._systemSlot(system);
|
|
52
|
+
return { system, runs, totalMs, maxMs };
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
/** @internal Reuse a slot after the system's first measured or read appearance. */
|
|
56
|
+
_systemSlot(system) {
|
|
57
|
+
let slot = this._systems.get(system);
|
|
58
|
+
if (!slot) {
|
|
59
|
+
slot = { system, runs: 0, totalMs: 0, maxMs: 0, generation: this._generation };
|
|
60
|
+
this._systems.set(system, slot);
|
|
61
|
+
}
|
|
62
|
+
if (slot.generation !== this._generation) {
|
|
63
|
+
this._clear(slot);
|
|
64
|
+
slot.generation = this._generation;
|
|
65
|
+
}
|
|
66
|
+
return slot;
|
|
67
|
+
}
|
|
68
|
+
/** @internal Aggregate a completed execution without allocating. */
|
|
69
|
+
_record(slot, elapsedMs) {
|
|
70
|
+
slot.runs++;
|
|
71
|
+
slot.totalMs += elapsedMs;
|
|
72
|
+
slot.maxMs = Math.max(slot.maxMs, elapsedMs);
|
|
73
|
+
}
|
|
74
|
+
_clear(slot) {
|
|
75
|
+
slot.runs = 0;
|
|
76
|
+
slot.totalMs = 0;
|
|
77
|
+
slot.maxMs = 0;
|
|
78
|
+
}
|
|
79
|
+
_operationSlot(name) {
|
|
80
|
+
let slot = this._operations.get(name);
|
|
81
|
+
if (!slot) {
|
|
82
|
+
slot = { name, runs: 0, totalMs: 0, maxMs: 0 };
|
|
83
|
+
this._operations.set(name, slot);
|
|
84
|
+
}
|
|
85
|
+
return slot;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=stats.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stats.js","sourceRoot":"","sources":["../../src/world/stats.ts"],"names":[],"mappings":"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"}
|
package/dist/world/world.base.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
export class Base {
|
|
2
2
|
constructor() {
|
|
3
|
+
/** @internal Suspend cleanup policies only during dispose's infrastructure pass. */
|
|
4
|
+
this._tearingDownInfrastructure = false;
|
|
3
5
|
/**
|
|
4
6
|
* @internal Per-world registry mapping a component class to its
|
|
5
7
|
* component-entity. The registry is per-world so the lookup stays off the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"world.base.js","sourceRoot":"","sources":["../../src/world/world.base.ts"],"names":[],"mappings":"AAOA,MAAM,OAAO,IAAI;IAAjB;QACE;;;;WAIG;QACa,mBAAc,GAAG,IAAI,GAAG,EAAkB,CAAC;QAE3D;;;WAGG;QACa,uBAAkB,GAAG,IAAI,GAAG,EAAkB,CAAC;QAE/D;;;WAGG;QACa,0BAAqB,GAAG,IAAI,OAAO,EAAkB,CAAC;QAEtE;;;;WAIG;QACI,mBAAc,GAAuB,SAAS,CAAC;QAEtD;;;;WAIG;QACI,mBAAc,GAAuB,SAAS,CAAC;IACxD,CAAC;CAAA"}
|
|
1
|
+
{"version":3,"file":"world.base.js","sourceRoot":"","sources":["../../src/world/world.base.ts"],"names":[],"mappings":"AAOA,MAAM,OAAO,IAAI;IAAjB;QACE,oFAAoF;QAC7E,+BAA0B,GAAG,KAAK,CAAC;QAE1C;;;;WAIG;QACa,mBAAc,GAAG,IAAI,GAAG,EAAkB,CAAC;QAE3D;;;WAGG;QACa,uBAAkB,GAAG,IAAI,GAAG,EAAkB,CAAC;QAE/D;;;WAGG;QACa,0BAAqB,GAAG,IAAI,OAAO,EAAkB,CAAC;QAEtE;;;;WAIG;QACI,mBAAc,GAAuB,SAAS,CAAC;QAEtD;;;;WAIG;QACI,mBAAc,GAAuB,SAAS,CAAC;IACxD,CAAC;CAAA"}
|
|
@@ -11,6 +11,8 @@ export declare class Components extends Entities {
|
|
|
11
11
|
* and its id is drawn from the `"component"` id pool (1–899 by default).
|
|
12
12
|
* Subsequent calls with the same class return the same entity. The same class
|
|
13
13
|
* may be registered independently in multiple worlds.
|
|
14
|
+
* A newly registered definition inherits the current scope parent immediately.
|
|
15
|
+
* Scopes must be entered outside deferred mode. Existing lookups do not reparent it.
|
|
14
16
|
*
|
|
15
17
|
* Pass an explicit numeric `ceid` to pin the component to a server-assigned
|
|
16
18
|
* stable id instead of auto-allocating one.
|
|
@@ -71,6 +71,10 @@ export class Components extends Entities {
|
|
|
71
71
|
const component = new Constructor(this, ceid, ComponentClass);
|
|
72
72
|
this._entities.set(ceid, component);
|
|
73
73
|
this._classRegistry.set(ComponentClass, component);
|
|
74
|
+
const parent = this._scope;
|
|
75
|
+
if (parent !== undefined) {
|
|
76
|
+
component.childOf(parent);
|
|
77
|
+
}
|
|
74
78
|
// Component-definition entities are first-class entities: notify so any
|
|
75
79
|
// live world-rooted query/term picks them up reactively (reflection),
|
|
76
80
|
// exactly like an ordinary `world.entity()`.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"world.components.js","sourceRoot":"","sources":["../../src/world/world.components.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAA2C,MAAM,iBAAiB,CAAC;AAGrF,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAG/C,MAAM,YAAY,GAAG,CAAC,CAAC;AAEvB,MAAM,OAAO,UAAW,SAAQ,QAAQ;
|
|
1
|
+
{"version":3,"file":"world.components.js","sourceRoot":"","sources":["../../src/world/world.components.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,61 +6,59 @@ import type { World } from "./world.js";
|
|
|
6
6
|
* to `Pipeline`.
|
|
7
7
|
*/
|
|
8
8
|
export declare class Disposal extends Transfers {
|
|
9
|
-
/** `true` once {@link dispose} has started:
|
|
9
|
+
/** `true` once {@link dispose} has started: repeated top-level calls are idempotent. */
|
|
10
10
|
private _disposeStarted;
|
|
11
11
|
/**
|
|
12
|
-
* End the world's life: destroy
|
|
12
|
+
* End the world's life: destroy application entities, then all world infrastructure, so the
|
|
13
13
|
* `remove` hooks of the components they carry release what those components own (render
|
|
14
14
|
* objects, handles, timers). Call it when the world is finished — a scene or route change, a
|
|
15
15
|
* hot reload — and drop the reference afterwards.
|
|
16
16
|
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* and
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
* ## What stays
|
|
24
|
-
*
|
|
25
|
-
* The infrastructure the world needs to stay coherent is not destroyed:
|
|
26
|
-
*
|
|
27
|
-
* - component and module entities (every {@link Component}),
|
|
28
|
-
* - the entities behind queries and systems (they carry the {@link Query} component), and
|
|
29
|
-
* - phase entities (they carry the {@link Phase} component).
|
|
30
|
-
*
|
|
31
|
-
* What those entities hold stays too: data stored on a component entity (a singleton set with
|
|
32
|
-
* {@link set}) and any entity they still carry as a component key, which cannot be destroyed
|
|
33
|
-
* while it is in use. Release such data yourself. {@link clearAllEntities} is the full wipe,
|
|
34
|
-
* infrastructure included.
|
|
17
|
+
* Both passes use the existing entity destroy path and fire every component's
|
|
18
|
+
* `remove` hook exactly once. Application cleanup retains ordinary cleanup policies
|
|
19
|
+
* and cascades. Infrastructure teardown suspends cleanup policies: it removes a
|
|
20
|
+
* component from remaining carriers instead of throwing or deleting them, and
|
|
21
|
+
* destroys children explicitly rather than through ChildOf/OwnedTarget cascades.
|
|
35
22
|
*
|
|
36
23
|
* ## Order
|
|
37
24
|
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
25
|
+
* Queued application cleanup finishes before infrastructure teardown starts. Systems and
|
|
26
|
+
* queries go first in the infrastructure pass, then modules in reverse registration
|
|
27
|
+
* order, then the rest. Beyond these priorities the order is unspecified, not a
|
|
28
|
+
* resource dependency contract. Infrastructure carrier cycles are stripped, not
|
|
29
|
+
* reported as survivors. Nothing remains after successful disposal.
|
|
30
|
+
* {@link clearAllEntities} retains its own throwing behavior.
|
|
41
31
|
*
|
|
42
|
-
* ##
|
|
32
|
+
* ## Call site
|
|
43
33
|
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
* the destruction like any `destroy()` in that situation, and the destruction completes when
|
|
50
|
-
* the queue next drains: right after the running system, or at the end of the `defer` block.
|
|
34
|
+
* Call synchronously at top level: not inside {@link progress}, {@link defer}, a command drain
|
|
35
|
+
* or an entity's destroy. A refused call throws before teardown starts, leaving the world
|
|
36
|
+
* usable; call again after the enclosing operation finishes. Ordinary synchronous top-level
|
|
37
|
+
* `add`, `set` and `remove` hooks may call it. Cleanup and commands created by teardown hooks
|
|
38
|
+
* settle before this call returns.
|
|
51
39
|
*
|
|
52
40
|
* ## After disposal
|
|
53
41
|
*
|
|
54
42
|
* A disposed world must not be used again. Nothing enforces it — no other method checks, so
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
43
|
+
* mutations have no disposal guard — but the world has no state left to run on. Calling
|
|
44
|
+
* `dispose()` again at top level does nothing. The call-site rule still applies during teardown.
|
|
45
|
+
* Do not create entities indefinitely from teardown hooks: the final pass repeats while it can
|
|
46
|
+
* destroy more entities. Release resources in `remove` hooks, not system `exit` callbacks,
|
|
47
|
+
* which will not run after teardown. A hook that throws propagates out of
|
|
60
48
|
* the call and leaves the world partial, as it does from any destroy: treat it as a programming
|
|
61
49
|
* error.
|
|
50
|
+
*
|
|
51
|
+
* @throws An `Error` for a forbidden call site before any disposal mutation,
|
|
52
|
+
* an internal-invariant error if infrastructure teardown makes no progress,
|
|
53
|
+
* or an error propagated by a teardown hook. The latter errors leave the world partial.
|
|
62
54
|
*/
|
|
63
55
|
dispose(this: World): void;
|
|
56
|
+
/**
|
|
57
|
+
* Validate the disposal call site before teardown changes any state.
|
|
58
|
+
* Subclasses overriding {@link dispose} must call this before starting their own cleanup.
|
|
59
|
+
* @throws An `Error` inside a frame, deferred scope, command drain or entity destroy.
|
|
60
|
+
*/
|
|
61
|
+
protected _assertDisposalAllowed(): void;
|
|
64
62
|
/**
|
|
65
63
|
* The entities {@link dispose} destroys, in an order that lets every destroy succeed: those the
|
|
66
64
|
* application created, with each one used as a component key after its carriers.
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { Component } from "../component.js";
|
|
2
2
|
import { Phase } from "../modules/pipeline.js";
|
|
3
3
|
import { Query } from "../query/index.js";
|
|
4
|
+
import { Module } from "../module.js";
|
|
5
|
+
import { carriersFirst } from "./destroy-order.js";
|
|
4
6
|
import { Transfers } from "./world.transfers.js";
|
|
5
7
|
/**
|
|
6
8
|
* World teardown. It is a layer of its own rather than a method of `World`, because the layers
|
|
@@ -10,73 +12,117 @@ import { Transfers } from "./world.transfers.js";
|
|
|
10
12
|
export class Disposal extends Transfers {
|
|
11
13
|
constructor() {
|
|
12
14
|
super(...arguments);
|
|
13
|
-
/** `true` once {@link dispose} has started:
|
|
15
|
+
/** `true` once {@link dispose} has started: repeated top-level calls are idempotent. */
|
|
14
16
|
this._disposeStarted = false;
|
|
15
17
|
}
|
|
16
18
|
/**
|
|
17
|
-
* End the world's life: destroy
|
|
19
|
+
* End the world's life: destroy application entities, then all world infrastructure, so the
|
|
18
20
|
* `remove` hooks of the components they carry release what those components own (render
|
|
19
21
|
* objects, handles, timers). Call it when the world is finished — a scene or route change, a
|
|
20
22
|
* hot reload — and drop the reference afterwards.
|
|
21
23
|
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
* and
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
* ## What stays
|
|
29
|
-
*
|
|
30
|
-
* The infrastructure the world needs to stay coherent is not destroyed:
|
|
31
|
-
*
|
|
32
|
-
* - component and module entities (every {@link Component}),
|
|
33
|
-
* - the entities behind queries and systems (they carry the {@link Query} component), and
|
|
34
|
-
* - phase entities (they carry the {@link Phase} component).
|
|
35
|
-
*
|
|
36
|
-
* What those entities hold stays too: data stored on a component entity (a singleton set with
|
|
37
|
-
* {@link set}) and any entity they still carry as a component key, which cannot be destroyed
|
|
38
|
-
* while it is in use. Release such data yourself. {@link clearAllEntities} is the full wipe,
|
|
39
|
-
* infrastructure included.
|
|
24
|
+
* Both passes use the existing entity destroy path and fire every component's
|
|
25
|
+
* `remove` hook exactly once. Application cleanup retains ordinary cleanup policies
|
|
26
|
+
* and cascades. Infrastructure teardown suspends cleanup policies: it removes a
|
|
27
|
+
* component from remaining carriers instead of throwing or deleting them, and
|
|
28
|
+
* destroys children explicitly rather than through ChildOf/OwnedTarget cascades.
|
|
40
29
|
*
|
|
41
30
|
* ## Order
|
|
42
31
|
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
32
|
+
* Queued application cleanup finishes before infrastructure teardown starts. Systems and
|
|
33
|
+
* queries go first in the infrastructure pass, then modules in reverse registration
|
|
34
|
+
* order, then the rest. Beyond these priorities the order is unspecified, not a
|
|
35
|
+
* resource dependency contract. Infrastructure carrier cycles are stripped, not
|
|
36
|
+
* reported as survivors. Nothing remains after successful disposal.
|
|
37
|
+
* {@link clearAllEntities} retains its own throwing behavior.
|
|
46
38
|
*
|
|
47
|
-
* ##
|
|
39
|
+
* ## Call site
|
|
48
40
|
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
* the destruction like any `destroy()` in that situation, and the destruction completes when
|
|
55
|
-
* the queue next drains: right after the running system, or at the end of the `defer` block.
|
|
41
|
+
* Call synchronously at top level: not inside {@link progress}, {@link defer}, a command drain
|
|
42
|
+
* or an entity's destroy. A refused call throws before teardown starts, leaving the world
|
|
43
|
+
* usable; call again after the enclosing operation finishes. Ordinary synchronous top-level
|
|
44
|
+
* `add`, `set` and `remove` hooks may call it. Cleanup and commands created by teardown hooks
|
|
45
|
+
* settle before this call returns.
|
|
56
46
|
*
|
|
57
47
|
* ## After disposal
|
|
58
48
|
*
|
|
59
49
|
* A disposed world must not be used again. Nothing enforces it — no other method checks, so
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
50
|
+
* mutations have no disposal guard — but the world has no state left to run on. Calling
|
|
51
|
+
* `dispose()` again at top level does nothing. The call-site rule still applies during teardown.
|
|
52
|
+
* Do not create entities indefinitely from teardown hooks: the final pass repeats while it can
|
|
53
|
+
* destroy more entities. Release resources in `remove` hooks, not system `exit` callbacks,
|
|
54
|
+
* which will not run after teardown. A hook that throws propagates out of
|
|
65
55
|
* the call and leaves the world partial, as it does from any destroy: treat it as a programming
|
|
66
56
|
* error.
|
|
57
|
+
*
|
|
58
|
+
* @throws An `Error` for a forbidden call site before any disposal mutation,
|
|
59
|
+
* an internal-invariant error if infrastructure teardown makes no progress,
|
|
60
|
+
* or an error propagated by a teardown hook. The latter errors leave the world partial.
|
|
67
61
|
*/
|
|
68
62
|
dispose() {
|
|
63
|
+
this._assertDisposalAllowed();
|
|
69
64
|
if (this._disposeStarted) {
|
|
70
65
|
return;
|
|
71
66
|
}
|
|
72
67
|
this._disposeStarted = true;
|
|
73
|
-
//
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
68
|
+
// Settle application hooks and any entities they create before removing infrastructure.
|
|
69
|
+
let applications = this._destroyOrder();
|
|
70
|
+
while (applications.length > 0) {
|
|
71
|
+
this.defer(() => {
|
|
72
|
+
for (const entity of applications) {
|
|
73
|
+
this._enqueue({ kind: 4 /* CommandKind.Destroy */, entity });
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
applications = this._destroyOrder();
|
|
77
|
+
}
|
|
78
|
+
this._tearingDownInfrastructure = true;
|
|
79
|
+
try {
|
|
80
|
+
while (this._entities.size > 0) {
|
|
81
|
+
const entities = this._entities.values().filter((entity) => !entity.destroyed);
|
|
82
|
+
// The class registry is insertion-ordered; the dense entity map swaps entries on deletion.
|
|
83
|
+
const modules = [...this._classRegistry.values()]
|
|
84
|
+
.filter((entity) => entity instanceof Module && !entity.destroyed)
|
|
85
|
+
.reverse();
|
|
86
|
+
const queryEid = this.getEntity(Query)?.eid;
|
|
87
|
+
const queries = entities.filter((entity) => queryEid !== undefined && entity.has(queryEid));
|
|
88
|
+
const priority = new Set([...queries, ...modules]);
|
|
89
|
+
const ordered = [
|
|
90
|
+
...queries,
|
|
91
|
+
...modules,
|
|
92
|
+
...entities.filter((entity) => !priority.has(entity)),
|
|
93
|
+
];
|
|
94
|
+
let destroyed = 0;
|
|
95
|
+
for (const entity of ordered) {
|
|
96
|
+
if (!entity.destroyed) {
|
|
97
|
+
entity._destroy();
|
|
98
|
+
if (entity.destroyed) {
|
|
99
|
+
destroyed++;
|
|
100
|
+
}
|
|
101
|
+
this.flush();
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
this.flush();
|
|
105
|
+
if (destroyed === 0 && this._entities.size > 0) {
|
|
106
|
+
throw new Error(`Internal invariant: infrastructure teardown made no progress; registered entities: ${this._entities
|
|
107
|
+
.values()
|
|
108
|
+
.map((entity) => `${entity.eid} (${entity.meta.Class.name}, destroyed=${entity.destroyed})`)
|
|
109
|
+
.join(", ")}`);
|
|
110
|
+
}
|
|
78
111
|
}
|
|
79
|
-
}
|
|
112
|
+
}
|
|
113
|
+
finally {
|
|
114
|
+
this._tearingDownInfrastructure = false;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Validate the disposal call site before teardown changes any state.
|
|
119
|
+
* Subclasses overriding {@link dispose} must call this before starting their own cleanup.
|
|
120
|
+
* @throws An `Error` inside a frame, deferred scope, command drain or entity destroy.
|
|
121
|
+
*/
|
|
122
|
+
_assertDisposalAllowed() {
|
|
123
|
+
if (this.deferred || this._frameInProgress || this._deletionScope) {
|
|
124
|
+
throw new Error("dispose() must be called outside progress(), defer, a command drain or an entity's destroy");
|
|
125
|
+
}
|
|
80
126
|
}
|
|
81
127
|
/**
|
|
82
128
|
* The entities {@link dispose} destroys, in an order that lets every destroy succeed: those the
|
|
@@ -89,58 +135,7 @@ export class Disposal extends Transfers {
|
|
|
89
135
|
const isInfrastructure = (entity) => entity instanceof Component ||
|
|
90
136
|
(queryEid !== undefined && entity.has(queryEid)) ||
|
|
91
137
|
(phaseEid !== undefined && entity.has(phaseEid));
|
|
92
|
-
|
|
93
|
-
// In a deferred scope an entity created earlier is only queued, not registered yet. Its
|
|
94
|
-
// creation runs ahead of the destroy that is queued after it.
|
|
95
|
-
for (const command of this._commandQueue) {
|
|
96
|
-
if (command.kind === 0 /* CommandKind.CreateEntity */ &&
|
|
97
|
-
!command.entity.destroyed &&
|
|
98
|
-
this._entities.get(command.entity.eid) !== command.entity) {
|
|
99
|
-
entities.push(command.entity);
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
return carriersFirst(entities.filter((entity) => !isInfrastructure(entity)), isInfrastructure);
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
/**
|
|
106
|
-
* Order `entities` so that an entity used as a component key follows every entity that carries it.
|
|
107
|
-
*
|
|
108
|
-
* A key destroyed while still carried throws under the default cleanup policy, so carriers go
|
|
109
|
-
* first. A key that something outside `entities` carries, which is infrastructure in practice, or
|
|
110
|
-
* that is caught in a cycle, cannot be ordered and is left out: destroying it would throw or strip
|
|
111
|
-
* the infrastructure.
|
|
112
|
-
*/
|
|
113
|
-
function carriersFirst(entities, isInfrastructure) {
|
|
114
|
-
const ordered = [];
|
|
115
|
-
const keys = new Set();
|
|
116
|
-
for (const entity of entities) {
|
|
117
|
-
if (entity.instanceCount() === 0) {
|
|
118
|
-
ordered.push(entity);
|
|
119
|
-
}
|
|
120
|
-
else {
|
|
121
|
-
keys.add(entity);
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
let progressed = keys.size > 0;
|
|
125
|
-
while (progressed) {
|
|
126
|
-
progressed = false;
|
|
127
|
-
for (const key of keys) {
|
|
128
|
-
if (!isCarried(key, keys, isInfrastructure)) {
|
|
129
|
-
ordered.push(key);
|
|
130
|
-
keys.delete(key);
|
|
131
|
-
progressed = true;
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
return ordered;
|
|
136
|
-
}
|
|
137
|
-
/** Whether `key` is still carried by another key that waits to be ordered, or by infrastructure. */
|
|
138
|
-
function isCarried(key, waiting, isInfrastructure) {
|
|
139
|
-
for (const carrier of key.meta._carriers ?? []) {
|
|
140
|
-
if (carrier !== key && (waiting.has(carrier) || isInfrastructure(carrier))) {
|
|
141
|
-
return true;
|
|
142
|
-
}
|
|
138
|
+
return carriersFirst(this._entities.values().filter((entity) => !entity.destroyed && !isInfrastructure(entity)));
|
|
143
139
|
}
|
|
144
|
-
return false;
|
|
145
140
|
}
|
|
146
141
|
//# sourceMappingURL=world.disposal.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"world.disposal.js","sourceRoot":"","sources":["../../src/world/world.disposal.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,OAAO,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;AAC/C,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAGjD;;;;GAIG;AACH,MAAM,OAAO,QAAS,SAAQ,SAAS;IAAvC;;QACE,
|
|
1
|
+
{"version":3,"file":"world.disposal.js","sourceRoot":"","sources":["../../src/world/world.disposal.ts"],"names":[],"mappings":"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"}
|
|
@@ -31,6 +31,26 @@ export declare class Entities extends Deferred {
|
|
|
31
31
|
* A foreign `Entity` ref throws (see {@link getEntity}).
|
|
32
32
|
*/
|
|
33
33
|
entity(this: World, ref: ComponentRef): Entity;
|
|
34
|
-
/**
|
|
34
|
+
/**
|
|
35
|
+
* Destroy every tracked entity, ordering both carriers and ChildOf children
|
|
36
|
+
* before their keys/parents. Retains ordinary cleanup policies; throws when
|
|
37
|
+
* dependency cycles prevent safe destruction (unlike dispose's final pass).
|
|
38
|
+
*/
|
|
35
39
|
clearAllEntities(): void;
|
|
40
|
+
/**
|
|
41
|
+
* Parent entities created synchronously in `fn`'s body to `parent` through ChildOf.
|
|
42
|
+
* Includes components, modules, queries, systems and ordinary entities. Existing
|
|
43
|
+
* lookups are not reparented; an explicit childOf call replaces the scope parent.
|
|
44
|
+
* Nested scopes restore their caller in finally, even when fn throws.
|
|
45
|
+
* Entities created by deferred callbacks inside the body are not parented:
|
|
46
|
+
* query.forEach, enter backfill during query build, or an explicit world.defer.
|
|
47
|
+
* These are run-time data; the same callback outside the scope would not parent
|
|
48
|
+
* them either. For example, health bars created per existing ship by an enter
|
|
49
|
+
* or forEach callback remain roots, unlike definitions created directly in init.
|
|
50
|
+
* Throws while deferred: call outside progress() and defer, not during a command
|
|
51
|
+
* drain. Schedule lazy module loading after progress() returns.
|
|
52
|
+
* The parent must be a live entity of this world. This is a synchronous scope,
|
|
53
|
+
* not an async context; it does not change deferral or catch callback errors.
|
|
54
|
+
*/
|
|
55
|
+
scope(this: World, parent: Entity, fn: () => void): void;
|
|
36
56
|
}
|