module Simulation.Aivika.Trans.Arrival
(Arrival(..),
ArrivalTimer,
newArrivalTimer,
arrivalTimerProcessor,
arrivalTimerSignal,
arrivalTimerChannel,
arrivalProcessingTime,
arrivalProcessingTimeChanged,
arrivalProcessingTimeChanged_,
resetArrivalTimer) 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)
{-# INLINABLE newArrivalTimer #-}
newArrivalTimer =
do r <- newRef emptySamplingStats
s <- newSignalSource
return ArrivalTimer { arrivalProcessingTimeRef = r,
arrivalProcessingTimeChangedSource = s }
arrivalProcessingTime :: MonadDES m => ArrivalTimer m -> Event m (SamplingStats Double)
{-# INLINABLE arrivalProcessingTime #-}
arrivalProcessingTime = readRef . arrivalProcessingTimeRef
arrivalProcessingTimeChanged :: MonadDES m => ArrivalTimer m -> Signal m (SamplingStats Double)
{-# INLINABLE arrivalProcessingTimeChanged #-}
arrivalProcessingTimeChanged timer =
mapSignalM (const $ arrivalProcessingTime timer) (arrivalProcessingTimeChanged_ timer)
arrivalProcessingTimeChanged_ :: MonadDES m => ArrivalTimer m -> Signal m ()
{-# INLINABLE arrivalProcessingTimeChanged_ #-}
arrivalProcessingTimeChanged_ timer =
publishSignal (arrivalProcessingTimeChangedSource timer)
arrivalTimerProcessor :: MonadDES m => ArrivalTimer m -> Processor m (Arrival a) (Arrival a)
{-# INLINABLE arrivalTimerProcessor #-}
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)
{-# INLINABLE arrivalTimerSignal #-}
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)
{-# INLINABLE arrivalTimerChannel #-}
arrivalTimerChannel timer =
Channel $ \sa ->
return $ arrivalTimerSignal timer sa
resetArrivalTimer :: MonadDES m => ArrivalTimer m -> Event m ()
{-# INLINABLE resetArrivalTimer #-}
resetArrivalTimer timer =
do writeRef (arrivalProcessingTimeRef timer) emptySamplingStats
triggerSignal (arrivalProcessingTimeChangedSource timer) ()