module Simulation.Aivika.Trans.GPSS.MatchChain
(MatchChain,
newMatchChain,
matchTransact,
transactMatching,
transactMatchingChanged,
transactMatchingChangedByTransact_,
transactMatchingChangedByAssemblySet_) where
import Control.Monad
import Control.Monad.Trans
import qualified Data.HashMap.Lazy as HM
import Simulation.Aivika.Trans
import Simulation.Aivika.Trans.GPSS.Transact
import Simulation.Aivika.Trans.GPSS.AssemblySet
data MatchChain m =
MatchChain { matchChainMap :: Ref m (HM.HashMap (AssemblySet m) (ProcessId m)),
matchChainSource :: SignalSource m (AssemblySet m)
}
newMatchChain :: MonadDES m => Simulation m (MatchChain m)
newMatchChain =
do map <- newRef HM.empty
src <- newSignalSource
return MatchChain { matchChainMap = map,
matchChainSource = src
}
matchTransact :: MonadDES m => MatchChain m -> Transact m a -> Process m ()
matchTransact chain t =
do (map, set) <-
liftEvent $
do map <- readRef (matchChainMap chain)
set <- transactAssemblySet t
return (map, set)
case HM.lookup set map of
Just pid ->
liftEvent $
do modifyRef (matchChainMap chain) $
HM.delete set
yieldEvent $
triggerSignal (matchChainSource chain) set
reactivateProcess pid
Nothing ->
do liftEvent $
do pid <- requireTransactProcessId t
modifyRef (matchChainMap chain) $
HM.insert set pid
yieldEvent $
triggerSignal (matchChainSource chain) set
passivateProcess
transactMatching :: MonadDES m => MatchChain m -> AssemblySet m -> Event m Bool
transactMatching chain set =
do map <- readRef (matchChainMap chain)
return (HM.member set map)
transactMatchingChangedByAssemblySet_ :: MonadDES m => MatchChain m -> AssemblySet m -> Signal m ()
transactMatchingChangedByAssemblySet_ chain set =
mapSignal (const ()) $
filterSignal (== set) $
transactMatchingChanged chain
transactMatchingChangedByTransact_ :: MonadDES m => MatchChain m -> Transact m a -> Signal m ()
transactMatchingChangedByTransact_ chain t =
mapSignal (const ()) $
filterSignalM pred $
transactMatchingChanged chain
where pred set =
do set' <- transactAssemblySet t
return (set == set')
transactMatchingChanged :: MonadDES m => MatchChain m -> Signal m (AssemblySet m)
transactMatchingChanged chain =
publishSignal (matchChainSource chain)