UNPKG

polygonjs-engine

Version:

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

71 lines (65 loc) 2.32 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 '../../scene/utils/events/_BaseEventsController'; 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> { params_config = ParamsConfig; static type() { return 'timer'; } 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.dispatch_event_to_output(OUTPUT_NAME, event_context); this._current_count += 1; this._run_timer(event_context); } else { this._stop_timer(); } } }, this.pv.period); } }