module Simulation.Aivika.Distributed.Optimistic.Internal.Ref.Strict
(Ref,
newRef,
newRef0,
readRef,
writeRef,
modifyRef) where
import Data.IORef
import Control.Monad
import Control.Monad.Trans
import Simulation.Aivika.Trans.Comp
import Simulation.Aivika.Trans.Internal.Types
import Simulation.Aivika.Distributed.Optimistic.Internal.DIO
import Simulation.Aivika.Distributed.Optimistic.Internal.Event
import Simulation.Aivika.Distributed.Optimistic.Internal.IO
import Simulation.Aivika.Distributed.Optimistic.Internal.UndoableLog
newtype Ref a = Ref { refValue :: IORef a }
instance Eq (Ref a) where
(Ref r1) == (Ref r2) = r1 == r2
newRef :: a -> Simulation DIO (Ref a)
newRef = liftComp . newRef0
newRef0 :: a -> DIO (Ref a)
newRef0 a =
do x <- liftIOUnsafe $ newIORef a
return Ref { refValue = x }
readRef :: Ref a -> Event DIO a
readRef r = Event $ \p ->
liftIOUnsafe $ readIORef (refValue r)
writeRef :: Ref a -> a -> Event DIO ()
writeRef r a = Event $ \p ->
do let log = queueLog $ runEventQueue (pointRun p)
a0 <- liftIOUnsafe $ readIORef (refValue r)
invokeEvent p $
writeLog log $
liftIOUnsafe $ writeIORef (refValue r) a0
a `seq` liftIOUnsafe $ writeIORef (refValue r) a
modifyRef :: Ref a -> (a -> a) -> Event DIO ()
modifyRef r f = Event $ \p ->
do let log = queueLog $ runEventQueue (pointRun p)
a <- liftIOUnsafe $ readIORef (refValue r)
let b = f a
invokeEvent p $
writeLog log $
liftIOUnsafe $ writeIORef (refValue r) a
b `seq` liftIOUnsafe $ writeIORef (refValue r) b