From e0784a670c3b131a00f2133fee7f9ed18b591354 Mon Sep 17 00:00:00 2001 From: Hide_D Date: Sat, 9 Mar 2024 16:28:46 +0000 Subject: [PATCH] feat: GameEngineWorker --- @sammo/server/src/GameEngineController.ts | 9 ++--- @sammo/server/src/GameEngineDefs.ts | 13 +++++- @sammo/server/src/GameEngineWorker.ts | 48 +++++++++++++++++++++++ 3 files changed, 62 insertions(+), 8 deletions(-) diff --git a/@sammo/server/src/GameEngineController.ts b/@sammo/server/src/GameEngineController.ts index dcb93ba..eee33be 100644 --- a/@sammo/server/src/GameEngineController.ts +++ b/@sammo/server/src/GameEngineController.ts @@ -45,18 +45,15 @@ class GameEngineController { const { port1: rpcServer, port2: rpcClient } = new MessageChannel(); - const worker = new Worker(workerPath, { - workerData: { - guid - } - }); + const worker = new Worker(workerPath); this.stopWaiter = new Promise((resolve) => { this.stopWaiterResolve = resolve; }); worker.postMessage({ type: 'init', - port: rpcServer + port: rpcServer, + guid }, [rpcServer]); await delay(0); diff --git a/@sammo/server/src/GameEngineDefs.ts b/@sammo/server/src/GameEngineDefs.ts index fc36fea..35acf87 100644 --- a/@sammo/server/src/GameEngineDefs.ts +++ b/@sammo/server/src/GameEngineDefs.ts @@ -1,6 +1,6 @@ import type { RPCLists } from "@sammo/server_util"; import type { ActionRequest, ActionResult } from "./GameEngine.js"; - +import type { MessagePort } from "node:worker_threads"; export type GameEngineRPCDefs = { @@ -15,4 +15,13 @@ type WorkerUpdate = { lastExecuted: string, } -export type GameEngineMsg = WorkerUpdate; \ No newline at end of file +export type GameEngineMsg = WorkerUpdate; + + +type WorkerInit = { + type: 'init', + port: MessagePort, + guid: string, +} + +export type GameEngineWorkerMsg = WorkerInit; \ No newline at end of file diff --git a/@sammo/server/src/GameEngineWorker.ts b/@sammo/server/src/GameEngineWorker.ts index e69de29..5648bd5 100644 --- a/@sammo/server/src/GameEngineWorker.ts +++ b/@sammo/server/src/GameEngineWorker.ts @@ -0,0 +1,48 @@ +import { parentPort as _parentPort } from "node:worker_threads"; +import { type MessagePort } from "node:worker_threads"; +import type { GameEngineMsg, GameEngineRPCDefs, GameEngineWorkerMsg } from "./GameEngineDefs.js"; +import { GameEngine } from "./GameEngine.js"; +import { RPCServer } from "@sammo/server_util"; + +if (!_parentPort) { + throw new Error('GameEngineWorker must be run as worker'); +} + +const parentPort = _parentPort; + +function sendToParent(msg: GameEngineMsg) { + parentPort.postMessage(msg); +} + +let engineDone: () => void = () => { throw new Error('GameEngineWorker: engineDone not set')}; +let engine: GameEngine; +let rpcServer: RPCServer; + +async function startWorker(port: MessagePort, guid: string){ + engine = await GameEngine.initInstance(sendToParent); + rpcServer = new RPCServer(port, { + stop: async ()=>{ + await engine.stop(); + engineDone(); + }, + pushAPIAction: async (action)=>{ + return await engine.pushAPIAction(action); + }, + pushServerAction: async (action)=>{ + return await engine.pushServerAction(action); + } + }); +} + +await new Promise((resolve) => { + parentPort.on('message', (msg: GameEngineWorkerMsg) => { + switch (msg.type) { + case 'init': + engineDone = resolve; + startWorker(msg.port, msg.guid); + break; + default: + throw new Error(`GameEngineWorker: unknown message type ${msg.type}`); + } + }); +}) \ No newline at end of file