{-# LANGUAGE Arrows #-}
{-# LANGUAGE RecordWildCards #-}

module FRP.Rhine.Clock.Util where

-- base
import Control.Arrow

-- time-domain
import Data.TimeDomain

-- automaton
import Data.Automaton (Automaton, delay)

-- rhine
import FRP.Rhine.Clock
import FRP.Rhine.Clock.Proxy

-- * Auxiliary definitions and utilities

{- | Given a clock value and an initial time,
   generate a stream of time stamps.
-}
genTimeInfo ::
  (Monad m, Clock m cl) =>
  ClockProxy cl ->
  Time cl ->
  Automaton m (Time cl, Tag cl) (TimeInfo cl)
genTimeInfo :: forall (m :: Type -> Type) cl.
(Monad m, Clock m cl) =>
ClockProxy cl
-> Time cl -> Automaton m (Time cl, Tag cl) (TimeInfo cl)
genTimeInfo ClockProxy cl
_ Time cl
initialTime = proc (Time cl
absolute, Tag cl
tag) -> do
  Time cl
lastTime <- Time cl -> Automaton m (Time cl) (Time cl)
forall (m :: Type -> Type) a. Applicative m => a -> Automaton m a a
delay Time cl
initialTime -< Time cl
absolute
  Automaton m (TimeInfo cl) (TimeInfo cl)
forall (a :: Type -> Type -> Type) b. Arrow a => a b b
returnA
    -<
      TimeInfo
        { sinceLast :: Diff (Time cl)
sinceLast = Time cl
absolute Time cl -> Time cl -> Diff (Time cl)
forall time. TimeDomain time => time -> time -> Diff time
`diffTime` Time cl
lastTime
        , sinceInit :: Diff (Time cl)
sinceInit = Time cl
absolute Time cl -> Time cl -> Diff (Time cl)
forall time. TimeDomain time => time -> time -> Diff time
`diffTime` Time cl
initialTime
        , Time cl
Tag cl
absolute :: Time cl
tag :: Tag cl
absolute :: Time cl
tag :: Tag cl
..
        }