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