108 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			108 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| 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> = []
 | |
| 
 | |
|     /**
 | |
|      * 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
 | |
|         //
 | |
|         //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
 | |
|      * @param signal The signal
 | |
|      * @param value The value associated with the signal
 | |
|      */
 | |
|     fireSignal(instanceId: number, signal: string, value: any){
 | |
|         const hooks: Array<TrackedHook> = this.signalHookMap[signal]
 | |
|         hooks.forEach(trackedHook => {
 | |
|             trackedHook.callback(value)
 | |
|         })
 | |
|     }
 | |
| 
 | |
| }
 | |
| 
 |