//--------------------------------------------------------------------------- // @syndicate-lang/driver-timer, a Syndicate driver for time-related events. // Copyright (C) 2016-2018 Tony Garnock-Jones // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . //--------------------------------------------------------------------------- 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; } } } } }