mediabus-0.2.0.0: src/Data/MediaBus/Clock.hs
module Data.MediaBus.Clock
( IsClock(..)
, timeSince
, UtcClock(..)
, useUtcClock
, _utcClockTimeDiff
, _utcClockTime
, utcClockTimeDiff
) where
import Conduit
import Control.Lens
import Data.Default
import Data.Function ( on )
import Data.Kind
import Data.MediaBus.Monotone
import Data.Proxy
import Data.Time.Calendar
import Data.Time.Clock
import Data.Word
import Test.QuickCheck
import GHC.Generics ( Generic )
import Control.DeepSeq
-- | Clocks can generate reference times, and they can convert these to tickss. Tickss are mere integrals
class (Default (ClockTimeDiff c), Ord (ClockTimeDiff c), Eq (ClockTimeDiff c), Num (ClockTimeDiff c), Show (ClockTime c), Eq (ClockTime c), Show (ClockTimeDiff c), LocalOrd (ClockTimeDiff c)) =>
IsClock c where
data ClockTime c
data ClockTimeDiff c
type MonadClock c (m :: Type -> Type) :: Constraint
now :: MonadClock c m => m (ClockTime c)
timeAsTimeDiff :: ClockTime c -> ClockTimeDiff c
diffTime :: ClockTime c -> ClockTime c -> ClockTimeDiff c
timeAddTimeDiff :: ClockTime c -> ClockTimeDiff c -> ClockTime c
timeSince :: (IsClock c, MonadClock c m, Monad m) => ClockTime c -> m (ClockTimeDiff c)
timeSince t0 = do
t1 <- now
return (diffTime t1 t0)
data UtcClock = MkUtcClock
deriving Generic
instance NFData UtcClock
useUtcClock :: Proxy UtcClock
useUtcClock = Proxy
instance IsClock UtcClock where
newtype ClockTime UtcClock = MkUtcClockTime{_utcClockTime :: UTCTime}
deriving (Eq, Generic)
newtype ClockTimeDiff UtcClock = MkUtcClockTimeDiff{_utcClockTimeDiff ::
NominalDiffTime}
deriving (Ord, Eq, Num, Generic)
type MonadClock UtcClock m = MonadIO m
now = MkUtcClockTime <$> liftIO getCurrentTime
timeAsTimeDiff (MkUtcClockTime ref) =
MkUtcClockTimeDiff $ diffUTCTime ref $ UTCTime (toEnum 0) 0
timeAddTimeDiff (MkUtcClockTime t) (MkUtcClockTimeDiff dt) =
MkUtcClockTime (addUTCTime dt t)
diffTime (MkUtcClockTime later) (MkUtcClockTime sooner) =
MkUtcClockTimeDiff $ diffUTCTime later sooner
instance NFData (ClockTime UtcClock)
instance Show (ClockTime UtcClock) where
show (MkUtcClockTime t) = show t
instance Show (ClockTimeDiff UtcClock) where
show (MkUtcClockTimeDiff t) =
"dt:" ++ show t
instance NFData (ClockTimeDiff UtcClock)
instance Default (ClockTimeDiff UtcClock) where
def = MkUtcClockTimeDiff $ fromInteger def
instance Arbitrary (ClockTime UtcClock) where
arbitrary = MkUtcClockTime <$> (UTCTime <$> (ModifiedJulianDay <$> arbitrary)
<*> (fromInteger <$> arbitrary))
instance Arbitrary (ClockTimeDiff UtcClock) where
arbitrary = MkUtcClockTimeDiff . fromInteger <$> arbitrary
utcClockTimeDiff :: Lens' (ClockTimeDiff UtcClock) NominalDiffTime
utcClockTimeDiff = lens _utcClockTimeDiff (const MkUtcClockTimeDiff)
instance LocalOrd (ClockTimeDiff UtcClock) where
succeeds = succeeds `on` roundToSeconds
where
roundToSeconds = round . (/ 1000000000000) . _utcClockTimeDiff
roundToSeconds :: ClockTimeDiff UtcClock -> Word64