packages feed

vocoder-dunai-0.1.0.0: example/MVarClock.hs

{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeFamilies #-}
module MVarClock where

import Data.Time.Clock
import Control.Concurrent.MVar
import Control.Monad.IO.Class
import Control.Monad.Trans.Reader
import FRP.Rhine

type EventMVarT event m = ReaderT (MVar event) m

withEventMVar :: MVar event -> EventMVarT event m a -> m a
withEventMVar = flip runReaderT

withEventMVarS :: Monad m => MVar event -> ClSF (EventMVarT event m) cl a b -> ClSF m cl a b
withEventMVarS = flip runReaderS_

data MVarClock event = MVarClock

instance Semigroup (MVarClock event) where
    (<>) _ _ = MVarClock

instance MonadIO m => Clock (EventMVarT event m) (MVarClock event) where
    type Time (MVarClock event) = UTCTime
    type Tag (MVarClock event) = event
    initClock _ = do
        initialTime <- liftIO getCurrentTime
        return
            ( constM $ do
                mvar  <- ask
                event <- liftIO $ takeMVar mvar
                time  <- liftIO $ getCurrentTime
                return (time, event)
            , initialTime
            )

instance GetClockProxy (MVarClock event)

mVarClockOn :: MonadIO m => MVar event -> HoistClock (EventMVarT event m) m (MVarClock event)
mVarClockOn mvar = HoistClock
    { unhoistedClock = MVarClock
    , monadMorphism = withEventMVar mvar
    }