polygonjs-engine
Version:
node-based webgl 3D engine https://polygonjs.com
71 lines (65 loc) • 2.32 kB
text/typescript
/**
* 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);
}
}