From 8e4cafc3d249d151c6f3850129e2362056f2e0b2 Mon Sep 17 00:00:00 2001 From: Colin Espinas Date: Wed, 16 Oct 2024 14:13:08 +0200 Subject: [PATCH] feat: added hooks to engine step loop --- .changeset/few-schools-explain.md | 5 +++++ src/core/Engine.ts | 26 ++++++++++++++++++++++++++ src/types/options.d.ts | 16 ++++++++++++++++ 3 files changed, 47 insertions(+) create mode 100644 .changeset/few-schools-explain.md diff --git a/.changeset/few-schools-explain.md b/.changeset/few-schools-explain.md new file mode 100644 index 0000000..f8e9105 --- /dev/null +++ b/.changeset/few-schools-explain.md @@ -0,0 +1,5 @@ +--- +"@ineka/engine": minor +--- + +Added hooks to execute code at engine's key locations diff --git a/src/core/Engine.ts b/src/core/Engine.ts index 09864d3..061efdc 100644 --- a/src/core/Engine.ts +++ b/src/core/Engine.ts @@ -63,6 +63,10 @@ export class Engine { fullscreen: true, container: 'body', framerate: null, + hooks: { + beforeStep: async () => { }, + afterStep: async () => { }, + }, ...options, } this._container = document.querySelector(this._options.container as string) as HTMLElement @@ -98,6 +102,17 @@ export class Engine { * to fix the timestep for fixed update loops (useful for physics and user interactions). */ protected step(now: number): void { + // Call beforeStep hook + try { + if (!this.options.hooks || !this.options.hooks.beforeStep) { + throw new EngineError(this, 'ENGINE:FAILURE', 'No beforeStep hook given to engine.') + } + this.options.hooks.beforeStep() + } + catch (err) { + console.error(err) + } + if (!this.rootNode) { throw new EngineError(this, 'ENGINE:FAILURE', 'No root node given to engine, cannot run.') } @@ -118,6 +133,17 @@ export class Engine { system.step(this.time.delta) }) this.rootNode.step(this.time.delta) + // Call afterStep hook + try { + if (!this.options.hooks || !this.options.hooks.afterStep) { + throw new EngineError(this, 'ENGINE:FAILURE', 'No afterStep hook given to engine.') + } + this.options.hooks.afterStep() + } + catch (err) { + console.error(err) + } + // Request next step requestAnimationFrame(this.step.bind(this)) } diff --git a/src/types/options.d.ts b/src/types/options.d.ts index f1c841d..0cf0928 100644 --- a/src/types/options.d.ts +++ b/src/types/options.d.ts @@ -32,4 +32,20 @@ export interface EngineOptions { * @default null */ framerate?: number | null + + /** + * Hooks are functions that are called at specific points in the engine's runtime. + */ + hooks?: { + /** + * Called before the engine's step loop. + * @default async () => { } + */ + beforeStep: () => Promise + /** + * Called after the engine's step loop. + * @default async () => { } + */ + afterStep: () => Promise + } }