reactive-0.9.7: src/FRP/Reactive/Internal/Clock.hs
{-# LANGUAGE ScopedTypeVariables, Rank2Types #-}
{-# OPTIONS_GHC -Wall #-}
----------------------------------------------------------------------
-- |
-- Module : FRP.Reactive.Internal.Clock
-- Copyright : (c) Conal Elliott 2008
-- License : BSD3
--
-- Maintainer : conal@conal.net
-- Stability : experimental
--
-- Serializing clocks
--
-- Thanks to Luke Palmer for help with this module.
----------------------------------------------------------------------
module FRP.Reactive.Internal.Clock
(Clock(..), makeClock) where
import Control.Applicative (liftA2)
import System.Time
import FRP.Reactive.Reactive (TimeT)
-- import FRP.Reactive.Internal.Misc (Sink)
import FRP.Reactive.Internal.Serial
-- | Waits a specified duration and then execute an action
-- type Delay t = t -> forall a. IO a -> IO a
-- | Waits until just after a specified time and then execute an action,
-- passing in the actual time.
-- type Schedule t = t -> Sink (Sink t)
-- | A serializing clock. Can (a) produce a time and (b) serialize an
-- action.
data Clock t = Clock { cGetTime :: IO t
, cSerialize :: Serial
}
-- | Make a clock
makeClock :: IO (Clock TimeT)
makeClock = liftA2 clock getClockTime makeSerial
where
clock :: ClockTime -> Serial -> Clock TimeT
clock refTime serial =
Clock (currRelTime refTime) serial
-- TODO: How can I know that actions are carried out monotonically?
-- | Get the current time in seconds, relative to a start 'ClockTime'.
currRelTime :: ClockTime -> IO TimeT
currRelTime (TOD sec0 pico0) = fmap delta getClockTime
where
delta (TOD sec pico) =
fromIntegral (sec-sec0) + 1.0e-12 * fromIntegral (pico-pico0)