UNPKG

@polygonjs/polygonjs

Version:

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

71 lines (65 loc) 2.34 kB
/** * Timer to trigger events at certain intervals * * * */ import {TypedEventNode} from './_Base'; const INPUT_START_NAME = 'start'; const INPUT_END_NAME = 'stop'; const OUTPUT_NAME = 'tick'; import {NodeParamsConfig, ParamConfig} from '../utils/params/ParamsConfig'; import {EventConnectionPoint, EventConnectionPointType} from '../utils/io/connections/Event'; import { EventContext } from '../../../core/event/EventContextType'; class TimerEventParamsConfig extends NodeParamsConfig { /** @param period between each interval */ period = ParamConfig.INTEGER(1000); /** @param number of times the timer should repeat. Set to -1 to never stop */ count = ParamConfig.INTEGER(-1); } const ParamsConfig = new TimerEventParamsConfig(); export class TimerEventNode extends TypedEventNode<TimerEventParamsConfig> { override paramsConfig = ParamsConfig; static override type() { return 'timer'; } override initializeNode() { this.io.inputs.setNamedInputConnectionPoints([ new EventConnectionPoint(INPUT_START_NAME, EventConnectionPointType.BASE, this._start_timer.bind(this)), new EventConnectionPoint(INPUT_END_NAME, EventConnectionPointType.BASE, this._stop_timer.bind(this)), ]); this.io.outputs.setNamedOutputConnectionPoints([ new EventConnectionPoint(OUTPUT_NAME, EventConnectionPointType.BASE), ]); } private _timer_active = false; private _current_count = 0; private _start_timer(event_context: EventContext<Event>) { if (!this._timer_active) { this._timer_active = true; this._current_count = 0; } // TODO: this needs to be more robust. // Currently if the timer has a period of 1 second, // with a count of 1, and is started twice, 500ms after one another, // only a single instance will be fired. Unless _run_timer() is out of the if block above. // But then it could be started too many times this._run_timer(event_context); } protected _stop_timer() { this._timer_active = false; } private _run_timer(event_context: EventContext<Event>) { setTimeout(() => { if (this._timer_active) { if (this.pv.count <= 0 || this._current_count < this.pv.count) { this.dispatchEventToOutput(OUTPUT_NAME, event_context); this._current_count += 1; this._run_timer(event_context); } else { this._stop_timer(); } } }, this.pv.period); } }