{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, FlexibleContexts, UndecidableInstances #-}
module Simulation.Aivika.Trans.Ref
(Ref,
refChanged,
refChanged_,
newRef,
newRef0,
readRef,
writeRef,
modifyRef) where
import Data.IORef
import Control.Monad
import Control.Monad.Trans
import Simulation.Aivika.Trans.Internal.Simulation
import Simulation.Aivika.Trans.Internal.Event
import Simulation.Aivika.Trans.Signal
import qualified Simulation.Aivika.Trans.Ref.Base as B
import Simulation.Aivika.Trans.DES
import Simulation.Aivika.Trans.Observable
data Ref m a =
Ref { forall (m :: * -> *) a. Ref m a -> Ref m a
refValue :: B.Ref m a,
forall (m :: * -> *) a. Ref m a -> SignalSource m a
refChangedSource :: SignalSource m a }
newRef :: MonadDES m => a -> Simulation m (Ref m a)
{-# INLINABLE newRef #-}
newRef :: forall (m :: * -> *) a. MonadDES m => a -> Simulation m (Ref m a)
newRef a
a =
forall (m :: * -> *) a. (Run m -> m a) -> Simulation m a
Simulation forall a b. (a -> b) -> a -> b
$ \Run m
r ->
do Ref m a
x <- forall (m :: * -> *) a. Run m -> Simulation m a -> m a
invokeSimulation Run m
r forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadRef m => a -> Simulation m (Ref m a)
B.newRef a
a
SignalSource m a
s <- forall (m :: * -> *) a. Run m -> Simulation m a -> m a
invokeSimulation Run m
r forall (m :: * -> *) a.
MonadDES m =>
Simulation m (SignalSource m a)
newSignalSource
forall (m :: * -> *) a. Monad m => a -> m a
return Ref { refValue :: Ref m a
refValue = Ref m a
x,
refChangedSource :: SignalSource m a
refChangedSource = SignalSource m a
s }
newRef0 :: (MonadDES m, B.MonadRef0 m) => a -> m (Ref m a)
{-# INLINABLE newRef0 #-}
newRef0 :: forall (m :: * -> *) a.
(MonadDES m, MonadRef0 m) =>
a -> m (Ref m a)
newRef0 a
a =
do Ref m a
x <- forall (m :: * -> *) a. MonadRef0 m => a -> m (Ref m a)
B.newRef0 a
a
SignalSource m a
s <- forall (m :: * -> *) a.
(MonadDES m, MonadRef0 m) =>
m (SignalSource m a)
newSignalSource0
forall (m :: * -> *) a. Monad m => a -> m a
return Ref { refValue :: Ref m a
refValue = Ref m a
x,
refChangedSource :: SignalSource m a
refChangedSource = SignalSource m a
s }
readRef :: MonadDES m => Ref m a -> Event m a
{-# INLINE readRef #-}
readRef :: forall (m :: * -> *) a. MonadDES m => Ref m a -> Event m a
readRef Ref m a
r = forall (m :: * -> *) a. MonadRef m => Ref m a -> Event m a
B.readRef (forall (m :: * -> *) a. Ref m a -> Ref m a
refValue Ref m a
r)
writeRef :: MonadDES m => Ref m a -> a -> Event m ()
{-# INLINABLE writeRef #-}
writeRef :: forall (m :: * -> *) a. MonadDES m => Ref m a -> a -> Event m ()
writeRef Ref m a
r a
a = forall (m :: * -> *) a. (Point m -> m a) -> Event m a
Event forall a b. (a -> b) -> a -> b
$ \Point m
p ->
do a
a seq :: forall a b. a -> b -> b
`seq` forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadRef m => Ref m a -> a -> Event m ()
B.writeRef (forall (m :: * -> *) a. Ref m a -> Ref m a
refValue Ref m a
r) a
a
forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. SignalSource m a -> a -> Event m ()
triggerSignal (forall (m :: * -> *) a. Ref m a -> SignalSource m a
refChangedSource Ref m a
r) a
a
modifyRef :: MonadDES m => Ref m a -> (a -> a) -> Event m ()
{-# INLINABLE modifyRef #-}
modifyRef :: forall (m :: * -> *) a.
MonadDES m =>
Ref m a -> (a -> a) -> Event m ()
modifyRef Ref m a
r a -> a
f = forall (m :: * -> *) a. (Point m -> m a) -> Event m a
Event forall a b. (a -> b) -> a -> b
$ \Point m
p ->
do a
a <- forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadRef m => Ref m a -> Event m a
B.readRef (forall (m :: * -> *) a. Ref m a -> Ref m a
refValue Ref m a
r)
let b :: a
b = a -> a
f a
a
a
b seq :: forall a b. a -> b -> b
`seq` forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadRef m => Ref m a -> a -> Event m ()
B.writeRef (forall (m :: * -> *) a. Ref m a -> Ref m a
refValue Ref m a
r) a
b
forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. SignalSource m a -> a -> Event m ()
triggerSignal (forall (m :: * -> *) a. Ref m a -> SignalSource m a
refChangedSource Ref m a
r) a
b
refChanged :: Ref m a -> Signal m a
{-# INLINE refChanged #-}
refChanged :: forall (m :: * -> *) a. Ref m a -> Signal m a
refChanged Ref m a
r = forall (m :: * -> *) a. SignalSource m a -> Signal m a
publishSignal (forall (m :: * -> *) a. Ref m a -> SignalSource m a
refChangedSource Ref m a
r)
refChanged_ :: MonadDES m => Ref m a -> Signal m ()
{-# INLINABLE refChanged_ #-}
refChanged_ :: forall (m :: * -> *) a. MonadDES m => Ref m a -> Signal m ()
refChanged_ Ref m a
r = forall (m :: * -> *) a b.
MonadDES m =>
(a -> b) -> Signal m a -> Signal m b
mapSignal (forall a b. a -> b -> a
const ()) forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Ref m a -> Signal m a
refChanged Ref m a
r
instance MonadDES m => Eq (Ref m a) where
{-# INLINE (==) #-}
Ref m a
r1 == :: Ref m a -> Ref m a -> Bool
== Ref m a
r2 = (forall (m :: * -> *) a. Ref m a -> Ref m a
refValue Ref m a
r1) forall a. Eq a => a -> a -> Bool
== (forall (m :: * -> *) a. Ref m a -> Ref m a
refValue Ref m a
r2)
instance (MonadDES m, Observable (B.Ref m) (t m)) => Observable (Ref m) (t m) where
{-# INLINE readObservable #-}
readObservable :: forall a. Ref m a -> t m a
readObservable Ref m a
r = forall (o :: * -> *) (m :: * -> *) a. Observable o m => o a -> m a
readObservable (forall (m :: * -> *) a. Ref m a -> Ref m a
refValue Ref m a
r)