module Simulation.Aivika.RealTime.RT
(
RT,
RTParams(..),
RTContext,
RTScaling(..),
runRT,
defaultRTParams,
newRTContext,
rtParams,
rtScale,
applyEventRT,
applyEventRT_,
enqueueEventRT,
enqueueEventRT_) where
import Control.Monad
import Control.Monad.Trans
import Control.Concurrent.STM
import Control.Concurrent.Async
import Simulation.Aivika.Trans
import Simulation.Aivika.IO.Comp
import Simulation.Aivika.IO.Ref.Base
import Simulation.Aivika.IO.QueueStrategy
import Simulation.Aivika.IO.Exception
import Simulation.Aivika.RealTime.Internal.RT
import Simulation.Aivika.RealTime.Internal.Channel
import Simulation.Aivika.RealTime.Event
import Simulation.Aivika.RealTime.QueueStrategy
import Simulation.Aivika.RealTime.Comp
import Simulation.Aivika.RealTime.Ref.Base.Lazy
import Simulation.Aivika.RealTime.Ref.Base.Strict
instance (Monad m, MonadIO m, MonadException m, MonadComp m) => MonadDES (RT m) where
{-# SPECIALIZE instance MonadDES (RT IO) #-}
instance (Monad m, MonadIO m, MonadException m) => EventIOQueueing (RT m) where
{-# SPECIALIZE instance EventIOQueueing (RT IO) #-}
enqueueEventIO :: Double -> Event (RT m) () -> Event (RT m) ()
enqueueEventIO = Double -> Event (RT m) () -> Event (RT m) ()
forall (m :: * -> *).
EventQueueing m =>
Double -> Event m () -> Event m ()
enqueueEvent
invokeEventRT_ :: MonadIO m
=> RTContext m
-> (Event (RT m) () -> Event (RT m) ())
-> Event (RT m) ()
-> m ()
{-# INLINABLE invokeEventRT_ #-}
invokeEventRT_ :: RTContext m
-> (Event (RT m) () -> Event (RT m) ()) -> Event (RT m) () -> m ()
invokeEventRT_ RTContext m
ctx Event (RT m) () -> Event (RT m) ()
f Event (RT m) ()
m =
let ch :: Channel (Event (RT m) ())
ch = RTContext m -> Channel (Event (RT m) ())
forall (m :: * -> *). RTContext m -> Channel (Event (RT m) ())
rtChannel0 RTContext m
ctx
in IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ Channel (Event (RT m) ()) -> Event (RT m) () -> IO ()
forall a. Channel a -> a -> IO ()
writeChannel Channel (Event (RT m) ())
ch (Event (RT m) () -> IO ()) -> Event (RT m) () -> IO ()
forall a b. (a -> b) -> a -> b
$ Event (RT m) () -> Event (RT m) ()
f Event (RT m) ()
m
invokeEventRT :: MonadIO m
=> RTContext m
-> (Event (RT m) () -> Event (RT m) ())
-> Event (RT m) a
-> m (Async a)
{-# INLINABLE invokeEventRT #-}
invokeEventRT :: RTContext m
-> (Event (RT m) () -> Event (RT m) ())
-> Event (RT m) a
-> m (Async a)
invokeEventRT RTContext m
ctx Event (RT m) () -> Event (RT m) ()
f Event (RT m) a
m =
do let ch :: Channel (Event (RT m) ())
ch = RTContext m -> Channel (Event (RT m) ())
forall (m :: * -> *). RTContext m -> Channel (Event (RT m) ())
rtChannel0 RTContext m
ctx
TVar (Maybe a)
v <- IO (TVar (Maybe a)) -> m (TVar (Maybe a))
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (TVar (Maybe a)) -> m (TVar (Maybe a)))
-> IO (TVar (Maybe a)) -> m (TVar (Maybe a))
forall a b. (a -> b) -> a -> b
$ Maybe a -> IO (TVar (Maybe a))
forall a. a -> IO (TVar a)
newTVarIO Maybe a
forall a. Maybe a
Nothing
IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$
Channel (Event (RT m) ()) -> Event (RT m) () -> IO ()
forall a. Channel a -> a -> IO ()
writeChannel Channel (Event (RT m) ())
ch (Event (RT m) () -> IO ()) -> Event (RT m) () -> IO ()
forall a b. (a -> b) -> a -> b
$
Event (RT m) () -> Event (RT m) ()
f (Event (RT m) () -> Event (RT m) ())
-> Event (RT m) () -> Event (RT m) ()
forall a b. (a -> b) -> a -> b
$
do a
a <- Event (RT m) a
m
IO () -> Event (RT m) ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> Event (RT m) ()) -> IO () -> Event (RT m) ()
forall a b. (a -> b) -> a -> b
$
STM () -> IO ()
forall a. STM a -> IO a
atomically (STM () -> IO ()) -> STM () -> IO ()
forall a b. (a -> b) -> a -> b
$
TVar (Maybe a) -> Maybe a -> STM ()
forall a. TVar a -> a -> STM ()
writeTVar TVar (Maybe a)
v (a -> Maybe a
forall a. a -> Maybe a
Just a
a)
IO (Async a) -> m (Async a)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Async a) -> m (Async a)) -> IO (Async a) -> m (Async a)
forall a b. (a -> b) -> a -> b
$
IO a -> IO (Async a)
forall a. IO a -> IO (Async a)
async (IO a -> IO (Async a)) -> IO a -> IO (Async a)
forall a b. (a -> b) -> a -> b
$
STM a -> IO a
forall a. STM a -> IO a
atomically (STM a -> IO a) -> STM a -> IO a
forall a b. (a -> b) -> a -> b
$
do Maybe a
b <- TVar (Maybe a) -> STM (Maybe a)
forall a. TVar a -> STM a
readTVar TVar (Maybe a)
v
case Maybe a
b of
Just a
a -> a -> STM a
forall (m :: * -> *) a. Monad m => a -> m a
return a
a
Maybe a
Nothing -> STM a
forall a. STM a
retry
applyEventRT :: MonadIO m => RTContext m -> Event (RT m) a -> m (Async a)
{-# INLINABLE applyEventRT #-}
applyEventRT :: RTContext m -> Event (RT m) a -> m (Async a)
applyEventRT RTContext m
ctx Event (RT m) a
m = RTContext m
-> (Event (RT m) () -> Event (RT m) ())
-> Event (RT m) a
-> m (Async a)
forall (m :: * -> *) a.
MonadIO m =>
RTContext m
-> (Event (RT m) () -> Event (RT m) ())
-> Event (RT m) a
-> m (Async a)
invokeEventRT RTContext m
ctx Event (RT m) () -> Event (RT m) ()
forall a. a -> a
id Event (RT m) a
m
applyEventRT_ :: MonadIO m => RTContext m -> Event (RT m) () -> m ()
{-# INLINABLE applyEventRT_ #-}
applyEventRT_ :: RTContext m -> Event (RT m) () -> m ()
applyEventRT_ RTContext m
ctx Event (RT m) ()
m = RTContext m
-> (Event (RT m) () -> Event (RT m) ()) -> Event (RT m) () -> m ()
forall (m :: * -> *).
MonadIO m =>
RTContext m
-> (Event (RT m) () -> Event (RT m) ()) -> Event (RT m) () -> m ()
invokeEventRT_ RTContext m
ctx Event (RT m) () -> Event (RT m) ()
forall a. a -> a
id Event (RT m) ()
m
enqueueEventRT :: MonadIO m => RTContext m -> Double -> Event (RT m) a -> m (Async a)
{-# INLINABLE enqueueEventRT #-}
enqueueEventRT :: RTContext m -> Double -> Event (RT m) a -> m (Async a)
enqueueEventRT RTContext m
ctx Double
t Event (RT m) a
m = RTContext m
-> (Event (RT m) () -> Event (RT m) ())
-> Event (RT m) a
-> m (Async a)
forall (m :: * -> *) a.
MonadIO m =>
RTContext m
-> (Event (RT m) () -> Event (RT m) ())
-> Event (RT m) a
-> m (Async a)
invokeEventRT RTContext m
ctx (Double -> Event (RT m) () -> Event (RT m) ()
forall (m :: * -> *).
EventQueueing m =>
Double -> Event m () -> Event m ()
enqueueEvent Double
t) Event (RT m) a
m
enqueueEventRT_ :: MonadIO m => RTContext m -> Double -> Event (RT m) () -> m ()
{-# INLINABLE enqueueEventRT_ #-}
enqueueEventRT_ :: RTContext m -> Double -> Event (RT m) () -> m ()
enqueueEventRT_ RTContext m
ctx Double
t Event (RT m) ()
m = RTContext m
-> (Event (RT m) () -> Event (RT m) ()) -> Event (RT m) () -> m ()
forall (m :: * -> *).
MonadIO m =>
RTContext m
-> (Event (RT m) () -> Event (RT m) ()) -> Event (RT m) () -> m ()
invokeEventRT_ RTContext m
ctx (Double -> Event (RT m) () -> Event (RT m) ()
forall (m :: * -> *).
EventQueueing m =>
Double -> Event m () -> Event m ()
enqueueEvent Double
t) Event (RT m) ()
m