/// SPDX-License-Identifier: GPL-3.0-or-later /// SPDX-FileCopyrightText: Copyright © 2016-2023 Tony Garnock-Jones import { preserves, Observe, floatValue, Turn, Ref } from "@syndicate-lang/core"; import { QuasiValue as Q } from "@syndicate-lang/core"; export message type PeriodicTick(intervalMS); export assertion type TimeLaterThan(deadlineMS); export function sleep(ds: Ref, ms: number, cb: () => void): void { react { at ds { stop on asserted TimeLaterThan(+(new Date()) + ms) { cb(); } } } } export function boot(ds: Ref) { spawn named 'timer/PeriodicTick' { at ds { during Observe({ "pattern": :pattern PeriodicTick(\Q.lit($intervalMS)) }) => spawn named (preserves`PeriodicTick(${intervalMS})`) { const thisFacet = Turn.activeFacet; thisFacet.preventInertCheck(); const handle = setInterval(() => thisFacet.turn(() => { send message PeriodicTick(intervalMS); }), floatValue(intervalMS)); on stop clearInterval(handle); } } } spawn named 'timer/TimeLaterThan' { at ds { during Observe({ "pattern": :pattern TimeLaterThan(\Q.lit($deadlineMS)) }) => spawn named (preserves`TimeLaterThan(${deadlineMS})`) { const thisFacet = Turn.activeFacet; thisFacet.preventInertCheck(); let delta = floatValue(deadlineMS) - (+(new Date())); let handle: any | null = setTimeout(() => thisFacet.turn(() => { handle = null; react { assert TimeLaterThan(deadlineMS); } }), delta); on stop if (handle) { clearTimeout(handle); handle = null; } } } } }