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