module Simulation.Aivika.Ref.Base
(Ref,
newRef,
readRef,
writeRef,
modifyRef) where
import Data.IORef
import Control.Monad
import Control.Monad.Trans
import Simulation.Aivika.Internal.Simulation
import Simulation.Aivika.Internal.Event
newtype Ref a =
Ref { forall a. Ref a -> IORef a
refValue :: IORef a }
newRef :: a -> Simulation (Ref a)
newRef :: forall a. a -> Simulation (Ref a)
newRef a
a =
do IORef a
x <- forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a. a -> IO (IORef a)
newIORef a
a
forall (m :: * -> *) a. Monad m => a -> m a
return Ref { refValue :: IORef a
refValue = IORef a
x }
readRef :: Ref a -> Event a
readRef :: forall a. Ref a -> Event a
readRef Ref a
r = forall a. (Point -> IO a) -> Event a
Event forall a b. (a -> b) -> a -> b
$ \Point
p -> forall a. IORef a -> IO a
readIORef (forall a. Ref a -> IORef a
refValue Ref a
r)
writeRef :: Ref a -> a -> Event ()
writeRef :: forall a. Ref a -> a -> Event ()
writeRef Ref a
r a
a = forall a. (Point -> IO a) -> Event a
Event forall a b. (a -> b) -> a -> b
$ \Point
p ->
a
a seq :: forall a b. a -> b -> b
`seq` forall a. IORef a -> a -> IO ()
writeIORef (forall a. Ref a -> IORef a
refValue Ref a
r) a
a
modifyRef :: Ref a -> (a -> a) -> Event ()
modifyRef :: forall a. Ref a -> (a -> a) -> Event ()
modifyRef Ref a
r a -> a
f = forall a. (Point -> IO a) -> Event a
Event forall a b. (a -> b) -> a -> b
$ \Point
p ->
do a
a <- forall a. IORef a -> IO a
readIORef (forall a. Ref a -> IORef a
refValue Ref a
r)
let b :: a
b = a -> a
f a
a
a
b seq :: forall a b. a -> b -> b
`seq` forall a. IORef a -> a -> IO ()
writeIORef (forall a. Ref a -> IORef a
refValue Ref a
r) a
b