@aethervtt/shard-runtime 0.0.1 → 0.2.0
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/dist/app.d.ts +145 -1
- package/dist/app.js +333 -17
- package/dist/budgets.d.ts +197 -0
- package/dist/budgets.js +256 -0
- package/dist/control.d.ts +2 -0
- package/dist/control.js +7 -1
- package/dist/demand.d.ts +47 -0
- package/dist/demand.js +68 -0
- package/dist/index.d.ts +6 -2
- package/dist/index.js +55 -1
- package/dist/perf.d.ts +157 -0
- package/dist/perf.js +245 -0
- package/dist/plugin.d.ts +12 -0
- package/dist/runners.d.ts +17 -2
- package/dist/runners.js +130 -48
- package/dist/scenario.d.ts +9 -0
- package/dist/scenario.js +9 -0
- package/dist/testing.d.ts +22 -0
- package/dist/testing.js +64 -0
- package/dist/time.d.ts +4 -0
- package/dist/time.js +5 -0
- package/dist/write-check.d.ts +22 -0
- package/dist/write-check.js +54 -0
- package/package.json +7 -3
package/dist/app.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type ComponentDef, type ResourceDef, type ScheduleLabel, type SystemConfig, type SystemDef, type SystemDescription, type SystemSetConfig, World } from '@aethervtt/shard-core';
|
|
1
|
+
import { type ComponentDef, type ProfilerSettingsData, type ResourceDef, type ScheduleLabel, type SystemConfig, type SystemDef, type SystemDescription, type SystemSetConfig, World } from '@aethervtt/shard-core';
|
|
2
2
|
import type { Plugin } from './plugin.js';
|
|
3
3
|
import type { Runner } from './runners.js';
|
|
4
4
|
import { type StateDef } from './state.js';
|
|
@@ -11,6 +11,24 @@ export interface AppOptions {
|
|
|
11
11
|
now?: () => number;
|
|
12
12
|
/** Seed for the `GlobalRng` resource. Default 0. */
|
|
13
13
|
seed?: number;
|
|
14
|
+
/**
|
|
15
|
+
* A development build: missing assets show loudly (checkers), and dev-only checks and issues
|
|
16
|
+
* run (shader cache misses, color-space mismatches, GL error checks). Read it from `DevMode`.
|
|
17
|
+
* Default false.
|
|
18
|
+
*/
|
|
19
|
+
dev?: boolean;
|
|
20
|
+
/**
|
|
21
|
+
* The profiler (0074): `enabled: false` turns spans off for builds that want every microsecond;
|
|
22
|
+
* `window` is how many runs aggregates cover. Also `ProfilerSettings` at runtime. Default on, 120.
|
|
23
|
+
*/
|
|
24
|
+
profiler?: Partial<ProfilerSettingsData>;
|
|
25
|
+
/**
|
|
26
|
+
* The budget scenario the app runs as (0075, `bench/perf/budgets.json`): features that adapt
|
|
27
|
+
* (0045's foliage) default their target to their slice of its frame, and the `perf` overlay shows
|
|
28
|
+
* its slices. Default none: nothing adapts. Also `App.perfScenario` and the `PerfScenario`
|
|
29
|
+
* resource at runtime.
|
|
30
|
+
*/
|
|
31
|
+
perfScenario?: string | null;
|
|
14
32
|
}
|
|
15
33
|
export interface AppDescription {
|
|
16
34
|
plugins: {
|
|
@@ -39,6 +57,39 @@ export interface AppMethod {
|
|
|
39
57
|
world: World;
|
|
40
58
|
}, params: Record<string, unknown>): unknown;
|
|
41
59
|
}
|
|
60
|
+
/**
|
|
61
|
+
* Code the app runs happens inside its scopes: plugin builds and ready hooks, frames, pumps, and
|
|
62
|
+
* disposal. The render plugin uses one to count GPU objects against the app (0052).
|
|
63
|
+
*/
|
|
64
|
+
export interface AppScope {
|
|
65
|
+
enter(): void;
|
|
66
|
+
exit(): void;
|
|
67
|
+
}
|
|
68
|
+
/** What a loop runner gives the app while it drives it (0052). */
|
|
69
|
+
export interface FrameDriver {
|
|
70
|
+
/** Schedules a frame if none is coming (on-demand); a no-op for runners that run every frame. */
|
|
71
|
+
requestFrame(): void;
|
|
72
|
+
/** Stops the loop for good. */
|
|
73
|
+
stop(): void;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Waits until what the last frame drew is on screen (0062), resolving with when that was on the
|
|
77
|
+
* app's clock if it knows better than "now". The render plugin sets one: the frame's GPU work done,
|
|
78
|
+
* then the next animation frame, whose timestamp it resolves with. Without one, a frame counts as
|
|
79
|
+
* presented when it ends.
|
|
80
|
+
*/
|
|
81
|
+
export type FramePresenter = () => Promise<number | undefined>;
|
|
82
|
+
/** When the app started and became usable, in ms on its clock (`AppOptions.now`) (0062). */
|
|
83
|
+
export interface StartupTimings {
|
|
84
|
+
/** `init()` was called. NaN before. */
|
|
85
|
+
initStart: number;
|
|
86
|
+
/** `init()` resolved. NaN before. */
|
|
87
|
+
initEnd: number;
|
|
88
|
+
/** The host called `markUsable()`. NaN before. */
|
|
89
|
+
usableMarked: number;
|
|
90
|
+
/** The first frame after `markUsable()` was presented. NaN before. */
|
|
91
|
+
usable: number;
|
|
92
|
+
}
|
|
42
93
|
/**
|
|
43
94
|
* Owns the world, plugins, and schedules, and runs frames. Hosts drive it with a runner
|
|
44
95
|
* (animation frame, headless, or manual `update` calls).
|
|
@@ -50,6 +101,11 @@ export declare class App {
|
|
|
50
101
|
private readonly now;
|
|
51
102
|
private readonly plugins;
|
|
52
103
|
private readonly pending;
|
|
104
|
+
/** Plugins in the order they were built; disposal runs it backwards. */
|
|
105
|
+
private readonly built;
|
|
106
|
+
private readonly scopes;
|
|
107
|
+
private driver;
|
|
108
|
+
private disposing;
|
|
53
109
|
private readonly schedules;
|
|
54
110
|
private readonly systemNames;
|
|
55
111
|
private readonly states;
|
|
@@ -59,6 +115,12 @@ export declare class App {
|
|
|
59
115
|
private startupDone;
|
|
60
116
|
private accumulator;
|
|
61
117
|
private readonly frameListeners;
|
|
118
|
+
private presenter;
|
|
119
|
+
/** Traces stamped since the last frame started; the next frame carries them. */
|
|
120
|
+
private readonly traces;
|
|
121
|
+
private readonly traceListeners;
|
|
122
|
+
private readonly usableWaiters;
|
|
123
|
+
private readonly startup_;
|
|
62
124
|
private readonly appMethods;
|
|
63
125
|
/** The plugin whose `build` is running, so registrations can be attributed to it. */
|
|
64
126
|
private building;
|
|
@@ -68,6 +130,12 @@ export declare class App {
|
|
|
68
130
|
addPlugin(...plugins: Plugin[]): this;
|
|
69
131
|
/** Adds protocol methods (see `AppMethod`). A second method with a taken name throws. */
|
|
70
132
|
addMethod(...methods: AppMethod[]): this;
|
|
133
|
+
/**
|
|
134
|
+
* The budget scenario the app declares (0075): features with a budget resource adapt to their
|
|
135
|
+
* slice of its frame, and the `perf` overlay shows its slices. null (the default): none.
|
|
136
|
+
*/
|
|
137
|
+
get perfScenario(): string | null;
|
|
138
|
+
set perfScenario(name: string | null);
|
|
71
139
|
/** Methods plugins added, in the order they were added. */
|
|
72
140
|
get methods(): readonly AppMethod[];
|
|
73
141
|
addSystems(schedule: ScheduleLabel, ...systems: SystemInput[]): this;
|
|
@@ -95,8 +163,70 @@ export declare class App {
|
|
|
95
163
|
init(): Promise<void>;
|
|
96
164
|
/** Initializes, then hands control to the runner (manual if none was set). */
|
|
97
165
|
run(): Promise<void>;
|
|
166
|
+
/**
|
|
167
|
+
* Stops the runner, waits for every plugin's work in flight (`beforeDispose`), then disposes
|
|
168
|
+
* plugins in reverse build order, so each releases what it created: GPU objects, surfaces,
|
|
169
|
+
* listeners, workers (0052). Idempotent; afterwards any other
|
|
170
|
+
* call throws `runtime/disposed`. A plugin whose dispose throws is logged and the rest still run.
|
|
171
|
+
*/
|
|
172
|
+
dispose(): Promise<void>;
|
|
173
|
+
/** True once `dispose()` was called. */
|
|
174
|
+
get disposed(): boolean;
|
|
175
|
+
/**
|
|
176
|
+
* Adds a scope around everything the app runs (see `AppScope`). Returns a function that removes
|
|
177
|
+
* it; don't call that from inside the app's own code (a frame, a plugin's dispose): disposal
|
|
178
|
+
* drops every scope once plugins are done. Scopes enter in the order added and exit in reverse.
|
|
179
|
+
*/
|
|
180
|
+
addScope(scope: AppScope): () => void;
|
|
181
|
+
/**
|
|
182
|
+
* Called by a loop runner as it starts. `requestFrame` and `dispose` reach the loop through it.
|
|
183
|
+
*/
|
|
184
|
+
attachDriver(driver: FrameDriver): void;
|
|
185
|
+
/**
|
|
186
|
+
* Asks for a frame: an on-demand runner schedules one if none is coming (0052). Host code that
|
|
187
|
+
* changes what's on screen without writing the world (a canvas style, a DOM overlay) calls it.
|
|
188
|
+
*/
|
|
189
|
+
requestFrame(): void;
|
|
190
|
+
/** Sets how a frame waits to be on screen (see `FramePresenter`). The render plugin calls it. */
|
|
191
|
+
setPresenter(presenter: FramePresenter | undefined): void;
|
|
192
|
+
/** When init started and ended and when the app became usable, in ms on the app's clock. */
|
|
193
|
+
get startup(): Readonly<StartupTimings>;
|
|
194
|
+
/**
|
|
195
|
+
* The host says the app is usable (for a VTT, once the scene is interactive). The first complete
|
|
196
|
+
* frame presented after this is the first usable frame (`startup.usable`, `whenUsable()`). Later
|
|
197
|
+
* calls do nothing.
|
|
198
|
+
*/
|
|
199
|
+
markUsable(): void;
|
|
200
|
+
/** Resolves with `startup.usable` once the first usable frame is presented. */
|
|
201
|
+
whenUsable(): Promise<number>;
|
|
202
|
+
/**
|
|
203
|
+
* Stamps a host write (a patch, a token move) for latency: resolves with the ms from now until the
|
|
204
|
+
* frame that carries it is presented. Call it right after the write. The next frame to start
|
|
205
|
+
* carries every trace stamped before it; a frame that ends still loading (`LOADING_DEMAND`: a
|
|
206
|
+
* pipeline compiling, a mesh not uploaded) hands them on, so the latency runs until the write is
|
|
207
|
+
* visible. `onTrace` listeners see each result.
|
|
208
|
+
*/
|
|
209
|
+
trace(label: string): Promise<number>;
|
|
210
|
+
/**
|
|
211
|
+
* Requests a frame and resolves (with the ms waited) once a complete frame is presented, as
|
|
212
|
+
* `trace` does, but no `onTrace` listener sees it: for tools waiting on the screen, not for
|
|
213
|
+
* latency.
|
|
214
|
+
*/
|
|
215
|
+
whenPresented(): Promise<number>;
|
|
216
|
+
/** Called with every resolved trace: its label and latency in ms. Returns an unsubscribe function. */
|
|
217
|
+
onTrace(listener: (label: string, ms: number) => void): () => void;
|
|
218
|
+
/**
|
|
219
|
+
* Drops accumulated fixed-step time, so the next frame runs FixedUpdate for its own delta only.
|
|
220
|
+
* On-demand runners call it on waking, so a scene idle for a minute doesn't simulate the minute.
|
|
221
|
+
*/
|
|
222
|
+
resetFixedTime(): void;
|
|
98
223
|
/** Runs one frame. `delta` is in seconds. */
|
|
99
224
|
update(delta: number): void;
|
|
225
|
+
/** One frame, timed as the `frame` span (0074). */
|
|
226
|
+
private frame;
|
|
227
|
+
private frameBody;
|
|
228
|
+
/** Resolves traces and the usable mark once this frame is on screen. */
|
|
229
|
+
private present;
|
|
100
230
|
/** Called after every frame with the number of frames completed. Returns an unsubscribe function. */
|
|
101
231
|
onFrame(listener: (frame: number) => void): () => void;
|
|
102
232
|
/**
|
|
@@ -106,6 +236,20 @@ export declare class App {
|
|
|
106
236
|
pump(): void;
|
|
107
237
|
runSchedule(label: ScheduleLabel): void;
|
|
108
238
|
describe(): AppDescription;
|
|
239
|
+
private assertLive;
|
|
240
|
+
/**
|
|
241
|
+
* Runs `fn` inside the app's scopes, as build and ready hooks run. For the part of an async ready
|
|
242
|
+
* hook after its first await, which runs outside them: what it makes counts against the app.
|
|
243
|
+
*/
|
|
244
|
+
scoped<T>(fn: () => T): T;
|
|
245
|
+
/** Enters every scope; returns how many, for the matching `exit`. */
|
|
246
|
+
private enter;
|
|
247
|
+
/** Exits the first `n` scopes, so one added inside the section never sees an unmatched exit. */
|
|
248
|
+
private exit;
|
|
249
|
+
private buildPlugin;
|
|
250
|
+
/** Awaits a ready hook; the part that runs before its first await is inside the app's scopes. */
|
|
251
|
+
private readyPlugin;
|
|
252
|
+
private disposeAll;
|
|
109
253
|
private schedule;
|
|
110
254
|
private applyStateTransitions;
|
|
111
255
|
private dependencyError;
|