MainLoop
The MainLoop class is the central runtime coordinator of a bg2 engine web application. It connects a Canvas instance with an AppController, initializes both objects, registers input and window events, and integrates the application into the global animation loop.
It is responsible for:
- Starting the application lifecycle
- Managing redraw requests
- Handling resize notifications
- Exposing the current mouse state
- Registering and unregistering the application from the engine animation loop
Constructor
Section titled “Constructor”constructor(canvas: Canvas, appController: AppController)
Section titled “constructor(canvas: Canvas, appController: AppController)”Creates a new MainLoop instance bound to a specific canvas and application controller.
During construction, the main loop stores internal references to both objects and also injects itself into them through the internal _mainLoop property. The update mode is initialized to FrameUpdate.AUTO, the first-frame flag is cleared, redraw is enabled for one frame, and a new MouseStatus instance is created.
Parameters
Section titled “Parameters”canvas: Rendering canvas associated with this main loop.appController: Application controller that implements the application lifecycle.
Properties
Section titled “Properties”canvas: Canvas
Section titled “canvas: Canvas”Read-only reference to the canvas associated with this main loop.
appController: AppController
Section titled “appController: AppController”Read-only reference to the application controller associated with this main loop.
renderer: any
Section titled “renderer: any”Read-only shortcut to the renderer owned by the canvas.
Returns this._canvas?.renderer.
updateMode: FrameUpdate
Section titled “updateMode: FrameUpdate”Gets or sets the frame update mode of the main loop.
This property controls how rendering updates are scheduled. The default value is FrameUpdate.AUTO, that is, the main loop will automatically schedule redraws on each animation frame. Setting this property to FrameUpdate.MANUAL will disable automatic redraw scheduling, and the application will need to call postRedisplay() to request redraw frames.
mouseStatus: MouseStatus
Section titled “mouseStatus: MouseStatus”Read-only access to the current mouse state tracked by the main loop.
redisplay: boolean
Section titled “redisplay: boolean”Indicates whether there are pending redraw frames.
Returns true when _redisplayFrames > 0.
Methods
Section titled “Methods”async run(): Promise<void>
Section titled “async run(): Promise<void>”Initializes and starts the main loop.
This method:
- Initializes the canvas
- Initializes the application controller
- Registers event handlers
- Adds the current loop to the global animation loop registry
- Starts the animation loop
This is the main entry point for launching an application.
Returns
Section titled “Returns”A promise resolved when initialization has completed.
exit(): void
Section titled “exit(): void”Stops the main loop and destroys the application controller.
This method removes the current MainLoop instance from the global animation loop list. Before removal, it calls destroy() on the associated AppController.
Use this method to terminate the application and release its runtime resources.
postReshape(): void
Section titled “postReshape(): void”Requests a resize/update of the rendering surface.
Internally, this delegates to onResize(this).
This method is typically used when the application needs to notify the engine that the canvas size or layout has changed.
postRedisplay({ frames = 10, timeout = 10 } = {}): void
Section titled “postRedisplay({ frames = 10, timeout = 10 } = {}): void”Requests one or more future redraw frames.
This method sets the internal _redisplayFrames counter either immediately or after a delay. It is useful in manual or event-driven rendering workflows where rendering should only occur when needed.
Parameters
Section titled “Parameters”frames: Number of frames to redraw. Default is10.timeout: Delay in milliseconds before scheduling the redraw request. Default is10.
Behavior
Section titled “Behavior”- If
timeout <= 0, the redraw request is applied immediately. - Otherwise, the redraw request is scheduled using
setTimeout().
Usage Notes
Section titled “Usage Notes”A MainLoop instance binds together the rendering surface and the application logic. In typical usage, the Canvas manages the rendering backend and GPU context, while the AppController implements application-specific behavior such as initialization, update logic, and destruction.
MainLoop acts as the runtime bridge between both layers.
Example
Section titled “Example”import MainLoop from "bg2e-js/ts/app/MainLoop.ts";import Canvas from "bg2e-js/ts/app/Canvas.ts";import AppController from "bg2e-js/ts/app/AppController.ts";import WebGLRenderer from "bg2e-js/ts/render/webgl/Renderer.ts";
class MyAppController extends AppController { ...}
...
const canvasElem = document.getElementById('gl-canvas') as HTMLCanvasElement;if (!canvasElem) { console.error("Cannot find canvas element with id 'gl-canvas'"); return;}const canvas = new Canvas(canvasElem, new WebGLRenderer());const controller = new MyAppController();
const mainLoop = new MainLoop(canvas, controller);await mainLoop.run();