/// SPDX-License-Identifier: GPL-3.0-or-later /// SPDX-FileCopyrightText: Copyright © 2016-2021 Tony Garnock-Jones import { preserves, Observe, Dataspace, floatValue, Facet } from "@syndicate-lang/core"; export message type PeriodicTick(intervalMS); export assertion type TimeLaterThan(deadlineMS); export function sleep(thisFacet: Facet, ms: number, cb: () => void): void { react { stop on asserted TimeLaterThan(+(new Date()) + ms) { cb(); } } } boot { spawn named 'timer/PeriodicTick' { during Observe(PeriodicTick($intervalMS)) => spawn named (preserves`PeriodicTick(${intervalMS})`) { let handle: any | null = null; let finish: (() => void) | null = thisFacet.actor.dataspace.backgroundTask(); on start { handle = setInterval(thisFacet.wrapExternal((thisFacet) => { send message PeriodicTick(intervalMS); }), floatValue(intervalMS as any)); } on stop { if (handle) { clearInterval(handle); handle = null; } if (finish) { finish(); finish = null; } } } } spawn named 'timer/TimeLaterThan' { during Observe(TimeLaterThan($deadlineMS)) => spawn named (preserves`TimeLaterThan(${deadlineMS})`) { let handle: any | null = null; let finish: (() => void) | null = thisFacet.actor.dataspace.backgroundTask(); on start { let delta = floatValue(deadlineMS as any) - (+(new Date())); handle = setTimeout(thisFacet.wrapExternal((thisFacet) => { handle = null; if (finish) finish(); finish = null; react { assert TimeLaterThan(deadlineMS); } }), delta); } on stop { if (handle) { clearTimeout(handle); handle = null; } if (finish) { finish(); finish = null; } } } } }