import {BaseCameraObjNodeType} from '../../../nodes/obj/_BaseCamera'; import {BaseInputEventNodeType} from '../../../nodes/event/_BaseInput'; import {SceneEventsDispatcher} from './EventsDispatcher'; import {BaseNodeType} from '../../../nodes/_Base'; import {Intersection} from 'three/src/core/Raycaster'; import {CoreGraphNodeId} from '../../../../core/graph/CoreGraph'; import {BaseViewerType} from '../../../viewers/_Base'; interface EventContextValue { node?: BaseNodeType; // for node_cook intersect?: Intersection; // for raycast } export interface EventContext { viewer?: Readonly; event?: Readonly; cameraNode?: Readonly; value?: EventContextValue; } export abstract class BaseSceneEventsController { protected _nodes_by_graph_node_id: Map = new Map(); protected _require_canvas_event_listeners: boolean = false; constructor(private dispatcher: SceneEventsDispatcher) {} registerNode(node: T) { this._nodes_by_graph_node_id.set(node.graphNodeId(), node); this.updateViewerEventListeners(); } unregisterNode(node: T) { this._nodes_by_graph_node_id.delete(node.graphNodeId()); this.updateViewerEventListeners(); } abstract type(): string; abstract acceptedEventTypes(): string[]; // abstract accepts_event(event: Event): boolean; processEvent(event_context: EventContext) { if (this._active_event_types.length == 0) { return; } this._nodes_by_graph_node_id.forEach((node) => node.process_event(event_context)); } updateViewerEventListeners() { this._update_active_event_types(); if (this._require_canvas_event_listeners) { this.dispatcher.scene.viewersRegister.traverseViewers((viewer) => { viewer.eventsController.updateEvents(this); }); } } private _active_event_types: string[] = []; activeEventTypes() { return this._active_event_types; } private _update_active_event_types() { const active_node_event_types_state: Map = new Map(); this._nodes_by_graph_node_id.forEach((node) => { if (node.parent()) { const node_active_event_names = node.active_event_names(); for (let name of node_active_event_names) { active_node_event_types_state.set(name, true); } } }); this._active_event_types = []; active_node_event_types_state.forEach((state, name) => { this._active_event_types.push(name); }); } } export type BaseSceneEventsControllerType = BaseSceneEventsController; export class BaseSceneEventsControllerClass extends BaseSceneEventsController { type() { return ''; } acceptedEventTypes(): string[] { return []; } }