From ffd2a62c3f7df94365980302fef3bc3376b48182 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Mon, 3 Aug 2020 13:00:48 +0530 Subject: modularize repo, use pnpm, improve typechecking --- packages/taler-wallet-core/src/util/timer.ts | 165 +++++++++++++++++++++++++++ 1 file changed, 165 insertions(+) create mode 100644 packages/taler-wallet-core/src/util/timer.ts (limited to 'packages/taler-wallet-core/src/util/timer.ts') diff --git a/packages/taler-wallet-core/src/util/timer.ts b/packages/taler-wallet-core/src/util/timer.ts new file mode 100644 index 000000000..8eab1399c --- /dev/null +++ b/packages/taler-wallet-core/src/util/timer.ts @@ -0,0 +1,165 @@ +/* + This file is part of GNU Taler + (C) 2017-2019 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ + +/** + * Cross-platform timers. + * + * NodeJS and the browser use slightly different timer API, + * this abstracts over these differences. + */ + +/** + * Imports. + */ +import { Duration } from "./time"; +import { Logger } from "./logging"; + +const logger = new Logger("timer.ts"); + +/** + * Cancelable timer. + */ +export interface TimerHandle { + clear(): void; +} + +class IntervalHandle { + constructor(public h: any) {} + + clear(): void { + clearInterval(this.h); + } +} + +class TimeoutHandle { + constructor(public h: any) {} + + clear(): void { + clearTimeout(this.h); + } +} + +/** + * Get a performance counter in milliseconds. + */ +export const performanceNow: () => number = (() => { + // @ts-ignore + if (typeof process !== "undefined" && process.hrtime) { + return () => { + const t = process.hrtime(); + return t[0] * 1e9 + t[1]; + }; + } + + // @ts-ignore + if (typeof performance !== "undefined") { + // @ts-ignore + return () => performance.now(); + } + + return () => 0; +})(); + +/** + * Call a function every time the delay given in milliseconds passes. + */ +export function every(delayMs: number, callback: () => void): TimerHandle { + return new IntervalHandle(setInterval(callback, delayMs)); +} + +/** + * Call a function after the delay given in milliseconds passes. + */ +export function after(delayMs: number, callback: () => void): TimerHandle { + return new TimeoutHandle(setTimeout(callback, delayMs)); +} + +const nullTimerHandle = { + clear() { + // do nothing + return; + }, +}; + +/** + * Group of timers that can be destroyed at once. + */ +export class TimerGroup { + private stopped = false; + + private timerMap: { [index: number]: TimerHandle } = {}; + + private idGen = 1; + + stopCurrentAndFutureTimers(): void { + this.stopped = true; + for (const x in this.timerMap) { + if (!this.timerMap.hasOwnProperty(x)) { + continue; + } + this.timerMap[x].clear(); + delete this.timerMap[x]; + } + } + + resolveAfter(delayMs: Duration): Promise { + return new Promise((resolve, reject) => { + if (delayMs.d_ms !== "forever") { + this.after(delayMs.d_ms, () => { + resolve(); + }); + } + }); + } + + after(delayMs: number, callback: () => void): TimerHandle { + if (this.stopped) { + logger.warn("dropping timer since timer group is stopped"); + return nullTimerHandle; + } + const h = after(delayMs, callback); + const myId = this.idGen++; + this.timerMap[myId] = h; + + const tm = this.timerMap; + + return { + clear() { + h.clear(); + delete tm[myId]; + }, + }; + } + + every(delayMs: number, callback: () => void): TimerHandle { + if (this.stopped) { + logger.warn("dropping timer since timer group is stopped"); + return nullTimerHandle; + } + const h = every(delayMs, callback); + const myId = this.idGen++; + this.timerMap[myId] = h; + + const tm = this.timerMap; + + return { + clear() { + h.clear(); + delete tm[myId]; + }, + }; + } +} -- cgit v1.2.3