module Simulation.Aivika.Arrival
(Arrival(..),
ArrivalTimer,
newArrivalTimer,
arrivalTimerProcessor,
arrivalTimerSignal,
arrivalTimerChannel,
arrivalProcessingTime,
arrivalProcessingTimeChanged,
arrivalProcessingTimeChanged_,
resetArrivalTimer) where
import Control.Monad
import Control.Monad.Trans
import Simulation.Aivika.Simulation
import Simulation.Aivika.Dynamics
import Simulation.Aivika.Event
import Simulation.Aivika.Composite
import Simulation.Aivika.Processor
import Simulation.Aivika.Stream
import Simulation.Aivika.Statistics
import Simulation.Aivika.Ref
import Simulation.Aivika.Signal
import Simulation.Aivika.Channel
import Simulation.Aivika.Internal.Arrival
data ArrivalTimer =
ArrivalTimer { arrivalProcessingTimeRef :: Ref (SamplingStats Double),
arrivalProcessingTimeChangedSource :: SignalSource () }
newArrivalTimer :: Simulation ArrivalTimer
newArrivalTimer =
do r <- newRef emptySamplingStats
s <- newSignalSource
return ArrivalTimer { arrivalProcessingTimeRef = r,
arrivalProcessingTimeChangedSource = s }
arrivalProcessingTime :: ArrivalTimer -> Event (SamplingStats Double)
arrivalProcessingTime = readRef . arrivalProcessingTimeRef
arrivalProcessingTimeChanged :: ArrivalTimer -> Signal (SamplingStats Double)
arrivalProcessingTimeChanged timer =
mapSignalM (const $ arrivalProcessingTime timer) (arrivalProcessingTimeChanged_ timer)
arrivalProcessingTimeChanged_ :: ArrivalTimer -> Signal ()
arrivalProcessingTimeChanged_ timer =
publishSignal (arrivalProcessingTimeChangedSource timer)
arrivalTimerProcessor :: ArrivalTimer -> Processor (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 :: ArrivalTimer -> Signal (Arrival a) -> Signal (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 :: ArrivalTimer -> Channel (Arrival a) (Arrival a)
arrivalTimerChannel timer =
Channel $ \sa ->
return $ arrivalTimerSignal timer sa
resetArrivalTimer :: ArrivalTimer -> Event ()
resetArrivalTimer timer =
do writeRef (arrivalProcessingTimeRef timer) emptySamplingStats
triggerSignal (arrivalProcessingTimeChangedSource timer) ()