module Simulation.Aivika.RealTime.Internal.RT
(RT(..),
RTParams(..),
RTContext(..),
RTScaling(..),
invokeRT,
runRT,
defaultRTParams,
newRTContext,
rtParams,
rtChannel,
rtScale) where
import Control.Applicative
import Control.Monad
import Control.Monad.Trans
import Simulation.Aivika.Trans.Exception
import Simulation.Aivika.Trans.Internal.Types
import Simulation.Aivika.RealTime.Internal.Channel
data RTScaling = RTLinearScaling Double
| RTLogScaling Double
| RTScalingFunction (Double -> Double -> Double)
rtScale :: RTScaling
-> Double
-> Double
-> Double
rtScale :: RTScaling -> Double -> Double -> Double
rtScale (RTLinearScaling Double
k) Double
t0 Double
t = Double
k forall a. Num a => a -> a -> a
* (Double
t forall a. Num a => a -> a -> a
- Double
t0)
rtScale (RTLogScaling Double
k) Double
t0 Double
t = Double
k forall a. Num a => a -> a -> a
* forall a. Floating a => a -> a
log (Double
t forall a. Num a => a -> a -> a
- Double
t0)
rtScale (RTScalingFunction Double -> Double -> Double
f) Double
t0 Double
t = Double -> Double -> Double
f Double
t0 Double
t
data RTParams =
RTParams { RTParams -> RTScaling
rtScaling :: RTScaling,
RTParams -> Double
rtIntervalDelta :: Double
}
newtype RT m a = RT { forall (m :: * -> *) a. RT m a -> RTContext m -> m a
unRT :: RTContext m -> m a
}
data RTContext m =
RTContext { forall (m :: * -> *). RTContext m -> Channel (Event (RT m) ())
rtChannel0 :: Channel (Event (RT m) ()),
forall (m :: * -> *). RTContext m -> RTParams
rtParams0 :: RTParams
}
instance Monad m => Monad (RT m) where
{-# INLINE (>>=) #-}
(RT RTContext m -> m a
m) >>= :: forall a b. RT m a -> (a -> RT m b) -> RT m b
>>= a -> RT m b
k = forall (m :: * -> *) a. (RTContext m -> m a) -> RT m a
RT forall a b. (a -> b) -> a -> b
$ \RTContext m
ctx ->
RTContext m -> m a
m RTContext m
ctx forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \a
a ->
let m' :: RTContext m -> m b
m' = forall (m :: * -> *) a. RT m a -> RTContext m -> m a
unRT (a -> RT m b
k a
a) in RTContext m -> m b
m' RTContext m
ctx
instance Applicative m => Applicative (RT m) where
{-# INLINE pure #-}
pure :: forall a. a -> RT m a
pure = forall (m :: * -> *) a. (RTContext m -> m a) -> RT m a
RT forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. a -> b -> a
const forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a. Applicative f => a -> f a
pure
{-# INLINE (<*>) #-}
(RT RTContext m -> m (a -> b)
f) <*> :: forall a b. RT m (a -> b) -> RT m a -> RT m b
<*> (RT RTContext m -> m a
m) = forall (m :: * -> *) a. (RTContext m -> m a) -> RT m a
RT forall a b. (a -> b) -> a -> b
$ \RTContext m
ctx -> RTContext m -> m (a -> b)
f RTContext m
ctx forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> RTContext m -> m a
m RTContext m
ctx
instance Functor m => Functor (RT m) where
{-# INLINE fmap #-}
fmap :: forall a b. (a -> b) -> RT m a -> RT m b
fmap a -> b
f (RT RTContext m -> m a
m) = forall (m :: * -> *) a. (RTContext m -> m a) -> RT m a
RT forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. RTContext m -> m a
m
instance MonadIO m => MonadIO (RT m) where
{-# INLINE liftIO #-}
liftIO :: forall a. IO a -> RT m a
liftIO = forall (m :: * -> *) a. (RTContext m -> m a) -> RT m a
RT forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. a -> b -> a
const forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO
instance MonadException m => MonadException (RT m) where
{-# INLINE catchComp #-}
catchComp :: forall e a. Exception e => RT m a -> (e -> RT m a) -> RT m a
catchComp (RT RTContext m -> m a
m) e -> RT m a
h = forall (m :: * -> *) a. (RTContext m -> m a) -> RT m a
RT forall a b. (a -> b) -> a -> b
$ \RTContext m
ctx ->
forall (m :: * -> *) e a.
(MonadException m, Exception e) =>
m a -> (e -> m a) -> m a
catchComp (RTContext m -> m a
m RTContext m
ctx) (\e
e -> forall (m :: * -> *) a. RT m a -> RTContext m -> m a
unRT (e -> RT m a
h e
e) RTContext m
ctx)
{-# INLINE finallyComp #-}
finallyComp :: forall a b. RT m a -> RT m b -> RT m a
finallyComp (RT RTContext m -> m a
m1) (RT RTContext m -> m b
m2) = forall (m :: * -> *) a. (RTContext m -> m a) -> RT m a
RT forall a b. (a -> b) -> a -> b
$ \RTContext m
ctx ->
forall (m :: * -> *) a b. MonadException m => m a -> m b -> m a
finallyComp (RTContext m -> m a
m1 RTContext m
ctx) (RTContext m -> m b
m2 RTContext m
ctx)
{-# INLINE throwComp #-}
throwComp :: forall e a. Exception e => e -> RT m a
throwComp e
e = forall (m :: * -> *) a. (RTContext m -> m a) -> RT m a
RT forall a b. (a -> b) -> a -> b
$ \RTContext m
ctx ->
forall (m :: * -> *) e a.
(MonadException m, Exception e) =>
e -> m a
throwComp e
e
invokeRT :: RTContext m -> RT m a -> m a
{-# INLINE invokeRT #-}
invokeRT :: forall (m :: * -> *) a. RTContext m -> RT m a -> m a
invokeRT RTContext m
ctx (RT RTContext m -> m a
m) = RTContext m -> m a
m RTContext m
ctx
defaultRTParams :: RTParams
defaultRTParams :: RTParams
defaultRTParams =
RTParams { rtScaling :: RTScaling
rtScaling = Double -> RTScaling
RTLinearScaling Double
1,
rtIntervalDelta :: Double
rtIntervalDelta = Double
0.001
}
rtParams :: Monad m => RT m RTParams
{-# INLINE rtParams #-}
rtParams :: forall (m :: * -> *). Monad m => RT m RTParams
rtParams = forall (m :: * -> *) a. (RTContext m -> m a) -> RT m a
RT forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *). RTContext m -> RTParams
rtParams0
rtChannel :: Monad m => RT m (Channel (Event (RT m) ()))
{-# INLINE rtChannel #-}
rtChannel :: forall (m :: * -> *). Monad m => RT m (Channel (Event (RT m) ()))
rtChannel = forall (m :: * -> *) a. (RTContext m -> m a) -> RT m a
RT forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *). RTContext m -> Channel (Event (RT m) ())
rtChannel0
runRT :: RT m a -> RTContext m -> m a
runRT :: forall (m :: * -> *) a. RT m a -> RTContext m -> m a
runRT = forall (m :: * -> *) a. RT m a -> RTContext m -> m a
unRT
newRTContext :: RTParams -> IO (RTContext m)
newRTContext :: forall (m :: * -> *). RTParams -> IO (RTContext m)
newRTContext RTParams
ps =
do Channel (Event (RT m) ())
channel <- forall a. IO (Channel a)
newChannel
forall (m :: * -> *) a. Monad m => a -> m a
return RTContext { rtChannel0 :: Channel (Event (RT m) ())
rtChannel0 = Channel (Event (RT m) ())
channel,
rtParams0 :: RTParams
rtParams0 = RTParams
ps }