iris-ecs 0.0.1 → 0.0.2

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.
@@ -1,10 +1,69 @@
1
1
  import type { World } from "./world.js";
2
2
  /**
3
- * Schedule identifier.
3
+ * Schedule label brand for nominal typing.
4
+ */
5
+ declare const SCHEDULE_LABEL_BRAND: unique symbol;
6
+ /**
7
+ * Schedule label (branded string).
8
+ *
9
+ * Identifies a schedule within the pipeline. Built-in labels are provided
10
+ * for common lifecycle stages, custom labels created via defineSchedule().
11
+ */
12
+ export type ScheduleLabel = string & {
13
+ [SCHEDULE_LABEL_BRAND]: true;
14
+ };
15
+ /**
16
+ * Define a custom schedule label.
17
+ *
18
+ * @param name - Schedule name (must be unique when inserted into pipeline)
19
+ * @returns Schedule label
20
+ *
21
+ * @example
22
+ * ```typescript
23
+ * const Physics = defineSchedule("Physics");
24
+ * insertScheduleAfter(world, Physics, PreUpdate);
25
+ * addSystem(world, gravitySystem, { schedule: Physics });
26
+ * ```
27
+ */
28
+ export declare function defineSchedule(name: string): ScheduleLabel;
29
+ /**
30
+ * Startup schedule. Runs once before the first frame.
31
+ */
32
+ export declare const Startup: ScheduleLabel;
33
+ /**
34
+ * Shutdown schedule. Runs once when stop() is called.
35
+ */
36
+ export declare const Shutdown: ScheduleLabel;
37
+ /**
38
+ * First schedule in the main loop. Runs every frame before PreUpdate.
4
39
  *
5
- * Provides autocomplete for common schedules while allowing custom names.
40
+ * @example
41
+ * ```typescript
42
+ * addSystem(world, inputSystem, { schedule: First });
43
+ * ```
44
+ */
45
+ export declare const First: ScheduleLabel;
46
+ /**
47
+ * Pre-update schedule. Runs every frame before Update.
48
+ */
49
+ export declare const PreUpdate: ScheduleLabel;
50
+ /**
51
+ * Update schedule. Default schedule for systems. Runs every frame.
52
+ *
53
+ * @example
54
+ * ```typescript
55
+ * addSystem(world, physicsSystem); // defaults to Update
56
+ * ```
6
57
  */
7
- export type ScheduleId = "runtime" | "startup" | "shutdown" | (string & {});
58
+ export declare const Update: ScheduleLabel;
59
+ /**
60
+ * Post-update schedule. Runs every frame after Update.
61
+ */
62
+ export declare const PostUpdate: ScheduleLabel;
63
+ /**
64
+ * Last schedule in the main loop. Runs every frame after PostUpdate.
65
+ */
66
+ export declare const Last: ScheduleLabel;
8
67
  /**
9
68
  * System function signature.
10
69
  *
@@ -20,9 +79,9 @@ export type SystemOptions = {
20
79
  */
21
80
  name?: string;
22
81
  /**
23
- * Schedule this system belongs to. Defaults to 'runtime'.
82
+ * Schedule this system belongs to. Defaults to Update.
24
83
  */
25
- schedule?: ScheduleId;
84
+ schedule?: ScheduleLabel;
26
85
  /**
27
86
  * Run before these systems (within same schedule).
28
87
  */
