# SPDX-FileCopyrightText: ☭ Emery Hemingway # SPDX-License-Identifier: Unlicense import std/[asyncdispatch, monotimes, times, posix, times, epoll] import preserves import ../syndicate, ../protocols/timer from ../protocols/dataspace import Observe export timer type Observe = dataspace.Observe #[ proc timerfd_create(clock_id: ClockId, flags: cint): cint {.importc: "timerfd_create", header: "".} proc timerfd_settime(ufd: cint, flags: cint, utmr: var Itimerspec, otmr: var Itimerspec): cint {.importc: "timerfd_settime", header: "".} proc eventfd(count: cuint, flags: cint): cint {.importc: "eventfd", header: "".} ]# proc now: float64 = getTime().toUnixFloat() proc spawnTimers*(ds: Cap): Actor {.discardable.} = ## Spawn a timer actor. bootActor("timers") do (root: Facet): let pat = inject(grab Observe(pattern: dropType LaterThan), {0: grabLit()}) #[ during(ds, pat) do (seconds: float): let period = seconds - now() if period < 0.001 or true: let h = publish(ds, LaterThan(seconds: seconds).toPreserves) ]# #[ else: let fdi = timerfd_create(CLOCK_MONOTONIC, O_CLOEXEC or O_NONBLOCK) addCallback(sleepAsync(period * 1_000), turn) do (turn: Turn): discard publish(turn, ds, LaterThan(seconds: seconds)) ]# #[ proc after*(ds: Cap; dur: Duration; cb: proc () {.closure.}) = ## Execute `act` after some duration of time. let later = now() + dur.inMilliseconds.float64 * 1_000.0 onPublish(ds, grab LaterThan(seconds: later)): cb() ]# # TODO: periodic timer