moffy-0.1.0.0: src/Control/Moffy/Event/Time.hs
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE BlockArguments #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE DataKinds, TypeOperators #-}
{-# LANGUAGE TypeFamilies #-}
{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}
module Control.Moffy.Event.Time (
-- * Time Event
TimeEv,
-- * Elapsed
DeltaTime(..), pattern OccDeltaTime, deltaTime, elapsed,
-- * Sleep
TryWait(..), pattern OccTryWait, sleep ) where
import Prelude hiding (repeat, scanl)
import GHC.Stack (HasCallStack)
import Control.Moffy (Sig, React, Request(..), await, repeat, scanl)
import Data.Type.Set (numbered, pattern Nil, Singleton, (:-))
import Data.Bool (bool)
import Data.Time (DiffTime)
---------------------------------------------------------------------------
-- * ELAPSED
-- * SLEEP
-- * TIME EVENT
---------------------------------------------------------------------------
---------------------------------------------------------------------------
-- ELAPSED
---------------------------------------------------------------------------
data DeltaTime = DeltaTimeReq deriving (Show, Eq, Ord)
numbered [t| DeltaTime |]
instance Request DeltaTime where data Occurred DeltaTime = OccDeltaTime DiffTime
deltaTime :: React s (Singleton DeltaTime) DiffTime
deltaTime = await DeltaTimeReq \(OccDeltaTime t) -> t
elapsed :: Sig s (Singleton DeltaTime) DiffTime r
elapsed = scanl (+) 0 $ repeat deltaTime
---------------------------------------------------------------------------
-- SLEEP
---------------------------------------------------------------------------
newtype TryWait = TryWaitReq DiffTime deriving (Show, Eq, Ord)
numbered [t| TryWait |]
instance Request TryWait where data Occurred TryWait = OccTryWait DiffTime
tryWait :: DiffTime -> React s (Singleton TryWait) DiffTime
tryWait t = await (TryWaitReq t) \(OccTryWait t') -> t'
sleep :: HasCallStack => DiffTime -> React s (Singleton TryWait) ()
sleep t | t <= 0 = error "sleep t: t (seconds) should be positive"
sleep t = tryWait t >>= \t' -> bool (sleep (t - t')) (pure ()) (t' == t)
---------------------------------------------------------------------------
-- TIME EVENT
---------------------------------------------------------------------------
type TimeEv = DeltaTime :- TryWait :- 'Nil