@@ -43,7 +102,7 @@ export type SystemMeta = {
43
102
  /**
44
103
  * Schedule this system belongs to.
45
104
  */
46
- schedule: ScheduleId;
105
+ schedule: ScheduleLabel;
47
106
  /**
48
107
  * Registration order (for stable sort).
49
108
  */
@@ -63,44 +122,87 @@ export type SystemMeta = {
63
122
  * @param world - World instance
64
123
  * @param runner - System function (must be named unless name option provided)
65
124
  * @param options - Registration options (name, schedule, before, after)
66
- * @returns void
125
+ *
67
126
  * @example
127
+ * ```typescript
68
128
  * addSystem(world, physicsSystem);
69
- * addSystem(world, renderSystem, { after: "physicsSystem" });
129
+ * addSystem(world, renderSystem, { schedule: PostUpdate, after: "physicsSystem" });
130
+ * ```
70
131
  */
71
132
  export declare function addSystem(world: World, runner: SystemRunner, options?: SystemOptions): void;
72
133
  /**
73
- * Builds an execution order from registered systems using topological sort.
74
- * Systems are ordered by before/after constraints, with registration order as tiebreaker.
134
+ * Insert a schedule before an existing schedule in the pipeline.
135
+ *
136
+ * @param world - World instance
137
+ * @param schedule - New schedule label to insert
138
+ * @param anchor - Existing schedule label to insert before
139
+ *
140
+ * @example
141
+ * ```typescript
142
+ * const Physics = defineSchedule("Physics");
143
+ * insertScheduleBefore(world, Physics, Update);
144
+ * ```
145
+ */
146
+ export declare function insertScheduleBefore(world: World, schedule: ScheduleLabel, anchor: ScheduleLabel): void;
147
+ /**
148
+ * Insert a schedule after an existing schedule in the pipeline.
75
149
  *
76
150
  * @param world - World instance
77
- * @param scheduleId - Schedule identifier (defaults to "runtime")
78
- * @returns void
151
+ * @param schedule - New schedule label to insert
152
+ * @param anchor - Existing schedule label to insert after
153
+ *
79
154
  * @example
80
- * buildSchedule(world);
81
- * buildSchedule(world, "startup");
155
+ * ```typescript
156
+ * const Render = defineSchedule("Render");
157
+ * insertScheduleAfter(world, Render, PostUpdate);
158
+ * ```
82
159
  */
83
- export declare function buildSchedule(world: World, scheduleId?: ScheduleId): void;
160
+ export declare function insertScheduleAfter(world: World, schedule: ScheduleLabel, anchor: ScheduleLabel): void;
84
161
  /**
85
- * Executes a schedule synchronously. Throws if any system returns a Promise.
162
+ * Execute one frame. Runs startup on first call, then all pipeline schedules,
163
+ * then flushes events.
86
164
  *
87
165
  * @param world - World instance
88
- * @param scheduleId - Schedule identifier (defaults to "runtime")
89
- * @returns void
166
+ * @returns Promise that resolves when the frame completes
167
+ *
90
168
  * @example
91
- * executeSchedule(world);
92
- * executeSchedule(world, "startup");
169
+ * ```typescript
170
+ * // Game loop
171
+ * await runOnce(world);
172
+ * ```
93
173
  */
94
- export declare function executeSchedule(world: World, scheduleId?: ScheduleId): void;
174
+ export declare function runOnce(world: World): Promise<void>;
95
175
  /**
96
- * Executes a schedule with async support. Awaits systems that return Promises.
176
+ * Start the main loop using requestAnimationFrame.
177
+ *
178
+ * Startup schedule runs automatically on first frame. Each frame executes
179
+ * all pipeline schedules in order. Call stop() to end the loop.
97
180
  *
98
181
  * @param world - World instance
99
- * @param scheduleId - Schedule identifier (defaults to "runtime")
100
- * @returns Promise that resolves when all systems complete
182
+ *
183
+ * @example
184
+ * ```typescript
185
+ * addSystem(world, physicsSystem);
186
+ * addSystem(world, renderSystem, { schedule: PostUpdate });
187
+ * run(world);
188
+ * // ... later
189
+ * await stop(world);
190
+ * ```
191
+ */
192
+ export declare function run(world: World): void;
193
+ /**
194
+ * Stop the main loop and run the shutdown schedule.
195
+ *
196
+ * @param world - World instance
197
+ * @returns Promise that resolves when shutdown completes
198
+ *
101
199
  * @example
102
- * await executeScheduleAsync(world);
103
- * await executeScheduleAsync(world, "startup");
200
+ * ```typescript
201
+ * run(world);
202
+ * // ... later
203
+ * await stop(world);
204
+ * ```
104
205
  */
105
- export declare function executeScheduleAsync(world: World, scheduleId?: ScheduleId): Promise<void>;
206
+ export declare function stop(world: World): Promise<void>;
207
+ export {};
106
208
  //# sourceMappingURL=scheduler.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../src/scheduler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAMxC;;;;GAIG;AACH,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,SAAS,GAAG,UAAU,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAE5E;;;;GAIG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAElE;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,QAAQ,CAAC,EAAE,UAAU,CAAC;IAEtB;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAE3B;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;CAC3B,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG;IACvB;;OAEG;IACH,MAAM,EAAE,YAAY,CAAC;IAErB;;OAEG;IACH,QAAQ,EAAE,UAAU,CAAC;IAErB;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,MAAM,EAAE,MAAM,EAAE,CAAC;IAEjB;;OAEG;IACH,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB,CAAC;AAEF;;;;;;;;;;GAUG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,IAAI,CAuB3F;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,KAAK,EAAE,UAAU,GAAE,UAAsB,GAAG,IAAI,CAwFpF;AA0BD;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,KAAK,EAAE,UAAU,GAAE,UAAsB,GAAG,IAAI,CA2BtF;AAED;;;;;;;;;GASG;AACH,wBAAsB,oBAAoB,CAAC,KAAK,EAAE,KAAK,EAAE,UAAU,GAAE,UAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,CA2B1G"}
1
+ {"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../src/scheduler.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAMxC;;GAEG;AACH,OAAO,CAAC,MAAM,oBAAoB,EAAE,OAAO,MAAM,CAAC;AAElD;;;;;GAKG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG;IAAE,CAAC,oBAAoB,CAAC,EAAE,IAAI,CAAA;CAAE,CAAC;AAMtE;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,CAE1D;AAMD;;GAEG;AACH,eAAO,MAAM,OAAO,eAA4B,CAAC;AAEjD;;GAEG;AACH,eAAO,MAAM,QAAQ,eAA6B,CAAC;AAEnD;;;;;;;GAOG;AACH,eAAO,MAAM,KAAK,eAA0B,CAAC;AAE7C;;GAEG;AACH,eAAO,MAAM,SAAS,eAA8B,CAAC;AAErD;;;;;;;GAOG;AACH,eAAO,MAAM,MAAM,eAA2B,CAAC;AAE/C;;GAEG;AACH,eAAO,MAAM,UAAU,eAA+B,CAAC;AAEvD;;GAEG;AACH,eAAO,MAAM,IAAI,eAAyB,CAAC;AAM3C;;;;GAIG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAElE;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,QAAQ,CAAC,EAAE,aAAa,CAAC;IAEzB;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAE3B;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;CAC3B,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG;IACvB;;OAEG;IACH,MAAM,EAAE,YAAY,CAAC;IAErB;;OAEG;IACH,QAAQ,EAAE,aAAa,CAAC;IAExB;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,MAAM,EAAE,MAAM,EAAE,CAAC;IAEjB;;OAEG;IACH,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB,CAAC;AAMF;;;;;;;;;;;;GAYG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,IAAI,CAyB3F;AAMD;;;;;;;;;;;;GAYG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,EAAE,aAAa,GAAG,IAAI,CAavG;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,EAAE,aAAa,GAAG,IAAI,CAatG;AAoLD;;;;;;;;;;;;GAYG;AACH,wBAAsB,OAAO,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAoBzD;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,GAAG,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAOtC;AAyBD;;;;;;;;;;;;GAYG;AACH,wBAAsB,IAAI,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAkBtD"}
package/dist/scheduler.js CHANGED
@@ -1,13 +1,79 @@
1
+ import { flushEvents } from "./event.js";
2
+ // ============================================================================
3
+ // Schedule Definition
4
+ // ============================================================================
5
+ /**
6
+ * Define a custom schedule label.
7
+ *
8
+ * @param name - Schedule name (must be unique when inserted into pipeline)
9
+ * @returns Schedule label
10
+ *
11
+ * @example
12
+ * ```typescript
13
+ * const Physics = defineSchedule("Physics");
14
+ * insertScheduleAfter(world, Physics, PreUpdate);
15
+ * addSystem(world, gravitySystem, { schedule: Physics });
16
+ * ```
17
+ */
18
+ export function defineSchedule(name) {
19
+ return name;
20
+ }
21
+ // ============================================================================
22
+ // Built-in Schedule Labels
23
+ // ============================================================================
24
+ /**
25
+ * Startup schedule. Runs once before the first frame.
26
+ */
27
+ export const Startup = defineSchedule("Startup");
28
+ /**
29
+ * Shutdown schedule. Runs once when stop() is called.
30
+ */
31
+ export const Shutdown = defineSchedule("Shutdown");
32
+ /**
33
+ * First schedule in the main loop. Runs every frame before PreUpdate.
34
+ *
35
+ * @example
36
+ * ```typescript
37
+ * addSystem(world, inputSystem, { schedule: First });
38
+ * ```
39
+ */
40
+ export const First = defineSchedule("First");
41
+ /**
42
+ * Pre-update schedule. Runs every frame before Update.
43
+ */
44
+ export const PreUpdate = defineSchedule("PreUpdate");
45
+ /**
46
+ * Update schedule. Default schedule for systems. Runs every frame.
47
+ *
48
+ * @example
49
+ * ```typescript
50
+ * addSystem(world, physicsSystem); // defaults to Update
51
+ * ```
52
+ */
53
+ export const Update = defineSchedule("Update");
54
+ /**
55
+ * Post-update schedule. Runs every frame after Update.
56
+ */
57
+ export const PostUpdate = defineSchedule("PostUpdate");
58
+ /**
59
+ * Last schedule in the main loop. Runs every frame after PostUpdate.
60
+ */
61
+ export const Last = defineSchedule("Last");
62
+ // ============================================================================
63
+ // System Registration
64
+ // ============================================================================
1
65
  /**
2
66
  * Registers a system in the world for later scheduling.
3
67
  *
4
68
  * @param world - World instance
5
69
  * @param runner - System function (must be named unless name option provided)
6
70
  * @param options - Registration options (name, schedule, before, after)
7
- * @returns void
71
+ *
8
72
  * @example
73
+ * ```typescript
9
74
  * addSystem(world, physicsSystem);
10
- * addSystem(world, renderSystem, { after: "physicsSystem" });
75
+ * addSystem(world, renderSystem, { schedule: PostUpdate, after: "physicsSystem" });
76
+ * ```
11
77
  */
12
78
  export function addSystem(world, runner, options) {
13
79
  // Derive system name from function name or explicit option
@@ -23,33 +89,81 @@ export function addSystem(world, runner, options) {
23
89
  const after = options?.after;
24
90
  world.systems.byId.set(name, {
25
91
  runner,
26
- schedule: options?.schedule ?? "runtime",
92
+ schedule: options?.schedule ?? Update,
27
93
  index: world.systems.nextIndex++,
28
94
  before: !before ? [] : Array.isArray(before) ? before : [before],
29
95
  after: !after ? [] : Array.isArray(after) ? after : [after],
30
96
  });
97
+ world.schedules.dirty = true;
31
98
  }
99
+ // ============================================================================
100
+ // Pipeline Management
101
+ // ============================================================================
32
102
  /**
33
- * Builds an execution order from registered systems using topological sort.
34
- * Systems are ordered by before/after constraints, with registration order as tiebreaker.
103
+ * Insert a schedule before an existing schedule in the pipeline.
104
+ *
105
+ * @param world - World instance
106
+ * @param schedule - New schedule label to insert
107
+ * @param anchor - Existing schedule label to insert before
108
+ *
109
+ * @example
110
+ * ```typescript
111
+ * const Physics = defineSchedule("Physics");
112
+ * insertScheduleBefore(world, Physics, Update);
113
+ * ```
114
+ */
115
+ export function insertScheduleBefore(world, schedule, anchor) {
116
+ const idx = world.schedules.pipeline.indexOf(anchor);
117
+ if (idx === -1) {
118
+ throw new Error(`Schedule "${anchor}" not found in pipeline`);
119
+ }
120
+ if (world.schedules.pipeline.includes(schedule)) {
121
+ throw new Error(`Schedule "${schedule}" already in pipeline`);
122
+ }
123
+ world.schedules.pipeline.splice(idx, 0, schedule);
124
+ world.schedules.dirty = true;
125
+ }
126
+ /**
127
+ * Insert a schedule after an existing schedule in the pipeline.
35
128
  *
36
129
  * @param world - World instance
37
- * @param scheduleId - Schedule identifier (defaults to "runtime")
38
- * @returns void
130
+ * @param schedule - New schedule label to insert
131
+ * @param anchor - Existing schedule label to insert after
132
+ *
39
133
  * @example
40
- * buildSchedule(world);
41
- * buildSchedule(world, "startup");
134
+ * ```typescript
135
+ * const Render = defineSchedule("Render");
136
+ * insertScheduleAfter(world, Render, PostUpdate);
137
+ * ```
138
+ */
139
+ export function insertScheduleAfter(world, schedule, anchor) {
140
+ const idx = world.schedules.pipeline.indexOf(anchor);
141
+ if (idx === -1) {
142
+ throw new Error(`Schedule "${anchor}" not found in pipeline`);
143
+ }
144
+ if (world.schedules.pipeline.includes(schedule)) {
145
+ throw new Error(`Schedule "${schedule}" already in pipeline`);
146
+ }
147
+ world.schedules.pipeline.splice(idx + 1, 0, schedule);
148
+ world.schedules.dirty = true;
149
+ }
150
+ // ============================================================================
151
+ // Schedule Building (Internal)
152
+ // ============================================================================
153
+ /**
154
+ * Builds an execution order from registered systems using topological sort.
155
+ * Systems are ordered by before/after constraints, with registration order as tiebreaker.
42
156
  */
43
- export function buildSchedule(world, scheduleId = "runtime") {
157
+ function buildSchedule(world, scheduleLabel) {
44
158
  // Filter systems belonging to this schedule
45
159
  const scheduleSystems = new Map();
46
160
  for (const [name, meta] of world.systems.byId) {
47
- if (meta.schedule === scheduleId) {
161
+ if (meta.schedule === scheduleLabel) {
48
162
  scheduleSystems.set(name, meta);
49
163
  }
50
164
  }
51
165
  if (scheduleSystems.size === 0) {
52
- world.schedules.byId.set(scheduleId, []);
166
+ world.schedules.byId.set(scheduleLabel, []);
53
167
  return;
54
168
  }
55
169
  // Build dependency graph for Kahn's algorithm
@@ -63,7 +177,7 @@ export function buildSchedule(world, scheduleId = "runtime") {
63
177
  for (const [name, meta] of scheduleSystems) {
64
178
  for (const beforeName of meta.before) {
65
179
  if (!scheduleSystems.has(beforeName)) {
66
- throw new Error(`System "${name}" references unknown system "${beforeName}" in schedule "${scheduleId}"`);
180
+ throw new Error(`System "${name}" references unknown system "${beforeName}" in schedule "${scheduleLabel}"`);
67
181
  }
68
182
  // "A before B" means edge A -> B (A must run first)
69
183
  adjacency.get(name).push(beforeName);
@@ -71,7 +185,7 @@ export function buildSchedule(world, scheduleId = "runtime") {
71
185
  }
72
186
  for (const afterName of meta.after) {
73
187
  if (!scheduleSystems.has(afterName)) {
74
- throw new Error(`System "${name}" references unknown system "${afterName}" in schedule "${scheduleId}"`);
188
+ throw new Error(`System "${name}" references unknown system "${afterName}" in schedule "${scheduleLabel}"`);
75
189
  }
76
190
  // "A after B" means edge B -> A (B must run first)
77
191
  adjacency.get(afterName).push(name);
@@ -106,9 +220,9 @@ export function buildSchedule(world, scheduleId = "runtime") {
106
220
  remaining.push(name);
107
221
  }
108
222
  }
109
- throw new Error(`Circular dependency in schedule "${scheduleId}": ${remaining.join(", ")}`);
223
+ throw new Error(`Circular dependency in schedule "${scheduleLabel}": ${remaining.join(", ")}`);
110
224
  }
111
- world.schedules.byId.set(scheduleId, result);
225
+ world.schedules.byId.set(scheduleLabel, result);
112
226
  }
113
227
  /**
114
228
  * Inserts a system name into the queue maintaining sorted order by registration index.
@@ -132,73 +246,155 @@ function insertSorted(queue, name, systems) {
132
246
  queue.splice(low, 0, name);
133
247
  }
134
248
  /**
135
- * Executes a schedule synchronously. Throws if any system returns a Promise.
136
- *
137
- * @param world - World instance
138
- * @param scheduleId - Schedule identifier (defaults to "runtime")
139
- * @returns void
140
- * @example
141
- * executeSchedule(world);
142
- * executeSchedule(world, "startup");
249
+ * Rebuilds all schedules in the pipeline plus Startup and Shutdown.
143
250
  */
144
- export function executeSchedule(world, scheduleId = "runtime") {
145
- const order = world.schedules.byId.get(scheduleId);
146
- if (!order) {
147
- throw new Error(`Schedule "${scheduleId}" not built`);
251
+ function rebuildPipeline(world) {
252
+ // Build Startup and Shutdown schedules
253
+ buildSchedule(world, Startup);
254
+ buildSchedule(world, Shutdown);
255
+ // Build all pipeline schedules
256
+ for (let i = 0; i < world.schedules.pipeline.length; i++) {
257
+ buildSchedule(world, world.schedules.pipeline[i]);
258
+ }
259
+ world.schedules.dirty = false;
260
+ }
261
+ // ============================================================================
262
+ // Schedule Execution (Internal)
263
+ // ============================================================================
264
+ /**
265
+ * Executes a single schedule. Awaits async systems.
266
+ */
267
+ async function executeSchedule(world, scheduleLabel) {
268
+ const order = world.schedules.byId.get(scheduleLabel);
269
+ if (!order || order.length === 0) {
270
+ return;
148
271
  }
149
272
  // Track execution context for systems that need to know their environment
150
- world.execution.scheduleId = scheduleId;
151
- world.execution.tick++;
273
+ world.execution.scheduleLabel = scheduleLabel;
152
274
  try {
153
275
  for (const systemId of order) {
276
+ world.execution.tick++;
154
277
  world.execution.systemId = systemId;
155
278
  const meta = world.systems.byId.get(systemId);
156
279
  const result = meta.runner(world);
157
- // Fail fast if async system detected in sync execution
280
+ // Await async systems, sync systems pass through unchanged
158
281
  if (result instanceof Promise) {
159
- throw new Error(`System "${systemId}" returned Promise - use runScheduleAsync`);
282
+ await result;
160
283
  }
161
284
  }
162
285
  }
163
286
  finally {
164
- // Always clear execution context, even on error
165
- world.execution.scheduleId = null;
287
+ world.execution.tick++;
288
+ world.execution.scheduleLabel = null;
166
289
  world.execution.systemId = null;
167
290
  }
168
291
  }
292
+ // ============================================================================
293
+ // Public Execution API
294
+ // ============================================================================
169
295
  /**
170
- * Executes a schedule with async support. Awaits systems that return Promises.
296
+ * Execute one frame. Runs startup on first call, then all pipeline schedules,
297
+ * then flushes events.
171
298
  *
172
299
  * @param world - World instance
173
- * @param scheduleId - Schedule identifier (defaults to "runtime")
174
- * @returns Promise that resolves when all systems complete
300
+ * @returns Promise that resolves when the frame completes
301
+ *
175
302
  * @example
176
- * await executeScheduleAsync(world);
177
- * await executeScheduleAsync(world, "startup");
303
+ * ```typescript
304
+ * // Game loop
305
+ * await runOnce(world);
306
+ * ```
178
307
  */
179
- export async function executeScheduleAsync(world, scheduleId = "runtime") {
180
- const order = world.schedules.byId.get(scheduleId);
181
- if (!order) {
182
- throw new Error(`Schedule "${scheduleId}" not built`);
308
+ export async function runOnce(world) {
309
+ // Rebuild all schedules if pipeline is dirty
310
+ if (world.schedules.dirty) {
311
+ rebuildPipeline(world);
183
312
  }
184
- // Track execution context for systems that need to know their environment
185
- world.execution.scheduleId = scheduleId;
186
- world.execution.tick++;
187
- try {
188
- for (const systemId of order) {
189
- world.execution.systemId = systemId;
190
- const meta = world.systems.byId.get(systemId);
191
- const result = meta.runner(world);
192
- // Await async systems, sync systems pass through unchanged
193
- if (result instanceof Promise) {
194
- await result;
195
- }
313
+ // Run startup schedule on first call
314
+ if (!world.execution.startupRan) {
315
+ await executeSchedule(world, Startup);
316
+ world.execution.startupRan = true;
317
+ world.execution.shutdownRan = false;
318
+ }
319
+ // Run all pipeline schedules in order
320
+ for (let i = 0; i < world.schedules.pipeline.length; i++) {
321
+ await executeSchedule(world, world.schedules.pipeline[i]);
322
+ }
323
+ // Flush events at end of frame
324
+ flushEvents(world);
325
+ }
326
+ /**
327
+ * Start the main loop using requestAnimationFrame.
328
+ *
329
+ * Startup schedule runs automatically on first frame. Each frame executes
330
+ * all pipeline schedules in order. Call stop() to end the loop.
331
+ *
332
+ * @param world - World instance
333
+ *
334
+ * @example
335
+ * ```typescript
336
+ * addSystem(world, physicsSystem);
337
+ * addSystem(world, renderSystem, { schedule: PostUpdate });
338
+ * run(world);
339
+ * // ... later
340
+ * await stop(world);
341
+ * ```
342
+ */
343
+ export function run(world) {
344
+ if (world.execution.running) {
345
+ return;
346
+ }
347
+ world.execution.running = true;
348
+ scheduleFrame(world);
349
+ }
350
+ /**
351
+ * Schedules the next animation frame for the game loop.
352
+ */
353
+ function scheduleFrame(world) {
354
+ world.execution.rafHandle = requestAnimationFrame(async () => {
355
+ if (!world.execution.running) {
356
+ return;
357
+ }
358
+ try {
359
+ await runOnce(world);
360
+ }
361
+ catch (error) {
362
+ world.execution.running = false;
363
+ world.execution.rafHandle = null;
364
+ throw error;
365
+ }
366
+ if (world.execution.running) {
367
+ scheduleFrame(world);
196
368
  }
369
+ });
370
+ }
371
+ /**
372
+ * Stop the main loop and run the shutdown schedule.
373
+ *
374
+ * @param world - World instance
375
+ * @returns Promise that resolves when shutdown completes
376
+ *
377
+ * @example
378
+ * ```typescript
379
+ * run(world);
380
+ * // ... later
381
+ * await stop(world);
382
+ * ```
383
+ */
384
+ export async function stop(world) {
385
+ world.execution.running = false;
386
+ if (world.execution.rafHandle !== null) {
387
+ cancelAnimationFrame(world.execution.rafHandle);
388
+ world.execution.rafHandle = null;
197
389
  }
198
- finally {
199
- // Always clear execution context, even on error
200
- world.execution.scheduleId = null;
201
- world.execution.systemId = null;
390
+ // Rebuild if needed before shutdown
391
+ if (world.schedules.dirty) {
392
+ rebuildPipeline(world);
393
+ }
394
+ if (!world.execution.shutdownRan) {
395
+ await executeSchedule(world, Shutdown);
396
+ world.execution.shutdownRan = true;
397
+ world.execution.startupRan = false;
202
398
  }
203
399
  }
204
400
  //# sourceMappingURL=scheduler.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../src/scheduler.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../src/scheduler.ts"],"names":[],"mappings":"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"}