import { inspectSymbol } from '../debugging/inspect.js'; import { objectName } from '../debugging/object-with-name.js'; import type { IDisposable } from '../lifecycle/dispose/disposable.js'; import { EnhancedDisposable } from '../lifecycle/dispose/sync-disposable.js'; import { Emitter } from '../lifecycle/event/event.js'; type TimerT = ReturnType; /** * @param unref defaults to `false`, when true, call `unref()` on the timer. * can not set to `true` on other platform. * @returns dispose will stop the interval */ export function interval(ms: number, action: () => void, unref = false) { let timer: TimerT | undefined = setInterval(action, ms); // unref is not supported in browser if (unref) (timer as any).unref(); return { name: `interval(${ms}):${objectName(action)}`, dispose: () => { if (!timer) return; clearInterval(timer); timer = undefined; }, }; } /** * A simple interval class. * * mainly use for pause/resume several times. */ export class Interval extends EnhancedDisposable { private readonly _emitter = this._register(new Emitter()); public readonly onTick = this._emitter.event; private timer?: IDisposable; constructor( private readonly ms: number, private readonly unref = false, ) { super(`Interval(${ms})`); this.fire = this.fire.bind(this); } reset() { this.timer?.dispose(); this.timer = interval(this.ms, this.fire, this.unref); } fire() { this._emitter.fire(); } resume() { if (this.timer) return; this.timer = interval(this.ms, this.fire, this.unref); } pause() { if (!this.timer) return; this.timer.dispose(); this.timer = undefined; } override dispose() { if (this.timer) this.timer.dispose(); return super.dispose(); } [inspectSymbol](depth: number, options: any, inspect: any) { if (depth < 0) { return options.stylize(`[Interval ${this.ms}ms]`, 'special'); } let r = `${options.stylize(this.constructor.name, 'name')} ${options.stylize(`${this.ms}`, 'number')}ms`; const padding = ' '.repeat(2); const inner = inspect(this._emitter, options, inspect).replace(/\n/g, `\n${padding}`); r += ` {\n${padding}onTick: ${inner}\n}`; return r; } }