module Simulation.Aivika.GPSS.MatchChain
(MatchChain,
newMatchChain,
matchTransact,
transactMatching,
transactMatchingChanged,
transactMatchingChangedByTransact_,
transactMatchingChangedByAssemblySet_) where
import Data.IORef
import Control.Monad
import Control.Monad.Trans
import qualified Data.HashMap.Lazy as HM
import Simulation.Aivika
import Simulation.Aivika.GPSS.Transact
import Simulation.Aivika.GPSS.AssemblySet
data MatchChain =
MatchChain { MatchChain -> IORef (HashMap AssemblySet ProcessId)
matchChainMap :: IORef (HM.HashMap AssemblySet ProcessId),
MatchChain -> SignalSource AssemblySet
matchChainSource :: SignalSource AssemblySet
}
newMatchChain :: Simulation MatchChain
newMatchChain :: Simulation MatchChain
newMatchChain =
do IORef (HashMap AssemblySet ProcessId)
map <- forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a. a -> IO (IORef a)
newIORef forall k v. HashMap k v
HM.empty
SignalSource AssemblySet
src <- forall a. Simulation (SignalSource a)
newSignalSource
forall (m :: * -> *) a. Monad m => a -> m a
return MatchChain { matchChainMap :: IORef (HashMap AssemblySet ProcessId)
matchChainMap = IORef (HashMap AssemblySet ProcessId)
map,
matchChainSource :: SignalSource AssemblySet
matchChainSource = SignalSource AssemblySet
src
}
matchTransact :: MatchChain -> Transact a -> Process ()
matchTransact :: forall a. MatchChain -> Transact a -> Process ()
matchTransact MatchChain
chain Transact a
t =
do (HashMap AssemblySet ProcessId
map, AssemblySet
set) <-
forall (m :: * -> *) a. EventLift m => Event a -> m a
liftEvent forall a b. (a -> b) -> a -> b
$
do HashMap AssemblySet ProcessId
map <- forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a. IORef a -> IO a
readIORef (MatchChain -> IORef (HashMap AssemblySet ProcessId)
matchChainMap MatchChain
chain)
AssemblySet
set <- forall a. Transact a -> Event AssemblySet
transactAssemblySet Transact a
t
forall (m :: * -> *) a. Monad m => a -> m a
return (HashMap AssemblySet ProcessId
map, AssemblySet
set)
case forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
HM.lookup AssemblySet
set HashMap AssemblySet ProcessId
map of
Just ProcessId
pid ->
forall (m :: * -> *) a. EventLift m => Event a -> m a
liftEvent forall a b. (a -> b) -> a -> b
$
do forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a. IORef a -> (a -> a) -> IO ()
modifyIORef (MatchChain -> IORef (HashMap AssemblySet ProcessId)
matchChainMap MatchChain
chain) forall a b. (a -> b) -> a -> b
$
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> HashMap k v
HM.delete AssemblySet
set
Event () -> Event ()
yieldEvent forall a b. (a -> b) -> a -> b
$
forall a. SignalSource a -> a -> Event ()
triggerSignal (MatchChain -> SignalSource AssemblySet
matchChainSource MatchChain
chain) AssemblySet
set
ProcessId -> Event ()
reactivateProcess ProcessId
pid
Maybe ProcessId
Nothing ->
do forall (m :: * -> *) a. EventLift m => Event a -> m a
liftEvent forall a b. (a -> b) -> a -> b
$
do ProcessId
pid <- forall a. Transact a -> Event ProcessId
requireTransactProcessId Transact a
t
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a. IORef a -> (a -> a) -> IO ()
modifyIORef (MatchChain -> IORef (HashMap AssemblySet ProcessId)
matchChainMap MatchChain
chain) forall a b. (a -> b) -> a -> b
$
forall k v.
(Eq k, Hashable k) =>
k -> v -> HashMap k v -> HashMap k v
HM.insert AssemblySet
set ProcessId
pid
Event () -> Event ()
yieldEvent forall a b. (a -> b) -> a -> b
$
forall a. SignalSource a -> a -> Event ()
triggerSignal (MatchChain -> SignalSource AssemblySet
matchChainSource MatchChain
chain) AssemblySet
set
Process ()
passivateProcess
transactMatching :: MatchChain -> AssemblySet -> Event Bool
transactMatching :: MatchChain -> AssemblySet -> Event Bool
transactMatching MatchChain
chain AssemblySet
set =
do HashMap AssemblySet ProcessId
map <- forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a. IORef a -> IO a
readIORef (MatchChain -> IORef (HashMap AssemblySet ProcessId)
matchChainMap MatchChain
chain)
forall (m :: * -> *) a. Monad m => a -> m a
return (forall k a. (Eq k, Hashable k) => k -> HashMap k a -> Bool
HM.member AssemblySet
set HashMap AssemblySet ProcessId
map)
transactMatchingChangedByAssemblySet_ :: MatchChain -> AssemblySet -> Signal ()
transactMatchingChangedByAssemblySet_ :: MatchChain -> AssemblySet -> Signal ()
transactMatchingChangedByAssemblySet_ MatchChain
chain AssemblySet
set =
forall a b. (a -> b) -> Signal a -> Signal b
mapSignal (forall a b. a -> b -> a
const ()) forall a b. (a -> b) -> a -> b
$
forall a. (a -> Bool) -> Signal a -> Signal a
filterSignal (forall a. Eq a => a -> a -> Bool
== AssemblySet
set) forall a b. (a -> b) -> a -> b
$
MatchChain -> Signal AssemblySet
transactMatchingChanged MatchChain
chain
transactMatchingChangedByTransact_ :: MatchChain -> Transact a -> Signal ()
transactMatchingChangedByTransact_ :: forall a. MatchChain -> Transact a -> Signal ()
transactMatchingChangedByTransact_ MatchChain
chain Transact a
t =
forall a b. (a -> b) -> Signal a -> Signal b
mapSignal (forall a b. a -> b -> a
const ()) forall a b. (a -> b) -> a -> b
$
forall a. (a -> Event Bool) -> Signal a -> Signal a
filterSignalM AssemblySet -> Event Bool
pred forall a b. (a -> b) -> a -> b
$
MatchChain -> Signal AssemblySet
transactMatchingChanged MatchChain
chain
where pred :: AssemblySet -> Event Bool
pred AssemblySet
set =
do AssemblySet
set' <- forall a. Transact a -> Event AssemblySet
transactAssemblySet Transact a
t
forall (m :: * -> *) a. Monad m => a -> m a
return (AssemblySet
set forall a. Eq a => a -> a -> Bool
== AssemblySet
set')
transactMatchingChanged :: MatchChain -> Signal AssemblySet
transactMatchingChanged :: MatchChain -> Signal AssemblySet
transactMatchingChanged MatchChain
chain =
forall a. SignalSource a -> Signal a
publishSignal (MatchChain -> SignalSource AssemblySet
matchChainSource MatchChain
chain)