API reference

Every public class, method, and event in @codexo/exojs. Generated from source.

C

classCoroutineSystem

@codexo/exojs / core / stable

Advances generator-based coroutines a step at a time in the frame's leftover capacity, so heavy work (world generation, batch pathfinding, visibility rebuilds) spreads over frames without an `async` update. It runs in the SystemMethods.postFrame phase, after the backend has flushed: the work overlaps the GPU drawing the frame just submitted, and the frame's remaining time is known rather than guessed. `app.coroutines` is the instance the application owns, and `scene.coroutines` a scene-bound facade over it. Each coroutine is stepped at most once per frame, and the first step of a frame happens whatever the budget says, so a coroutine whose single step always overruns still makes progress. That one rule is what lets a body that ignores `budget` behave like a sequence (one `yield` is one frame) while a body that consults it fills whatever the frame has left. ```ts const terrain = scene.coroutines.queue(buildWorld(map), { name: 'terrain' }); terrain.done.then(world => { scene.root.addChild(world); }); ``` The engine cannot interrupt a running step - JavaScript is run-to-completion - so a body chooses its own granularity. A step that overruns its slice by a wide margin is reported in development, naming the coroutine.

6
props
4
methods
0
events
Import
import { CoroutineSystem } from '@codexo/exojs'

Advances generator-based coroutines a step at a time in the frame's leftover capacity, so heavy work (world generation, batch pathfinding, visibility rebuilds) spreads over frames without an `async` update.

It runs in the SystemMethods.postFrame phase, after the backend has flushed: the work overlaps the GPU drawing the frame just submitted, and the frame's remaining time is known rather than guessed. `app.coroutines` is the instance the application owns, and `scene.coroutines` a scene-bound facade over it.

Each coroutine is stepped at most once per frame, and the first step of a frame happens whatever the budget says, so a coroutine whose single step always overruns still makes progress. That one rule is what lets a body that ignores `budget` behave like a sequence (one `yield` is one frame) while a body that consults it fills whatever the frame has left.

```ts const terrain = scene.coroutines.queue(buildWorld(map), { name: 'terrain' });

terrain.done.then(world => { scene.root.addChild(world); }); ```

The engine cannot interrupt a running step - JavaScript is run-to-completion - so a body chooses its own granularity. A step that overruns its slice by a wide margin is reported in development, naming the coroutine.

Constructors1
new(options: CoroutineSystemOptions): CoroutineSystem
Methods4
clear(): void
Cancel every queued coroutine.
destroy(): void
Queue body and return its handle. The first step runs in the next frame's post-frame phase, never synchronously - and, because that phase is the last of the frame, work queued from an ordinary update() still takes its first step in the same frame. body is either a generator function, which is handed the frame budget, or a ready-made iterator for the sequencing case that has no use for one.
Properties6
order: number
destroyed: boolean
lastFrameMs: number
Milliseconds the most recent frame spent advancing coroutines.
pending: number
Coroutines that have not settled yet, including any a scene has suspended.
Source