@vworlds/vecs 1.0.11 → 1.0.13
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 +169 -72
- package/dist/component.d.ts +22 -70
- package/dist/component.js +4 -59
- package/dist/component.js.map +1 -1
- package/dist/dsl.d.ts +9 -5
- package/dist/dsl.js +6 -3
- package/dist/dsl.js.map +1 -1
- package/dist/entity.d.ts +10 -11
- package/dist/entity.js +55 -51
- package/dist/entity.js.map +1 -1
- package/dist/filter.d.ts +3 -3
- package/dist/index.d.ts +2 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/package.json +1 -1
- package/dist/phase.d.ts +7 -2
- package/dist/phase.js.map +1 -1
- package/dist/query.d.ts +21 -21
- package/dist/query.js +17 -16
- package/dist/query.js.map +1 -1
- package/dist/system.d.ts +120 -8
- package/dist/system.js +152 -12
- 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.js +11 -7
- package/dist/util/array_map.js.map +1 -1
- package/dist/util/bitset.d.ts +17 -3
- package/dist/util/bitset.js +47 -30
- package/dist/util/bitset.js.map +1 -1
- package/dist/world.d.ts +48 -17
- package/dist/world.js +91 -25
- package/dist/world.js.map +1 -1
- package/package.json +1 -1
package/dist/query.js
CHANGED
|
@@ -120,9 +120,10 @@ export class Query {
|
|
|
120
120
|
this._entities?.add(e);
|
|
121
121
|
e._addQueryMembership(this);
|
|
122
122
|
this._enterCallback?.(e);
|
|
123
|
-
e.components.forEach((c) => {
|
|
124
|
-
|
|
125
|
-
|
|
123
|
+
e.components.forEach((c, type) => {
|
|
124
|
+
const meta = this.world.getComponentMeta(type);
|
|
125
|
+
if (this._watchlistBitmask.hasBit(meta.bitPtr)) {
|
|
126
|
+
this._notifyModified(e, meta, c);
|
|
126
127
|
}
|
|
127
128
|
});
|
|
128
129
|
}
|
|
@@ -141,13 +142,13 @@ export class Query {
|
|
|
141
142
|
* `update` callback for the component type. `System` overrides this to push
|
|
142
143
|
* an inbox event instead of firing immediately.
|
|
143
144
|
*/
|
|
144
|
-
_notifyModified(c) {
|
|
145
|
-
if (!this._watchlistBitmask.hasBit(
|
|
145
|
+
_notifyModified(e, meta, c) {
|
|
146
|
+
if (!this._watchlistBitmask.hasBit(meta.bitPtr)) {
|
|
146
147
|
return;
|
|
147
148
|
}
|
|
148
|
-
const callback = this._componentUpdateCallbacks.get(
|
|
149
|
+
const callback = this._componentUpdateCallbacks.get(meta.type);
|
|
149
150
|
if (callback) {
|
|
150
|
-
callback(c);
|
|
151
|
+
callback(e, c);
|
|
151
152
|
}
|
|
152
153
|
}
|
|
153
154
|
/**
|
|
@@ -239,13 +240,13 @@ export class Query {
|
|
|
239
240
|
else {
|
|
240
241
|
const inject = injectOrCallback;
|
|
241
242
|
const injectedComponentTypes = inject.map((C) => this.world.getComponentType(C));
|
|
242
|
-
const cb = (c) => {
|
|
243
|
+
const cb = (e, c) => {
|
|
243
244
|
const injected = [];
|
|
244
245
|
injectedComponentTypes.forEach((InjectedComponentType) => {
|
|
245
|
-
injected.push(
|
|
246
|
+
injected.push(e.get(InjectedComponentType));
|
|
246
247
|
});
|
|
247
248
|
if (callback) {
|
|
248
|
-
callback(c, injected);
|
|
249
|
+
callback(e, c, injected);
|
|
249
250
|
}
|
|
250
251
|
};
|
|
251
252
|
this._componentUpdateCallbacks.set(type, cb);
|
|
@@ -263,26 +264,26 @@ export class Query {
|
|
|
263
264
|
}
|
|
264
265
|
/**
|
|
265
266
|
* Switch the tracked set to a sorted ordering: matched entities are stored
|
|
266
|
-
* in the position determined by `compare`, which receives
|
|
267
|
-
* resolved component instances for each pair being ordered.
|
|
267
|
+
* in the position determined by `compare`, which receives each entity and a
|
|
268
|
+
* tuple of resolved component instances for each pair being ordered.
|
|
268
269
|
*
|
|
269
270
|
* Implies {@link track}.
|
|
270
271
|
*
|
|
271
272
|
* @param components - Component classes to resolve and pass to `compare`.
|
|
272
|
-
* @param compare - Negative when `
|
|
273
|
-
* equality, positive when `
|
|
273
|
+
* @param compare - Negative when `entityA` should sort before `entityB`, zero
|
|
274
|
+
* for equality, positive when `entityA` should sort after `entityB`.
|
|
274
275
|
* @returns This query, for chaining.
|
|
275
276
|
*
|
|
276
277
|
* @example
|
|
277
278
|
* ```ts
|
|
278
279
|
* world.system("Render")
|
|
279
280
|
* .requires(Position, Sprite)
|
|
280
|
-
* .sort([Position], ([posA], [posB]) => posA.z - posB.z);
|
|
281
|
+
* .sort([Position], (_entityA, [posA], _entityB, [posB]) => posA.z - posB.z);
|
|
281
282
|
* ```
|
|
282
283
|
*/
|
|
283
284
|
sort(components, compare) {
|
|
284
285
|
const types = components.map((C) => this.world.getComponentType(C));
|
|
285
|
-
this._entities = new OrderedSet((a, b) => compare(types.map((t) => a.get(t)), types.map((t) => b.get(t))));
|
|
286
|
+
this._entities = new OrderedSet((a, b) => compare(a, types.map((t) => a.get(t)), b, types.map((t) => b.get(t))));
|
|
286
287
|
this._backfill();
|
|
287
288
|
return this;
|
|
288
289
|
}
|
package/dist/query.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"query.js","sourceRoot":"","sources":["../src/query.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"query.js","sourceRoot":"","sources":["../src/query.ts"],"names":[],"mappings":"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"}
|
package/dist/system.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { type ComponentClass } from "./component.js";
|
|
2
2
|
import { Query } from "./query.js";
|
|
3
3
|
import { type QueryDSL, type MaybeRequired } from "./dsl.js";
|
|
4
4
|
import type { Entity } from "./entity.js";
|
|
5
5
|
import { type IPhase } from "./phase.js";
|
|
6
6
|
import { type World } from "./world.js";
|
|
7
|
+
import { type ITickSource } from "./timer.js";
|
|
7
8
|
export type { QueryDSL as SystemQuery, EntityTestFunc } from "./dsl.js";
|
|
8
9
|
type RunCallback = (now: number, delta: number) => void;
|
|
9
10
|
/**
|
|
@@ -16,7 +17,7 @@ type RunCallback = (now: number, delta: number) => void;
|
|
|
16
17
|
* .requires(Position, Velocity) // track entities with both components
|
|
17
18
|
* .phase("update")
|
|
18
19
|
* .enter([Position], (e, [pos]) => { pos.x = 0; })
|
|
19
|
-
* .update(Position, (pos) => { pos.x += pos.vx; })
|
|
20
|
+
* .update(Position, (e, pos) => { pos.x += pos.vx; })
|
|
20
21
|
* .exit((e) => { console.log("entity left", e.eid); });
|
|
21
22
|
* ```
|
|
22
23
|
*
|
|
@@ -43,8 +44,75 @@ type RunCallback = (now: number, delta: number) => void;
|
|
|
43
44
|
*
|
|
44
45
|
* @typeParam R - Component classes guaranteed present on every matched entity.
|
|
45
46
|
*/
|
|
46
|
-
export declare class System<R extends
|
|
47
|
+
export declare class System<R extends ComponentClass[] = []> extends Query<R> implements ITickSource {
|
|
47
48
|
constructor(name: string, world: World);
|
|
49
|
+
/** True when this system's cadence source fired during the current frame. */
|
|
50
|
+
get didTick(): boolean;
|
|
51
|
+
/** Milliseconds accumulated into this system's most recent fire. */
|
|
52
|
+
get lastFireDelta(): number;
|
|
53
|
+
/**
|
|
54
|
+
* Run this system at a fixed interval, expressed in seconds.
|
|
55
|
+
*
|
|
56
|
+
* This is seconds, unlike `World.beginFrame`, `World.progress`, and
|
|
57
|
+
* `runPhase`, which receive millisecond deltas. Calling `interval` replaces
|
|
58
|
+
* the current cadence source with an {@link IntervalTickSource}. When this
|
|
59
|
+
* system has a cadence source, the `delta` passed to {@link run} is the
|
|
60
|
+
* accumulated milliseconds since the previous fire, not the per-frame delta.
|
|
61
|
+
*
|
|
62
|
+
* @param seconds - Positive interval duration in seconds.
|
|
63
|
+
* @returns This system, for chaining.
|
|
64
|
+
* @throws When `seconds` is less than or equal to zero.
|
|
65
|
+
*
|
|
66
|
+
* @example
|
|
67
|
+
* ```ts
|
|
68
|
+
* world.system("AI")
|
|
69
|
+
* .interval(0.5)
|
|
70
|
+
* .run((now, delta) => tickAI(delta));
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
interval(seconds: number): this;
|
|
74
|
+
/**
|
|
75
|
+
* Run this system every `n` ticks from the world or an upstream source.
|
|
76
|
+
*
|
|
77
|
+
* Without a `source`, this composes with the current cadence source. For an
|
|
78
|
+
* unconfigured system, that means every `n` frames. With a `source`, it
|
|
79
|
+
* replaces the current cadence with a {@link RateTickSource} over that source.
|
|
80
|
+
* The `delta` passed to {@link run} is the accumulated milliseconds since
|
|
81
|
+
* this system last fired.
|
|
82
|
+
*
|
|
83
|
+
* @param n - Positive integer tick divisor.
|
|
84
|
+
* @param source - Optional upstream source to divide.
|
|
85
|
+
* @returns This system, for chaining.
|
|
86
|
+
* @throws When `n` is not a positive integer.
|
|
87
|
+
*
|
|
88
|
+
* @example
|
|
89
|
+
* ```ts
|
|
90
|
+
* world.system("SendSnapshots")
|
|
91
|
+
* .rate(2)
|
|
92
|
+
* .run(flushNetwork);
|
|
93
|
+
* ```
|
|
94
|
+
*/
|
|
95
|
+
rate(n: number): this;
|
|
96
|
+
rate(n: number, source: ITickSource): this;
|
|
97
|
+
/**
|
|
98
|
+
* Run this system only when another timer or system ticks.
|
|
99
|
+
*
|
|
100
|
+
* Calling `tickSource` mirrors `source` directly; no wrapper source is
|
|
101
|
+
* created. Use `.tickSource(source).rate(n)` or `.rate(n, source)` when this
|
|
102
|
+
* system should divide an upstream source. The `delta` passed to {@link run}
|
|
103
|
+
* is the accumulated milliseconds since this system last fired.
|
|
104
|
+
*
|
|
105
|
+
* @param source - Tick source or system source to mirror.
|
|
106
|
+
* @returns This system, for chaining.
|
|
107
|
+
*
|
|
108
|
+
* @example
|
|
109
|
+
* ```ts
|
|
110
|
+
* const second = new IntervalTickSource(1);
|
|
111
|
+
* world.system("Logger").tickSource(second).run(logStats);
|
|
112
|
+
* ```
|
|
113
|
+
*/
|
|
114
|
+
tickSource(source: ITickSource): this;
|
|
115
|
+
private _setTickSource;
|
|
48
116
|
/**
|
|
49
117
|
* Assign this system to a pipeline phase.
|
|
50
118
|
*
|
|
@@ -66,7 +134,9 @@ export declare class System<R extends (typeof Component)[] = []> extends Query<R
|
|
|
66
134
|
* network flushing, global timers, etc.
|
|
67
135
|
*
|
|
68
136
|
* @param callback - Receives `now` (absolute timestamp in ms) and `delta`
|
|
69
|
-
* (ms since the previous tick).
|
|
137
|
+
* (ms since the previous tick). If the system has an active interval,
|
|
138
|
+
* rate, or tick source, `delta` is the accumulated milliseconds since this
|
|
139
|
+
* system last fired.
|
|
70
140
|
* @returns This system, for chaining.
|
|
71
141
|
*/
|
|
72
142
|
run(callback: RunCallback): this;
|
|
@@ -74,7 +144,7 @@ export declare class System<R extends (typeof Component)[] = []> extends Query<R
|
|
|
74
144
|
* Register a callback fired **every tick** for **every tracked entity**,
|
|
75
145
|
* unconditionally, with the listed components resolved from each entity.
|
|
76
146
|
*
|
|
77
|
-
* Unlike {@link update} (which only fires when `
|
|
147
|
+
* Unlike {@link update} (which only fires when `entity.modified(C)` is
|
|
78
148
|
* called), `each` fires every tick the system runs, once per tracked entity.
|
|
79
149
|
* Components declared via {@link requires} are non-nullable in the resolved
|
|
80
150
|
* tuple; any other component class may be `undefined` if the entity lacks it.
|
|
@@ -102,7 +172,7 @@ export declare class System<R extends (typeof Component)[] = []> extends Query<R
|
|
|
102
172
|
* });
|
|
103
173
|
* ```
|
|
104
174
|
*/
|
|
105
|
-
each<J extends
|
|
175
|
+
each<J extends ComponentClass[]>(components: readonly [...J], callback: (e: Entity, resolved: {
|
|
106
176
|
[K in keyof J]: MaybeRequired<J[K], R>;
|
|
107
177
|
}) => void): this;
|
|
108
178
|
/**
|
|
@@ -120,7 +190,7 @@ export declare class System<R extends (typeof Component)[] = []> extends Query<R
|
|
|
120
190
|
* entity (type hint only — not validated at runtime).
|
|
121
191
|
* @returns This system, retyped with the guaranteed tuple as its `R`.
|
|
122
192
|
*/
|
|
123
|
-
query<T extends
|
|
193
|
+
query<T extends ComponentClass[] = []>(q: QueryDSL, _guaranteed?: readonly [...T]): System<T>;
|
|
124
194
|
/**
|
|
125
195
|
* Shorthand for `query([...components])` — tracks entities that have **all**
|
|
126
196
|
* of the listed component types.
|
|
@@ -132,7 +202,49 @@ export declare class System<R extends (typeof Component)[] = []> extends Query<R
|
|
|
132
202
|
* @param components - Component classes to require.
|
|
133
203
|
* @returns This system, retyped with the required tuple as its `R`.
|
|
134
204
|
*/
|
|
135
|
-
requires<T extends
|
|
205
|
+
requires<T extends ComponentClass[]>(...components: [...T]): System<T>;
|
|
206
|
+
/**
|
|
207
|
+
* Disable this system.
|
|
208
|
+
*
|
|
209
|
+
* While disabled the system is effectively invisible: the inbox is cleared
|
|
210
|
+
* immediately, any new `enter`, `exit`, or `update` events are silently
|
|
211
|
+
* dropped, and {@link _run} returns without executing any callbacks. Entity
|
|
212
|
+
* membership in the underlying query is still maintained so the tracked set
|
|
213
|
+
* remains consistent and the system resumes correctly when
|
|
214
|
+
* {@link enable} is called.
|
|
215
|
+
*
|
|
216
|
+
* Disabling is independent from tick-source cadence: `disable` suppresses
|
|
217
|
+
* callbacks, but a disabled system used as a tick source still drives
|
|
218
|
+
* downstream consumers. Use `stop()` on an external `IntervalTickSource` or
|
|
219
|
+
* `RateTickSource` reference to halt that clock itself.
|
|
220
|
+
*
|
|
221
|
+
* Calling `disable` on an already-disabled system is a no-op.
|
|
222
|
+
*
|
|
223
|
+
* @returns This system, for chaining.
|
|
224
|
+
*
|
|
225
|
+
* @example
|
|
226
|
+
* ```ts
|
|
227
|
+
* const sys = world.system("AI").requires(Enemy).run(runAI);
|
|
228
|
+
* // Pause AI processing during a cutscene:
|
|
229
|
+
* sys.disable();
|
|
230
|
+
* // Resume:
|
|
231
|
+
* sys.enable();
|
|
232
|
+
* ```
|
|
233
|
+
*/
|
|
234
|
+
disable(): this;
|
|
235
|
+
/**
|
|
236
|
+
* Enable this system after a previous {@link disable} call.
|
|
237
|
+
*
|
|
238
|
+
* Once re-enabled the system resumes its normal tick behaviour: enter, exit,
|
|
239
|
+
* and update events are queued, and {@link _run} processes the inbox and fires
|
|
240
|
+
* all registered callbacks. Events that occurred while the system was disabled
|
|
241
|
+
* are not replayed.
|
|
242
|
+
*
|
|
243
|
+
* Calling `enable` on an already-enabled system is a no-op.
|
|
244
|
+
*
|
|
245
|
+
* @returns This system, for chaining.
|
|
246
|
+
*/
|
|
247
|
+
enable(): this;
|
|
136
248
|
/**
|
|
137
249
|
* Not supported on `System`. Throws unconditionally.
|
|
138
250
|
*
|
package/dist/system.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Query } from "./query.js";
|
|
2
2
|
import { Phase } from "./phase.js";
|
|
3
|
+
import { ALWAYS_TICK_SOURCE, IntervalTickSource, RateTickSource, } from "./timer.js";
|
|
3
4
|
/**
|
|
4
5
|
* A reactive processor running over a filtered subset of world entities.
|
|
5
6
|
*
|
|
@@ -10,7 +11,7 @@ import { Phase } from "./phase.js";
|
|
|
10
11
|
* .requires(Position, Velocity) // track entities with both components
|
|
11
12
|
* .phase("update")
|
|
12
13
|
* .enter([Position], (e, [pos]) => { pos.x = 0; })
|
|
13
|
-
* .update(Position, (pos) => { pos.x += pos.vx; })
|
|
14
|
+
* .update(Position, (e, pos) => { pos.x += pos.vx; })
|
|
14
15
|
* .exit((e) => { console.log("entity left", e.eid); });
|
|
15
16
|
* ```
|
|
16
17
|
*
|
|
@@ -42,6 +43,10 @@ export class System extends Query {
|
|
|
42
43
|
super(name, world, false);
|
|
43
44
|
/** @internal Single inbox replayed in arrival order on every `_run`. */
|
|
44
45
|
this._inbox = [];
|
|
46
|
+
/** @internal Whether this system processes events and runs callbacks. */
|
|
47
|
+
this._enabled = true;
|
|
48
|
+
/** @internal Cadence source for this system. Defaults to every frame. */
|
|
49
|
+
this._tickSource = ALWAYS_TICK_SOURCE;
|
|
45
50
|
}
|
|
46
51
|
/**
|
|
47
52
|
* @internal Routing entry: register query membership for `e`, push an
|
|
@@ -52,12 +57,16 @@ export class System extends Query {
|
|
|
52
57
|
_enter(e) {
|
|
53
58
|
this._entities?.add(e);
|
|
54
59
|
e._addQueryMembership(this);
|
|
60
|
+
if (!this._enabled) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
55
63
|
if (this._enterCallback !== undefined) {
|
|
56
64
|
this._inbox.push({ kind: 0 /* InboxCommand.Enter */, entity: e });
|
|
57
65
|
}
|
|
58
|
-
e.components.forEach((c) => {
|
|
59
|
-
|
|
60
|
-
|
|
66
|
+
e.components.forEach((c, type) => {
|
|
67
|
+
const meta = this.world.getComponentMeta(type);
|
|
68
|
+
if (this._watchlistBitmask.hasBit(meta.bitPtr)) {
|
|
69
|
+
this._notifyModified(e, meta, c);
|
|
61
70
|
}
|
|
62
71
|
});
|
|
63
72
|
}
|
|
@@ -70,6 +79,9 @@ export class System extends Query {
|
|
|
70
79
|
_exit(e) {
|
|
71
80
|
this._entities?.delete(e);
|
|
72
81
|
e._removeQueryMembership(this);
|
|
82
|
+
if (!this._enabled) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
73
85
|
if (this._exitCallback !== undefined) {
|
|
74
86
|
let snapshot;
|
|
75
87
|
if (this._exitSnapshotTypes && this._exitSnapshotTypes.length > 0) {
|
|
@@ -88,11 +100,11 @@ export class System extends Query {
|
|
|
88
100
|
* @internal Routing entry: push an inbox `update` event when the modified
|
|
89
101
|
* component matches the watchlist.
|
|
90
102
|
*/
|
|
91
|
-
_notifyModified(c) {
|
|
92
|
-
if (!this._watchlistBitmask.hasBit(
|
|
103
|
+
_notifyModified(e, meta, c) {
|
|
104
|
+
if (!this._enabled || !this._watchlistBitmask.hasBit(meta.bitPtr)) {
|
|
93
105
|
return;
|
|
94
106
|
}
|
|
95
|
-
this._inbox.push({ kind: 2 /* InboxCommand.Update */, component: c });
|
|
107
|
+
this._inbox.push({ kind: 2 /* InboxCommand.Update */, entity: e, meta, component: c });
|
|
96
108
|
}
|
|
97
109
|
/**
|
|
98
110
|
* @internal Execute one tick: drain the inbox in arrival order, then run
|
|
@@ -102,6 +114,13 @@ export class System extends Query {
|
|
|
102
114
|
* callbacks land in the world queue and are processed when `_run` returns.
|
|
103
115
|
*/
|
|
104
116
|
_run(now, delta) {
|
|
117
|
+
if (!this._enabled) {
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
if (!this._tickSource.didTick) {
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
const tickDelta = this._tickSource.lastFireDelta;
|
|
105
124
|
this.world.defer(() => {
|
|
106
125
|
for (let i = 0; i < this._inbox.length; i++) {
|
|
107
126
|
const event = this._inbox[i];
|
|
@@ -113,16 +132,16 @@ export class System extends Query {
|
|
|
113
132
|
this._exitCallback(event.entity, event.snapshot);
|
|
114
133
|
break;
|
|
115
134
|
case 2 /* InboxCommand.Update */:
|
|
116
|
-
const callback = this._componentUpdateCallbacks.get(event.
|
|
135
|
+
const callback = this._componentUpdateCallbacks.get(event.meta.type);
|
|
117
136
|
if (callback) {
|
|
118
|
-
callback(event.component);
|
|
137
|
+
callback(event.entity, event.component);
|
|
119
138
|
}
|
|
120
139
|
break;
|
|
121
140
|
}
|
|
122
141
|
}
|
|
123
142
|
this._inbox.length = 0;
|
|
124
143
|
if (this._runCallback) {
|
|
125
|
-
this._runCallback(now,
|
|
144
|
+
this._runCallback(now, tickDelta);
|
|
126
145
|
}
|
|
127
146
|
if (this._eachCallback) {
|
|
128
147
|
const cb = this._eachCallback;
|
|
@@ -130,6 +149,76 @@ export class System extends Query {
|
|
|
130
149
|
}
|
|
131
150
|
});
|
|
132
151
|
}
|
|
152
|
+
/** True when this system's cadence source fired during the current frame. */
|
|
153
|
+
get didTick() {
|
|
154
|
+
return this._tickSource.didTick;
|
|
155
|
+
}
|
|
156
|
+
/** Milliseconds accumulated into this system's most recent fire. */
|
|
157
|
+
get lastFireDelta() {
|
|
158
|
+
return this._tickSource.lastFireDelta;
|
|
159
|
+
}
|
|
160
|
+
/** @internal Evaluate this system's cadence source for a frame. */
|
|
161
|
+
_evalTick(delta, frameId) {
|
|
162
|
+
return this._tickSource._evalTick(delta, frameId);
|
|
163
|
+
}
|
|
164
|
+
/** @internal Register this system source and its current cadence source. */
|
|
165
|
+
_register(world) {
|
|
166
|
+
world._registerTickSource(this);
|
|
167
|
+
this._tickSource._register(world);
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Run this system at a fixed interval, expressed in seconds.
|
|
171
|
+
*
|
|
172
|
+
* This is seconds, unlike `World.beginFrame`, `World.progress`, and
|
|
173
|
+
* `runPhase`, which receive millisecond deltas. Calling `interval` replaces
|
|
174
|
+
* the current cadence source with an {@link IntervalTickSource}. When this
|
|
175
|
+
* system has a cadence source, the `delta` passed to {@link run} is the
|
|
176
|
+
* accumulated milliseconds since the previous fire, not the per-frame delta.
|
|
177
|
+
*
|
|
178
|
+
* @param seconds - Positive interval duration in seconds.
|
|
179
|
+
* @returns This system, for chaining.
|
|
180
|
+
* @throws When `seconds` is less than or equal to zero.
|
|
181
|
+
*
|
|
182
|
+
* @example
|
|
183
|
+
* ```ts
|
|
184
|
+
* world.system("AI")
|
|
185
|
+
* .interval(0.5)
|
|
186
|
+
* .run((now, delta) => tickAI(delta));
|
|
187
|
+
* ```
|
|
188
|
+
*/
|
|
189
|
+
interval(seconds) {
|
|
190
|
+
this._setTickSource(new IntervalTickSource(seconds));
|
|
191
|
+
return this;
|
|
192
|
+
}
|
|
193
|
+
rate(n, source) {
|
|
194
|
+
this._setTickSource(new RateTickSource(n, source ?? this._tickSource));
|
|
195
|
+
return this;
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Run this system only when another timer or system ticks.
|
|
199
|
+
*
|
|
200
|
+
* Calling `tickSource` mirrors `source` directly; no wrapper source is
|
|
201
|
+
* created. Use `.tickSource(source).rate(n)` or `.rate(n, source)` when this
|
|
202
|
+
* system should divide an upstream source. The `delta` passed to {@link run}
|
|
203
|
+
* is the accumulated milliseconds since this system last fired.
|
|
204
|
+
*
|
|
205
|
+
* @param source - Tick source or system source to mirror.
|
|
206
|
+
* @returns This system, for chaining.
|
|
207
|
+
*
|
|
208
|
+
* @example
|
|
209
|
+
* ```ts
|
|
210
|
+
* const second = new IntervalTickSource(1);
|
|
211
|
+
* world.system("Logger").tickSource(second).run(logStats);
|
|
212
|
+
* ```
|
|
213
|
+
*/
|
|
214
|
+
tickSource(source) {
|
|
215
|
+
this._setTickSource(source);
|
|
216
|
+
return this;
|
|
217
|
+
}
|
|
218
|
+
_setTickSource(source) {
|
|
219
|
+
this._tickSource = source;
|
|
220
|
+
source._register(this.world);
|
|
221
|
+
}
|
|
133
222
|
/**
|
|
134
223
|
* Assign this system to a pipeline phase.
|
|
135
224
|
*
|
|
@@ -162,7 +251,9 @@ export class System extends Query {
|
|
|
162
251
|
* network flushing, global timers, etc.
|
|
163
252
|
*
|
|
164
253
|
* @param callback - Receives `now` (absolute timestamp in ms) and `delta`
|
|
165
|
-
* (ms since the previous tick).
|
|
254
|
+
* (ms since the previous tick). If the system has an active interval,
|
|
255
|
+
* rate, or tick source, `delta` is the accumulated milliseconds since this
|
|
256
|
+
* system last fired.
|
|
166
257
|
* @returns This system, for chaining.
|
|
167
258
|
*/
|
|
168
259
|
run(callback) {
|
|
@@ -173,7 +264,7 @@ export class System extends Query {
|
|
|
173
264
|
* Register a callback fired **every tick** for **every tracked entity**,
|
|
174
265
|
* unconditionally, with the listed components resolved from each entity.
|
|
175
266
|
*
|
|
176
|
-
* Unlike {@link update} (which only fires when `
|
|
267
|
+
* Unlike {@link update} (which only fires when `entity.modified(C)` is
|
|
177
268
|
* called), `each` fires every tick the system runs, once per tracked entity.
|
|
178
269
|
* Components declared via {@link requires} are non-nullable in the resolved
|
|
179
270
|
* tuple; any other component class may be `undefined` if the entity lacks it.
|
|
@@ -247,6 +338,55 @@ export class System extends Query {
|
|
|
247
338
|
super.requires(...components);
|
|
248
339
|
return this;
|
|
249
340
|
}
|
|
341
|
+
/**
|
|
342
|
+
* Disable this system.
|
|
343
|
+
*
|
|
344
|
+
* While disabled the system is effectively invisible: the inbox is cleared
|
|
345
|
+
* immediately, any new `enter`, `exit`, or `update` events are silently
|
|
346
|
+
* dropped, and {@link _run} returns without executing any callbacks. Entity
|
|
347
|
+
* membership in the underlying query is still maintained so the tracked set
|
|
348
|
+
* remains consistent and the system resumes correctly when
|
|
349
|
+
* {@link enable} is called.
|
|
350
|
+
*
|
|
351
|
+
* Disabling is independent from tick-source cadence: `disable` suppresses
|
|
352
|
+
* callbacks, but a disabled system used as a tick source still drives
|
|
353
|
+
* downstream consumers. Use `stop()` on an external `IntervalTickSource` or
|
|
354
|
+
* `RateTickSource` reference to halt that clock itself.
|
|
355
|
+
*
|
|
356
|
+
* Calling `disable` on an already-disabled system is a no-op.
|
|
357
|
+
*
|
|
358
|
+
* @returns This system, for chaining.
|
|
359
|
+
*
|
|
360
|
+
* @example
|
|
361
|
+
* ```ts
|
|
362
|
+
* const sys = world.system("AI").requires(Enemy).run(runAI);
|
|
363
|
+
* // Pause AI processing during a cutscene:
|
|
364
|
+
* sys.disable();
|
|
365
|
+
* // Resume:
|
|
366
|
+
* sys.enable();
|
|
367
|
+
* ```
|
|
368
|
+
*/
|
|
369
|
+
disable() {
|
|
370
|
+
this._enabled = false;
|
|
371
|
+
this._inbox.length = 0;
|
|
372
|
+
return this;
|
|
373
|
+
}
|
|
374
|
+
/**
|
|
375
|
+
* Enable this system after a previous {@link disable} call.
|
|
376
|
+
*
|
|
377
|
+
* Once re-enabled the system resumes its normal tick behaviour: enter, exit,
|
|
378
|
+
* and update events are queued, and {@link _run} processes the inbox and fires
|
|
379
|
+
* all registered callbacks. Events that occurred while the system was disabled
|
|
380
|
+
* are not replayed.
|
|
381
|
+
*
|
|
382
|
+
* Calling `enable` on an already-enabled system is a no-op.
|
|
383
|
+
*
|
|
384
|
+
* @returns This system, for chaining.
|
|
385
|
+
*/
|
|
386
|
+
enable() {
|
|
387
|
+
this._enabled = true;
|
|
388
|
+
return this;
|
|
389
|
+
}
|
|
250
390
|
/**
|
|
251
391
|
* Not supported on `System`. Throws unconditionally.
|
|
252
392
|
*
|
package/dist/system.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"system.js","sourceRoot":"","sources":["../src/system.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAGnC,OAAO,EAAE,KAAK,EAAe,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"system.js","sourceRoot":"","sources":["../src/system.ts"],"names":[],"mappings":"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"}
|
package/dist/timer.d.ts
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/** A clock that the world evaluates once per frame. */
|
|
2
|
+
export interface ITickSource {
|
|
3
|
+
/** True when this source fired during the current frame. */
|
|
4
|
+
readonly didTick: boolean;
|
|
5
|
+
/** Milliseconds accumulated into the most recent fire. */
|
|
6
|
+
readonly lastFireDelta: number;
|
|
7
|
+
}
|
|
8
|
+
/** Shared state and start/stop control for concrete tick sources. */
|
|
9
|
+
declare abstract class BaseTickSource implements ITickSource {
|
|
10
|
+
get didTick(): boolean;
|
|
11
|
+
get lastFireDelta(): number;
|
|
12
|
+
/** Resume this source without replaying time elapsed while stopped. */
|
|
13
|
+
start(): this;
|
|
14
|
+
/** Pause this source, freezing accumulators and counters until `start()`. */
|
|
15
|
+
stop(): this;
|
|
16
|
+
}
|
|
17
|
+
/** Fires every `intervalSeconds` of accumulated wall-clock time. */
|
|
18
|
+
export declare class IntervalTickSource extends BaseTickSource {
|
|
19
|
+
private readonly _intervalMs;
|
|
20
|
+
private _accumulator;
|
|
21
|
+
/**
|
|
22
|
+
* Create an interval source.
|
|
23
|
+
*
|
|
24
|
+
* Intervals are expressed in seconds, unlike `World.progress` and
|
|
25
|
+
* `World.beginFrame`, which receive millisecond deltas. Large deltas produce
|
|
26
|
+
* at most one tick; residual time is preserved by subtracting the interval.
|
|
27
|
+
*
|
|
28
|
+
* @param intervalSeconds - Positive interval duration in seconds.
|
|
29
|
+
* @throws When `intervalSeconds` is less than or equal to zero.
|
|
30
|
+
*/
|
|
31
|
+
constructor(intervalSeconds: number);
|
|
32
|
+
}
|
|
33
|
+
/** Fires every `rate` ticks of `source`, or every `rate` frames without one. */
|
|
34
|
+
export declare class RateTickSource extends BaseTickSource {
|
|
35
|
+
private readonly _rate;
|
|
36
|
+
private _counter;
|
|
37
|
+
/**
|
|
38
|
+
* Create a rate filter.
|
|
39
|
+
*
|
|
40
|
+
* Without `source`, this counts world frames. With `source`, it counts ticks
|
|
41
|
+
* from that upstream clock. The source is immutable, so cyclic source graphs
|
|
42
|
+
* cannot be constructed through the public API.
|
|
43
|
+
*
|
|
44
|
+
* @param rate - Positive integer tick divisor.
|
|
45
|
+
* @param source - Optional upstream source to divide.
|
|
46
|
+
* @throws When `rate` is not a positive integer.
|
|
47
|
+
*/
|
|
48
|
+
constructor(rate: number, source?: ITickSource);
|
|
49
|
+
}
|
|
50
|
+
export {};
|