summaryrefslogtreecommitdiff
path: root/js/timers.ts
blob: 42be96d91b0d677ad65f70dc63b209edd961eace (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
90
91
92
93
94
95
96
97
98
// Copyright 2018 the Deno authors. All rights reserved. MIT license.
import { assert } from "./util";
import * as util from "./util";
import * as fbs from "gen/msg_generated";
import { flatbuffers } from "flatbuffers";
import { sendSync, sendAsync } from "./dispatch";

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
}

function startTimer(
  id: number,
  cb: TimerCallback,
  delay: number,
  interval: boolean,
  // tslint:disable-next-line:no-any
  args: any[]
): void {
  const timer: Timer = {
    id,
    interval,
    delay,
    args,
    cb
  };
  util.log("timers.ts startTimer");

  // Send TimerStart message
  const builder = new flatbuffers.Builder();
  fbs.TimerStart.startTimerStart(builder);
  fbs.TimerStart.addId(builder, timer.id);
  fbs.TimerStart.addDelay(builder, timer.delay);
  const msg = fbs.TimerStart.endTimerStart(builder);

  sendAsync(builder, fbs.Any.TimerStart, msg).then(
    baseRes => {
      assert(fbs.Any.TimerReady === baseRes!.msgType());
      const msg = new fbs.TimerReady();
      assert(baseRes!.msg(msg) != null);
      assert(msg.id() === timer.id);
      if (msg.canceled()) {
        util.log("timer canceled message");
      } else {
        cb(...args);
        if (interval) {
          // TODO Faking setInterval with setTimeout.
          // We need a new timer implementation, this is just a stopgap.
          startTimer(id, cb, delay, true, args);
        }
      }
    },
    error => {
      throw error;
    }
  );
}

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

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

export function clearTimer(id: number) {
  const builder = new flatbuffers.Builder();
  fbs.TimerClear.startTimerClear(builder);
  fbs.TimerClear.addId(builder, id);
  const msg = fbs.TimerClear.endTimerClear(builder);
  const res = sendSync(builder, fbs.Any.TimerClear, msg);
  assert(res == null);
}