import type { ScriptContext, ScriptCoroutineContext, ScriptGameEventHandler } from "../types"; import type { ScriptCoroutines } from "./coroutines"; export type ScriptCoroutineGameEventHandler = { handler: ScriptGameEventHandler; coroutine: ScriptCoroutineContext; } export class ScriptGameEventBus { private coroutines: ScriptCoroutines; private handlers: Record = {}; constructor(coroutines: ScriptCoroutines) { this.coroutines = coroutines; } on(event: string, handler: ScriptGameEventHandler, coroutine: ScriptCoroutineContext): void { console.log('subscribing to ' + event, handler, coroutine); let set = this.handlers[event]; if (!set) { set = []; this.handlers[event] = set; } if (!set.some((h) => h.handler === handler)) set.push({ handler, coroutine }); } off(event: string, handler: ScriptGameEventHandler): void { console.log('unubscribing from ' + event, handler); const handlers = this.handlers[event]; if (!handlers) return; this.handlers[event] = handlers.filter((h) => h.handler !== handler); } emit(event: string, context: Omit): void { const coroutines = this.handlers[event] ?.map((h) => ({ owner: h.coroutine.thisObject.id, name: `${h.coroutine.thisObjectType.name}[${h.coroutine.thisObject.id}]:${event}`, coroutine: h.handler({ ...context, ...h.coroutine }), })); if (coroutines) this.coroutines.push(coroutines); } }