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)
newGate opened =
do r <- newRef opened
return Gate { gateRef = r }
newGateOpened :: MonadDES m => Simulation m (Gate m)
newGateOpened = newGate True
newGateClosed :: MonadDES m => Simulation m (Gate m)
newGateClosed = newGate False
openGate :: MonadDES m => Gate m -> Event m ()
openGate gate =
writeRef (gateRef gate) True
closeGate :: MonadDES m => Gate m -> Event m ()
closeGate gate =
writeRef (gateRef gate) False
invertGate :: MonadDES m => Gate m -> Event m ()
invertGate gate =
modifyRef (gateRef gate) not
gateOpened :: MonadDES m => Gate m -> Event m Bool
gateOpened gate =
readRef (gateRef gate)
gateClosed :: MonadDES m => Gate m -> Event m Bool
gateClosed gate =
fmap not $ readRef (gateRef gate)
awaitGateOpened :: MonadDES m => Gate m -> Process m ()
awaitGateOpened gate =
do f <- liftEvent $ readRef (gateRef gate)
unless f $
do processAwait $ refChanged_ (gateRef gate)
awaitGateOpened gate
awaitGateClosed :: MonadDES m => Gate m -> Process m ()
awaitGateClosed gate =
do f <- liftEvent $ readRef (gateRef gate)
when f $
do processAwait $ refChanged_ (gateRef gate)
awaitGateClosed gate
gateChanged_ :: MonadDES m => Gate m -> Signal m ()
gateChanged_ gate =
refChanged_ (gateRef gate)