module Simulation.Aivika.Gate
(Gate,
newGate,
newGateOpened,
newGateClosed,
openGate,
closeGate,
invertGate,
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 { Gate -> Ref Bool
gateRef :: Ref Bool }
newGate :: Bool -> Simulation Gate
newGate :: Bool -> Simulation Gate
newGate Bool
opened =
do Ref Bool
r <- forall a. a -> Simulation (Ref a)
newRef Bool
opened
forall (m :: * -> *) a. Monad m => a -> m a
return Gate { gateRef :: Ref Bool
gateRef = Ref Bool
r }
newGateOpened :: Simulation Gate
newGateOpened :: Simulation Gate
newGateOpened = Bool -> Simulation Gate
newGate Bool
True
newGateClosed :: Simulation Gate
newGateClosed :: Simulation Gate
newGateClosed = Bool -> Simulation Gate
newGate Bool
False
openGate :: Gate -> Event ()
openGate :: Gate -> Event ()
openGate Gate
gate =
forall a. Ref a -> a -> Event ()
writeRef (Gate -> Ref Bool
gateRef Gate
gate) Bool
True
closeGate :: Gate -> Event ()
closeGate :: Gate -> Event ()
closeGate Gate
gate =
forall a. Ref a -> a -> Event ()
writeRef (Gate -> Ref Bool
gateRef Gate
gate) Bool
False
invertGate :: Gate -> Event ()
invertGate :: Gate -> Event ()
invertGate Gate
gate =
forall a. Ref a -> (a -> a) -> Event ()
modifyRef (Gate -> Ref Bool
gateRef Gate
gate) Bool -> Bool
not
gateOpened :: Gate -> Event Bool
gateOpened :: Gate -> Event Bool
gateOpened Gate
gate =
forall a. Ref a -> Event a
readRef (Gate -> Ref Bool
gateRef Gate
gate)
gateClosed :: Gate -> Event Bool
gateClosed :: Gate -> Event Bool
gateClosed Gate
gate =
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Bool -> Bool
not forall a b. (a -> b) -> a -> b
$ forall a. Ref a -> Event a
readRef (Gate -> Ref Bool
gateRef Gate
gate)
awaitGateOpened :: Gate -> Process ()
awaitGateOpened :: Gate -> Process ()
awaitGateOpened Gate
gate =
do Bool
f <- forall (m :: * -> *) a. EventLift m => Event a -> m a
liftEvent forall a b. (a -> b) -> a -> b
$ forall a. Ref a -> Event a
readRef (Gate -> Ref Bool
gateRef Gate
gate)
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
f forall a b. (a -> b) -> a -> b
$
do forall a. Signal a -> Process a
processAwait forall a b. (a -> b) -> a -> b
$ forall a. Ref a -> Signal ()
refChanged_ (Gate -> Ref Bool
gateRef Gate
gate)
Gate -> Process ()
awaitGateOpened Gate
gate
awaitGateClosed :: Gate -> Process ()
awaitGateClosed :: Gate -> Process ()
awaitGateClosed Gate
gate =
do Bool
f <- forall (m :: * -> *) a. EventLift m => Event a -> m a
liftEvent forall a b. (a -> b) -> a -> b
$ forall a. Ref a -> Event a
readRef (Gate -> Ref Bool
gateRef Gate
gate)
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
f forall a b. (a -> b) -> a -> b
$
do forall a. Signal a -> Process a
processAwait forall a b. (a -> b) -> a -> b
$ forall a. Ref a -> Signal ()
refChanged_ (Gate -> Ref Bool
gateRef Gate
gate)
Gate -> Process ()
awaitGateClosed Gate
gate
gateChanged_ :: Gate -> Signal ()
gateChanged_ :: Gate -> Signal ()
gateChanged_ Gate
gate =
forall a. Ref a -> Signal ()
refChanged_ (Gate -> Ref Bool
gateRef Gate
gate)