UNPKG

@polygonjs/polygonjs

Version:

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

156 lines (141 loc) 5.06 kB
import {BaseViewerType} from '../_Base'; import {BaseSceneEventsControllerType} from '../../scene/utils/events/_BaseEventsController'; import {EventContext} from '../../../../src/core/event/EventContextType'; import {EmitterElementOrWindow} from '../../../core/event/CoreEventEmitter'; import {ACCEPTED_KEYBOARD_EVENT_TYPES, KeyboardEventType} from '../../../core/event/KeyboardEventType'; import {allowCanvasKeyEventsListener} from '../../../core/event/CanvasKeyFocus'; import {getEventEmitter} from '../../../core/event/EventEmitter'; import {EventData, EventType} from '../../../core/event/EventData'; import {setToArray} from '../../../core/SetUtils'; type ViewerEventListener = (e: Event) => void; interface EventListenerWithData { listener: ViewerEventListener; data: EventData; } type ListenerByEventType = Map<EventType, EventListenerWithData>; const DEBUG = false; const _eventTypesSet: Set<string> = new Set(); // let listenerId: number = 0; export class ViewerEventsController { protected _eventTypes: Map<string, Map<EmitterElementOrWindow, ListenerByEventType>> = new Map(); constructor(protected viewer: BaseViewerType) {} removeEvents(eventsController: BaseSceneEventsControllerType, _canvas?: HTMLCanvasElement) { const canvas = _canvas || this.canvas(); if (!canvas) { console.warn('no canvas found'); return; } const mapForController = this._eventTypes.get(eventsController.type()); if (!mapForController) { return; } mapForController.forEach((listenerByEventType, emitter) => { listenerByEventType.forEach((listenerWithData, eventType: EventType) => { const eventEmitter = getEventEmitter({emitter: listenerWithData.data.emitter, type: eventType}, canvas); eventEmitter.removeEventListener(eventType, listenerWithData.listener); }); listenerByEventType.clear(); }); } updateEvents(eventsController: BaseSceneEventsControllerType) { if (DEBUG) { console.warn('------------ updateEvents START:', eventsController); } const canvas = this.canvas(); if (!canvas) { console.warn('no canvas found'); return; } this.removeEvents(eventsController, canvas); // const listener = (event: Event) => { // this.processEvent(event, eventsController, canvas); // }; const activeEventDatas = eventsController.activeEventDatas(); for (const eventData of activeEventDatas) { const eventEmitter = getEventEmitter(eventData, canvas); const map = this._mapForEmitter(eventsController, eventEmitter); const eventType = eventData.type; const _processEvent = ( event: Event, controller: BaseSceneEventsControllerType // canvas: HTMLCanvasElement ) => { const eventContext: EventContext<Event> = { viewer: this.viewer, event: event, emitter: eventData.emitter, // camera: this.camera(), }; controller.processEvent(eventContext); }; // listenerId++; // const _id = listenerId; const listener = (event: Event) => { // console.log('run listener:', _id, eventType); _processEvent(event, eventsController /*, canvas*/); }; if (DEBUG) { console.log('+ add event:', eventType, eventEmitter); } eventEmitter.addEventListener(eventType, listener, {passive: true}); // if the event being added is a keyboard type, // we need to add tabindex to the canvas to allow it to have focus if (eventEmitter != document) { if (ACCEPTED_KEYBOARD_EVENT_TYPES.includes(eventData.type as KeyboardEventType)) { allowCanvasKeyEventsListener(eventEmitter as HTMLCanvasElement); } } map.set(eventData.type, {listener, data: eventData}); } if (DEBUG) { console.log('------------ updateEvents DONE:'); } } private _mapForEmitter(eventsController: BaseSceneEventsControllerType, emitter: EmitterElementOrWindow) { const controllerType = eventsController.type(); let mapForController = this._eventTypes.get(controllerType); if (!mapForController) { mapForController = new Map(); this._eventTypes.set(controllerType, mapForController); } let mapForEmitter = mapForController.get(emitter); if (!mapForEmitter) { mapForEmitter = new Map(); mapForController.set(emitter, mapForEmitter); } return mapForEmitter; } camera() { return this.viewer.camera(); } canvas() { return this.viewer.canvas(); } init() { if (!this.canvas()) { console.warn('no canvas found for eventsController'); return; } this.viewer.scene().eventsDispatcher.traverseControllers((controller) => { this.updateEvents(controller); }); } unmount() { this.viewer.scene().eventsDispatcher.traverseControllers((controller) => { this.removeEvents(controller); }); } registeredEventTypes(): string[] { _eventTypesSet.clear(); this._eventTypes.forEach((mapForEmitter) => { mapForEmitter.forEach((listenerByEventType, emitter) => { listenerByEventType.forEach((listener, eventType: string) => { _eventTypesSet.add(eventType); }); }); }); const target: string[] = []; setToArray(_eventTypesSet, target); return target; } }