hbs2/hbs2-core/lib/HBS2/Clock.hs

76 lines
1.8 KiB
Haskell

{-# Language FunctionalDependencies #-}
module HBS2.Clock
( module HBS2.Clock
, module System.Clock
)where
import Control.Concurrent (threadDelay)
import Control.Monad.IO.Class
import Data.Fixed
import Data.Int (Int64)
import Data.Proxy
import Prettyprinter
import System.Clock
data TimeoutKind = MilliSeconds | Seconds | Minutes
data family Timeout ( a :: TimeoutKind )
newtype Wait a = Wait a
deriving newtype (Eq,Show,Pretty)
newtype Delay a = Delay a
deriving newtype (Eq,Show,Pretty)
class IsTimeout a where
toNanoSeconds :: Timeout a -> Int64
toMicroSeconds :: Timeout a -> Int
toMicroSeconds x = fromIntegral $ toNanoSeconds x `div` 1000
toTimeSpec :: Timeout a -> TimeSpec
toTimeSpec x = fromNanoSecs (fromIntegral (toNanoSeconds x))
class IsTimeout a => MonadPause a m where
pause :: Timeout a -> m ()
instance (IsTimeout a, MonadIO m) => MonadPause a m where
pause x = liftIO $ threadDelay (toMicroSeconds x)
instance Pretty (Fixed E9) where
pretty = pretty . show
newtype instance Timeout 'MilliSeconds =
TimeoutMSec (Fixed E9)
deriving newtype (Eq,Ord,Num,Real,Fractional,Show,Pretty)
newtype instance Timeout 'Seconds =
TimeoutSec (Fixed E9)
deriving newtype (Eq,Ord,Num,Real,Fractional,Show,Pretty)
newtype instance Timeout 'Minutes =
TimeoutMin (Fixed E9)
deriving newtype (Eq,Ord,Num,Real,Fractional,Show,Pretty)
instance IsTimeout 'MilliSeconds where
toNanoSeconds (TimeoutMSec x) = round (x * 1e6)
instance IsTimeout 'Seconds where
toNanoSeconds (TimeoutSec x) = round (x * 1e9)
instance IsTimeout 'Minutes where
toNanoSeconds (TimeoutMin x) = round (x * 60 * 1e9)
class Expires a where
expiresIn :: Proxy a -> Maybe (Timeout 'Seconds)
-- FIXME: dangerous!
expiresIn _ = Nothing