UNPKG

polygonjs-engine

Version:

node-based webgl 3D engine https://polygonjs.com

86 lines (75 loc) 2.75 kB
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<E extends Event> { viewer?: Readonly<BaseViewerType>; event?: Readonly<E>; cameraNode?: Readonly<BaseCameraObjNodeType>; value?: EventContextValue; } export abstract class BaseSceneEventsController<E extends Event, T extends BaseInputEventNodeType> { protected _nodes_by_graph_node_id: Map<CoreGraphNodeId, T> = 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<E>) { 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<string, boolean> = 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<Event, BaseInputEventNodeType>; export class BaseSceneEventsControllerClass extends BaseSceneEventsController<Event, BaseInputEventNodeType> { type() { return ''; } acceptedEventTypes(): string[] { return []; } }