import { Hook } from "/Scripts/types/hook" import { Scene } from "/Scripts/types/scene" /** * The scope that the hook is firing from */ export enum HookScope { CORE, SCRIPT, SCENE_CLIENT, SCENE_SERVER, } /** * A hook that is tracked by the manager */ export interface TrackedHook extends Hook { /** * The scope that this hook was defined at */ readonly scope: HookScope, /** * The scene that added the hook */ readonly scene?: Scene, } /** * Manages hooks for the engine */ export class HookManager { /** * The list of all hooks currently tracked by this manager */ readonly hooks: Array = [] /** * A map of engine signal to the list of hooks that should be called when that signal fires */ readonly signalHookMap: Record> = { } /** * The list of all scenes tracked by the manager */ readonly trackedScenes: Array = [] /** * Registers a hook * @param scene The scene introducing the hook * @param hook The hook */ registerHook(scene: Scene, hook: Hook, isServerScene: boolean){ const trackedHook: TrackedHook = { ...hook, scope: isServerScene ? HookScope.SCENE_SERVER : HookScope.SCENE_CLIENT, scene: scene, } //add to flat array this.hooks.push(trackedHook) //add to signal array const hookSignal: string = hook.signal const signalArray: Array = this.signalHookMap?.[hookSignal] ? this.signalHookMap?.[hookSignal] : [] signalArray.push(trackedHook) this.signalHookMap[hookSignal] = signalArray // //Scene related structures // //track scene if it isn't already being tracked let filteredArr = this.trackedScenes.filter(trackedScene => trackedScene.instanceId === scene.instanceId) if(filteredArr.length < 1){ this.trackedScenes.push(scene) } //add to scene tracking structures scene.sceneHooks.push(trackedHook) const sceneSignalArray: Array = scene.signalHookMap?.[hookSignal] ? scene.signalHookMap?.[hookSignal] : [] sceneSignalArray.push(trackedHook) scene.signalHookMap[hookSignal] = sceneSignalArray } /** * Deregisters a hook * @param scene The scene which introduced the hook * @param hook The hook */ deregisterHook(scene: Scene, hook: Hook){ throw new Error("Supported operation!") } /** * Fires a signal * @param signal The signal * @param value The value associated with the signal */ fireSignal(instanceId: number, signal: string, value: any){ const hooks: Array = this.signalHookMap[signal] hooks.forEach(trackedHook => { trackedHook.callback(value) }) } }