module Simulation.Aivika.Trans.Gate
(Gate,
newGate,
newGateOpened,
newGateClosed,
openGate,
closeGate,
invertGate,
gateOpened,
gateClosed,
awaitGateOpened,
awaitGateClosed,
gateChanged_) where
import Control.Monad
import Simulation.Aivika.Trans.DES
import Simulation.Aivika.Trans.Simulation
import Simulation.Aivika.Trans.Event
import Simulation.Aivika.Trans.Process
import Simulation.Aivika.Trans.Signal
import Simulation.Aivika.Trans.Ref
data Gate m = Gate { gateRef :: Ref m Bool }
newGate :: MonadDES m => Bool -> Simulation m (Gate m)
{-# INLINE newGate #-}
newGate opened =
do r <- newRef opened
return Gate { gateRef = r }
newGateOpened :: MonadDES m => Simulation m (Gate m)
{-# INLINE newGateOpened #-}
newGateOpened = newGate True
newGateClosed :: MonadDES m => Simulation m (Gate m)
{-# INLINE newGateClosed #-}
newGateClosed = newGate False
openGate :: MonadDES m => Gate m -> Event m ()
{-# INLINE openGate #-}
openGate gate =
writeRef (gateRef gate) True
closeGate :: MonadDES m => Gate m -> Event m ()
{-# INLINE closeGate #-}
closeGate gate =
writeRef (gateRef gate) False
invertGate :: MonadDES m => Gate m -> Event m ()
{-# INLINABLE invertGate #-}
invertGate gate =
modifyRef (gateRef gate) not
gateOpened :: MonadDES m => Gate m -> Event m Bool
{-# INLINE gateOpened #-}
gateOpened gate =
readRef (gateRef gate)
gateClosed :: MonadDES m => Gate m -> Event m Bool
{-# INLINE gateClosed #-}
gateClosed gate =
fmap not $ readRef (gateRef gate)
awaitGateOpened :: MonadDES m => Gate m -> Process m ()
{-# INLINABLE awaitGateOpened #-}
awaitGateOpened gate =
do f <- liftEvent $ readRef (gateRef gate)
unless f $
do processAwait $ refChanged_ (gateRef gate)
awaitGateOpened gate
awaitGateClosed :: MonadDES m => Gate m -> Process m ()
{-# INLINABLE awaitGateClosed #-}
awaitGateClosed gate =
do f <- liftEvent $ readRef (gateRef gate)
when f $
do processAwait $ refChanged_ (gateRef gate)
awaitGateClosed gate
gateChanged_ :: MonadDES m => Gate m -> Signal m ()
{-# INLINE gateChanged_ #-}
gateChanged_ gate =
refChanged_ (gateRef gate)