From 6228e27feb71da2b6ef16fe0818663549b8487a7 Mon Sep 17 00:00:00 2001 From: Exelo Date: Fri, 21 Mar 2025 00:41:50 +0100 Subject: [PATCH] feat(core): add tickrate and fix runner --- .../application/application-options.type.ts | 3 +++ .../src/application/nanoforge-application.ts | 11 +++++++++-- .../core/src/application/nanoforge-factory.ts | 9 +++++---- packages/core/src/core/core.ts | 19 +++++++++++++++---- 4 files changed, 32 insertions(+), 10 deletions(-) create mode 100644 packages/core/src/application/application-options.type.ts diff --git a/packages/core/src/application/application-options.type.ts b/packages/core/src/application/application-options.type.ts new file mode 100644 index 00000000..57ecc833 --- /dev/null +++ b/packages/core/src/application/application-options.type.ts @@ -0,0 +1,3 @@ +export interface IApplicationOptions { + tickRate: number; +} diff --git a/packages/core/src/application/nanoforge-application.ts b/packages/core/src/application/nanoforge-application.ts index 7db9a5a4..4684380e 100644 --- a/packages/core/src/application/nanoforge-application.ts +++ b/packages/core/src/application/nanoforge-application.ts @@ -9,13 +9,20 @@ import { import { Core } from "../core/core"; import { ApplicationConfig } from "./application-config"; +import type { IApplicationOptions } from "./application-options.type"; export abstract class NanoforgeApplication { protected applicationConfig: ApplicationConfig; private _core: Core; + private readonly _options: IApplicationOptions; - constructor() { + constructor(options?: Partial) { this.applicationConfig = new ApplicationConfig(); + + this._options = { + tickRate: 60, + ...(options ?? {}), + }; } public use(sym: symbol, library: ILibrary): void { @@ -36,7 +43,7 @@ export abstract class NanoforgeApplication { public async init(options: IRunOptions): Promise { this._core = new Core(this.applicationConfig, new ApplicationContext()); - await this._core.init(options); + await this._core.init(options, this._options); } public run() { diff --git a/packages/core/src/application/nanoforge-factory.ts b/packages/core/src/application/nanoforge-factory.ts index 9fcdb415..84711a6d 100644 --- a/packages/core/src/application/nanoforge-factory.ts +++ b/packages/core/src/application/nanoforge-factory.ts @@ -1,13 +1,14 @@ +import { type IApplicationOptions } from "./application-options.type"; import { NanoforgeClient } from "./nanoforge-client"; import { NanoforgeServer } from "./nanoforge-server"; class NanoforgeFactoryStatic { - createClient(): NanoforgeClient { - return new NanoforgeClient(); + createClient(options?: Partial): NanoforgeClient { + return new NanoforgeClient(options); } - createServer(): NanoforgeServer { - return new NanoforgeServer(); + createServer(options?: Partial): NanoforgeServer { + return new NanoforgeServer(options); } } diff --git a/packages/core/src/core/core.ts b/packages/core/src/core/core.ts index 87b6645b..6196cd1e 100644 --- a/packages/core/src/core/core.ts +++ b/packages/core/src/core/core.ts @@ -9,31 +9,42 @@ import { } from "@nanoforge/common"; import { type ApplicationConfig } from "../application/application-config"; +import type { IApplicationOptions } from "../application/application-options.type"; export class Core { private readonly config: ApplicationConfig; private readonly context: ApplicationContext; + private options: IApplicationOptions; constructor(config: ApplicationConfig, context: ApplicationContext) { this.config = config; this.context = context; } - public async init(options: IRunOptions): Promise { + public async init(options: IRunOptions, appOptions: IApplicationOptions): Promise { + this.options = appOptions; await this.runInit(this.getInitContext(options)); } public async run(): Promise { const context = this.getExecutionContext(); const libraries = this.config.libraryManager.getRunnerLibraries(); + let requestAnimationFrameHandle: number; + const runner = async () => { + await this.runExecute(context, libraries); + }; + + const render = () => { if (!context.isRunning) { + clearInterval(intervalHandle); return; } - await this.runExecute(context, libraries); - requestAnimationFrame(runner); + cancelAnimationFrame(requestAnimationFrameHandle); + requestAnimationFrameHandle = requestAnimationFrame(runner); }; - requestAnimationFrame(runner); + + const intervalHandle = setInterval(render, 1000 / this.options.tickRate); } private getInitContext(options: IRunOptions): InitContext {