Some checks failed
		
		
	
	studiorailgun/Renderer/pipeline/head There was a failure building this commit
				
			
		
			
				
	
	
		
			145 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			145 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
import { Engine } from "/Scripts/types/engine"
 | 
						|
import { Hook } from "/Scripts/types/hook"
 | 
						|
import { Scene } from "/Scripts/types/scene"
 | 
						|
import { loggerScripts } from '/Scripts/compiler/host_access'
 | 
						|
 | 
						|
/**
 | 
						|
 * The global scene id
 | 
						|
 */
 | 
						|
export const GLOBAL_SCENE_ID: number = -1
 | 
						|
 | 
						|
/**
 | 
						|
 * 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
 | 
						|
        loggerScripts.DEBUG('register signal hook map')
 | 
						|
        loggerScripts.DEBUG(hookSignal)
 | 
						|
        loggerScripts.DEBUG(Object.keys(this.signalHookMap) + '')
 | 
						|
        loggerScripts.DEBUG(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
 | 
						|
            loggerScripts.DEBUG("No global hooks for signal " + signal)
 | 
						|
        }
 | 
						|
 | 
						|
        if(instanceId !== GLOBAL_SCENE_ID){
 | 
						|
            //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
 | 
						|
                loggerScripts.DEBUG("No scene hooks for signal " + signal)
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
}
 | 
						|
 |