Renderer/assets/Scripts/engine/hooks/hook-manager.ts
austin 893239c158
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit
hooks implementation
2024-07-16 17:55:28 -04:00

138 lines
4.1 KiB
TypeScript

import { Engine } from "/Scripts/engine/engine-interface"
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<TrackedHook> = []
/**
* A map of engine signal to the list of hooks that should be called when that signal fires
*/
readonly signalHookMap: Record<string,Array<TrackedHook>> = { }
/**
* The list of all scenes tracked by the manager
*/
readonly trackedScenes: Array<Scene> = []
//The parent engine object
engine: Engine
/**
* 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<TrackedHook> = this.signalHookMap?.[hookSignal] ? this.signalHookMap?.[hookSignal] : []
signalArray.push(trackedHook)
this.signalHookMap[hookSignal] = signalArray
console.log('register signal hook map')
console.log(hookSignal)
console.log(Object.keys(this.signalHookMap))
console.log(this.signalHookMap[hookSignal])
//
//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<TrackedHook> = 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 scoped to a specific scene instance
* @param instanceId The scene instance id to fire the signal within
* @param signal The signal
* @param value The value associated with the signal
*/
fireSignal(instanceId: number, signal: string, ...value: any){
//parse from host
const argsRaw: any[] = value?.[0]
//try running global hooks for the signal
const globalHooks: Array<TrackedHook> = this.signalHookMap[signal]
if(!!globalHooks){
globalHooks.forEach(trackedHook => {
trackedHook.callback(...argsRaw)
})
} else {
//There isn't a hook registered for this signal at the global level
console.log("No global hooks for signal " + signal)
}
//try firing at scene scope
const scene: Scene = this.engine.sceneLoader.getScene(instanceId)
const sceneHooks: Array<TrackedHook> = scene.signalHookMap[signal]
if(!!sceneHooks){
sceneHooks.forEach(trackeHook => {
trackeHook.callback(...argsRaw)
})
} else {
//There isn't a hook registered for this signal at the scene level
console.log("No scene hooks for signal " + signal)
}
}
}