UNPKG

@polygonjs/polygonjs

Version:

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

74 lines (67 loc) 2.48 kB
/** * Throttles input events * * */ import {EventConnectionPoint, EventConnectionPointType} from '../utils/io/connections/Event'; import {NodeParamsConfig, ParamConfig} from '../utils/params/ParamsConfig'; import {TypedEventNode} from './_Base'; import throttle from 'lodash-es/throttle'; import type {DebouncedFunc} from 'lodash-es'; import {BaseNodeType} from '../_Base'; import {EventContext} from '../../../core/event/EventContextType'; const callbackOption = { callback: (node: BaseNodeType) => { ThrottleEventNode.PARAM_CALLBACK_resetDebouncedFunc(node as ThrottleEventNode); }, }; class ThrottleEventParamsConfig extends NodeParamsConfig { /** @param max time between each event */ time = ParamConfig.INTEGER(100, { range: [0, 1000], rangeLocked: [true, false], ...callbackOption, }); /** @param defines if event is dispatched on the leading edge of the timeout */ leading = ParamConfig.BOOLEAN(true, callbackOption); /** @param defines if event is trailing on the leading edge of the timeout */ trailing = ParamConfig.BOOLEAN(true, callbackOption); } const ParamsConfig = new ThrottleEventParamsConfig(); export class ThrottleEventNode extends TypedEventNode<ThrottleEventParamsConfig> { override paramsConfig = ParamsConfig; static override type() { return 'throttle'; } static readonly OUTPUT_NAME = 'output'; override initializeNode() { this.io.inputs.setNamedInputConnectionPoints([ new EventConnectionPoint('trigger', EventConnectionPointType.BASE), ]); this.io.outputs.setNamedOutputConnectionPoints([ new EventConnectionPoint(ThrottleEventNode.OUTPUT_NAME, EventConnectionPointType.BASE), ]); } private _debouncedFunc: DebouncedFunc<() => void> | undefined; private _lastEventContextReceived: EventContext<Event> | undefined; override processEvent(eventContext: EventContext<Event>) { this._lastEventContextReceived = eventContext; this._debouncedFunc = this._debouncedFunc || this._buildDebouncedFunc(); this._debouncedFunc(); } private _buildDebouncedFunc() { const {leading, trailing, time} = this.pv; const func = () => { if (this._lastEventContextReceived) { this.dispatchEventToOutput(ThrottleEventNode.OUTPUT_NAME, this._lastEventContextReceived); } }; return throttle(func, time, {leading, trailing}); } private _resetDebouncedFunc() { this._debouncedFunc = undefined; } static PARAM_CALLBACK_resetDebouncedFunc(node: ThrottleEventNode) { node._resetDebouncedFunc(); } }