module Simulation.Aivika.Trans.Arrival
(Arrival(..),
ArrivalTimer,
newArrivalTimer,
arrivalTimerProcessor,
arrivalTimerSignal,
arrivalTimerChannel,
arrivalProcessingTime,
arrivalProcessingTimeChanged,
arrivalProcessingTimeChanged_) where
import Control.Monad
import Control.Monad.Trans
import Simulation.Aivika.Trans.Comp
import Simulation.Aivika.Trans.Simulation
import Simulation.Aivika.Trans.Dynamics
import Simulation.Aivika.Trans.Event
import Simulation.Aivika.Trans.Composite
import Simulation.Aivika.Trans.Processor
import Simulation.Aivika.Trans.Stream
import Simulation.Aivika.Trans.Statistics
import Simulation.Aivika.Trans.Ref
import Simulation.Aivika.Trans.Signal
import Simulation.Aivika.Trans.Channel
import Simulation.Aivika.Trans.DES
import Simulation.Aivika.Arrival (Arrival(..))
data ArrivalTimer m =
ArrivalTimer { arrivalProcessingTimeRef :: Ref m (SamplingStats Double),
arrivalProcessingTimeChangedSource :: SignalSource m () }
newArrivalTimer :: MonadDES m => Simulation m (ArrivalTimer m)
newArrivalTimer =
do r <- newRef emptySamplingStats
s <- newSignalSource
return ArrivalTimer { arrivalProcessingTimeRef = r,
arrivalProcessingTimeChangedSource = s }
arrivalProcessingTime :: MonadDES m => ArrivalTimer m -> Event m (SamplingStats Double)
arrivalProcessingTime = readRef . arrivalProcessingTimeRef
arrivalProcessingTimeChanged :: MonadDES m => ArrivalTimer m -> Signal m (SamplingStats Double)
arrivalProcessingTimeChanged timer =
mapSignalM (const $ arrivalProcessingTime timer) (arrivalProcessingTimeChanged_ timer)
arrivalProcessingTimeChanged_ :: MonadDES m => ArrivalTimer m -> Signal m ()
arrivalProcessingTimeChanged_ timer =
publishSignal (arrivalProcessingTimeChangedSource timer)
arrivalTimerProcessor :: MonadDES m => ArrivalTimer m -> Processor m (Arrival a) (Arrival a)
arrivalTimerProcessor timer =
Processor $ \xs -> Cons $ loop xs where
loop xs =
do (a, xs) <- runStream xs
liftEvent $
do t <- liftDynamics time
modifyRef (arrivalProcessingTimeRef timer) $
addSamplingStats (t arrivalTime a)
triggerSignal (arrivalProcessingTimeChangedSource timer) ()
return (a, Cons $ loop xs)
arrivalTimerSignal :: MonadDES m => ArrivalTimer m -> Signal m (Arrival a) -> Signal m (Arrival a)
arrivalTimerSignal timer sa =
Signal { handleSignal = \h ->
handleSignal sa $ \a ->
do t <- liftDynamics time
modifyRef (arrivalProcessingTimeRef timer) $
addSamplingStats (t arrivalTime a)
h a
}
arrivalTimerChannel :: MonadDES m => ArrivalTimer m -> Channel m (Arrival a) (Arrival a)
arrivalTimerChannel timer =
Channel $ \sa ->
return $ arrivalTimerSignal timer sa