# SPDX-FileCopyrightText: ☭ Emery Hemingway # SPDX-License-Identifier: Unlicense import std/[asyncdispatch, monotimes, times] import preserves import syndicate, syndicate/actors import ../protocols/timer from syndicate/protocols/dataspace import Observe export timer type Observe = dataspace.Observe[Cap] proc now: float64 = getTime().toUnixFloat() proc spawnTimers*(turn: var Turn; ds: Cap): Actor {.discardable.} = ## Spawn a timer actor. spawn("timer", turn) do (turn: var Turn): during(turn, ds, ?Observe(pattern: !LaterThan) ?? {0: grabLit()}) do (seconds: float64): let period = seconds - now() if period < 0.001: discard publish(turn, ds, LaterThan(seconds: seconds)) else: let facet = turn.facet addTimer(int(period * 1_000), oneshot = true) do (fd: AsyncFD) -> bool: run(facet) do (turn: var Turn): discard publish(turn, ds, LaterThan(seconds: seconds)) template after*(turn: var Turn; ds: Cap; dur: Duration; act: untyped) = ## Execute `act` after some duration of time. let later = now() + dur.inMilliseconds.float64 * 1_000.0 onPublish(turn, ds, ?LaterThan(seconds: later), act)