summaryrefslogtreecommitdiff
path: root/js/timers.ts
blob: da2cccd89a9483f9152f6850daec660cd34c21ad (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
// Copyright 2018 Ryan Dahl <ry@tinyclouds.org>
// All rights reserved. MIT License.
import { deno as pb } from "./msg.pb";
import { pubInternal, sub } from "./dispatch";
import { assert } from "./util";

let nextTimerId = 1;

// tslint:disable-next-line:no-any
export type TimerCallback = (...args: any[]) => void;

interface Timer {
  id: number;
  cb: TimerCallback;
  interval: boolean;
  // tslint:disable-next-line:no-any
  args: any[];
  delay: number; // milliseconds
}

const timers = new Map<number, Timer>();

export function initTimers() {
  sub("timers", onMessage);
}

function onMessage(payload: Uint8Array) {
  const msg = pb.Msg.decode(payload);
  assert(msg.command === pb.Msg.Command.TIMER_READY);
  const { timerReadyId, timerReadyDone } = msg;
  const timer = timers.get(timerReadyId);
  if (!timer) {
    return;
  }
  timer.cb(...timer.args);
  if (timerReadyDone) {
    timers.delete(timerReadyId);
  }
}

function setTimer(
  cb: TimerCallback,
  delay: number,
  interval: boolean,
  // tslint:disable-next-line:no-any
  args: any[]
): number {
  const timer = {
    id: nextTimerId++,
    interval,
    delay,
    args,
    cb
  };
  timers.set(timer.id, timer);
  pubInternal("timers", {
    command: pb.Msg.Command.TIMER_START,
    timerStartId: timer.id,
    timerStartInterval: timer.interval,
    timerStartDelay: timer.delay
  });
  return timer.id;
}

export function setTimeout(
  cb: TimerCallback,
  delay: number,
  // tslint:disable-next-line:no-any
  ...args: any[]
): number {
  return setTimer(cb, delay, false, args);
}

export function setInterval(
  cb: TimerCallback,
  delay: number,
  // tslint:disable-next-line:no-any
  ...args: any[]
): number {
  return setTimer(cb, delay, true, args);
}

export function clearTimer(id: number) {
  timers.delete(id);
  pubInternal("timers", {
    command: pb.Msg.Command.TIMER_CLEAR,
    timerClearId: id
  });
}