-- |
-- Module     : Simulation.Aivika.Trans.GPSS.Facility
-- Copyright  : Copyright (c) 2017, David Sorokin <david.sorokin@gmail.com>
-- License    : BSD3
-- Maintainer : David Sorokin <david.sorokin@gmail.com>
-- Stability  : experimental
-- Tested with: GHC 8.0.1
--
-- This module defines the GPSS Facility entity.
--
module Simulation.Aivika.Trans.GPSS.Facility
       (-- * Facility Type
        Facility,
        FacilityPreemptMode(..),
        FacilityPreemptTransfer,
        -- * Creating Facility
        newFacility,
        -- * Facility Properties
        facilityCount,
        facilityCountStats,
        facilityCaptureCount,
        facilityUtilisationCount,
        facilityUtilisationCountStats,
        facilityQueueCount,
        facilityQueueCountStats,
        facilityTotalWaitTime,
        facilityWaitTime,
        facilityTotalHoldingTime,
        facilityHoldingTime,
        facilityInterrupted,
        -- * Seizing-Releasing and Preempting-Returning Facility
        seizeFacility,
        releaseFacility,
        preemptFacility,
        returnFacility,
        -- * Statistics Reset
        resetFacility,
        -- * Signals
        facilityCountChanged,
        facilityCountChanged_,
        facilityCaptureCountChanged,
        facilityCaptureCountChanged_,
        facilityUtilisationCountChanged,
        facilityUtilisationCountChanged_,
        facilityQueueCountChanged,
        facilityQueueCountChanged_,
        facilityWaitTimeChanged,
        facilityWaitTimeChanged_,
        facilityHoldingTimeChanged,
        facilityHoldingTimeChanged_,
        facilityChanged_) where

import Data.Monoid
import Data.Maybe

import Control.Monad
import Control.Monad.Trans
import Control.Exception

import Simulation.Aivika.Trans
import Simulation.Aivika.Trans.Internal.Specs
import Simulation.Aivika.Trans.Internal.Simulation
import Simulation.Aivika.Trans.Internal.Event
import Simulation.Aivika.Trans.Internal.Cont
import Simulation.Aivika.Trans.Internal.Process
import Simulation.Aivika.Trans.QueueStrategy
import Simulation.Aivika.Trans.Statistics
import Simulation.Aivika.Trans.Signal

import Simulation.Aivika.Trans.GPSS.Transact
import Simulation.Aivika.Trans.GPSS.TransactQueueStrategy

-- | Represents a GPSS Facility entity.
data Facility m a = 
  Facility { forall (m :: * -> *) a. Facility m a -> Ref m Int
facilityCountRef :: Ref m Int,
             forall (m :: * -> *) a. Facility m a -> Ref m (TimingStats Int)
facilityCountStatsRef :: Ref m (TimingStats Int),
             forall (m :: * -> *) a. Facility m a -> SignalSource m Int
facilityCountSource :: SignalSource m Int,
             forall (m :: * -> *) a. Facility m a -> Ref m Int
facilityCaptureCountRef :: Ref m Int,
             forall (m :: * -> *) a. Facility m a -> SignalSource m Int
facilityCaptureCountSource :: SignalSource m Int,
             forall (m :: * -> *) a. Facility m a -> Ref m Int
facilityUtilisationCountRef :: Ref m Int,
             forall (m :: * -> *) a. Facility m a -> Ref m (TimingStats Int)
facilityUtilisationCountStatsRef :: Ref m (TimingStats Int),
             forall (m :: * -> *) a. Facility m a -> SignalSource m Int
facilityUtilisationCountSource :: SignalSource m Int,
             forall (m :: * -> *) a. Facility m a -> Ref m Int
facilityQueueCountRef :: Ref m Int,
             forall (m :: * -> *) a. Facility m a -> Ref m (TimingStats Int)
facilityQueueCountStatsRef :: Ref m (TimingStats Int),
             forall (m :: * -> *) a. Facility m a -> SignalSource m Int
facilityQueueCountSource :: SignalSource m Int,
             forall (m :: * -> *) a. Facility m a -> Ref m Double
facilityTotalWaitTimeRef :: Ref m Double,
             forall (m :: * -> *) a.
Facility m a -> Ref m (SamplingStats Double)
facilityWaitTimeRef :: Ref m (SamplingStats Double),
             forall (m :: * -> *) a. Facility m a -> SignalSource m ()
facilityWaitTimeSource :: SignalSource m (),
             forall (m :: * -> *) a. Facility m a -> Ref m Double
facilityTotalHoldingTimeRef :: Ref m Double,
             forall (m :: * -> *) a.
Facility m a -> Ref m (SamplingStats Double)
facilityHoldingTimeRef :: Ref m (SamplingStats Double),
             forall (m :: * -> *) a. Facility m a -> SignalSource m ()
facilityHoldingTimeSource :: SignalSource m (),
             forall (m :: * -> *) a.
Facility m a -> Ref m (Maybe (FacilityOwnerItem m a))
facilityOwnerRef :: Ref m (Maybe (FacilityOwnerItem m a)),
             forall (m :: * -> *) a.
Facility m a
-> StrategyQueue
     m (TransactQueueStrategy FCFS) (FacilityDelayedItem m a)
facilityDelayChain :: StrategyQueue m (TransactQueueStrategy FCFS) (FacilityDelayedItem m a),
             forall (m :: * -> *) a.
Facility m a
-> StrategyQueue
     m (TransactQueueStrategy LCFS) (FacilityInterruptedItem m a)
facilityInterruptChain :: StrategyQueue m (TransactQueueStrategy LCFS) (FacilityInterruptedItem m a),
             forall (m :: * -> *) a.
Facility m a
-> StrategyQueue
     m (TransactQueueStrategy FCFS) (FacilityPendingItem m a)
facilityPendingChain :: StrategyQueue m (TransactQueueStrategy FCFS) (FacilityPendingItem m a) }

-- | Identifies a transact item that owns the facility.
data FacilityOwnerItem m a =
  FacilityOwnerItem { forall (m :: * -> *) a. FacilityOwnerItem m a -> Transact m a
ownerItemTransact :: Transact m a,
                      forall (m :: * -> *) a. FacilityOwnerItem m a -> Double
ownerItemTime :: Double,
                      forall (m :: * -> *) a. FacilityOwnerItem m a -> Bool
ownerItemPreempting :: Bool,
                      forall (m :: * -> *) a. FacilityOwnerItem m a -> Bool
ownerItemInterrupting :: Bool,
                      forall (m :: * -> *) a. FacilityOwnerItem m a -> Double
ownerItemAccHoldingTime :: Double }

-- | Idenitifies a transact item that was delayed.
data FacilityDelayedItem m a =
  FacilityDelayedItem { forall (m :: * -> *) a. FacilityDelayedItem m a -> Transact m a
delayedItemTransact :: Transact m a,
                        forall (m :: * -> *) a. FacilityDelayedItem m a -> Double
delayedItemTime :: Double,
                        forall (m :: * -> *) a. FacilityDelayedItem m a -> Bool
delayedItemPreempting :: Bool,
                        forall (m :: * -> *) a. FacilityDelayedItem m a -> Bool
delayedItemInterrupting :: Bool,
                        forall (m :: * -> *) a. FacilityDelayedItem m a -> FrozenCont m ()
delayedItemCont :: FrozenCont m () }

-- | Idenitifies a transact item that was interrupted.
data FacilityInterruptedItem m a =
  FacilityInterruptedItem { forall (m :: * -> *) a. FacilityInterruptedItem m a -> Transact m a
interruptedItemTransact :: Transact m a,
                            forall (m :: * -> *) a. FacilityInterruptedItem m a -> Double
interruptedItemTime :: Double,
                            forall (m :: * -> *) a. FacilityInterruptedItem m a -> Bool
interruptedItemPreempting :: Bool,
                            forall (m :: * -> *) a. FacilityInterruptedItem m a -> Bool
interruptedItemInterrupting :: Bool,
                            forall (m :: * -> *) a. FacilityInterruptedItem m a -> Maybe Double
interruptedItemRemainingTime :: Maybe Double,
                            forall (m :: * -> *) a.
FacilityInterruptedItem m a -> Maybe (FacilityPreemptTransfer m a)
interruptedItemTransfer :: Maybe (FacilityPreemptTransfer m a),
                            forall (m :: * -> *) a. FacilityInterruptedItem m a -> Double
interruptedItemAccHoldingTime :: Double }

-- | Idenitifies a transact item which is pending.
data FacilityPendingItem m a =
  FacilityPendingItem { forall (m :: * -> *) a. FacilityPendingItem m a -> Transact m a
pendingItemTransact :: Transact m a,
                        forall (m :: * -> *) a. FacilityPendingItem m a -> Double
pendingItemTime :: Double,
                        forall (m :: * -> *) a. FacilityPendingItem m a -> Bool
pendingItemPreempting :: Bool,
                        forall (m :: * -> *) a. FacilityPendingItem m a -> Bool
pendingItemInterrupting :: Bool,
                        forall (m :: * -> *) a. FacilityPendingItem m a -> FrozenCont m ()
pendingItemCont :: FrozenCont m () }

instance MonadDES m => Eq (Facility m a) where
  Facility m a
x == :: Facility m a -> Facility m a -> Bool
== Facility m a
y = forall (m :: * -> *) a. Facility m a -> Ref m Int
facilityCountRef Facility m a
x forall a. Eq a => a -> a -> Bool
== forall (m :: * -> *) a. Facility m a -> Ref m Int
facilityCountRef Facility m a
y  -- unique references

-- | The facility preemption mode.
data FacilityPreemptMode m a =
  FacilityPreemptMode { forall (m :: * -> *) a. FacilityPreemptMode m a -> Bool
facilityPriorityMode :: Bool,
                        -- ^ the Priority mode; otherwise, the Interrupt mode
                        forall (m :: * -> *) a.
FacilityPreemptMode m a -> Maybe (FacilityPreemptTransfer m a)
facilityTransfer :: Maybe (FacilityPreemptTransfer m a),
                        -- ^ where to transfer the preempted transact,
                        -- passing in the remaining time from the process holding
                        -- computation such as the ADVANCE block
                        forall (m :: * -> *) a. FacilityPreemptMode m a -> Bool
facilityRemoveMode :: Bool
                        -- ^ the Remove mode
                      }

-- | Proceed with the computation by the specified preempted transact
-- and remaining time from the process holding computation such as the ADVANCE block.
type FacilityPreemptTransfer m a = Transact m a -> Maybe Double -> Process m ()

-- | The default facility preemption mode.
defaultFacilityPreemptMode :: FacilityPreemptMode m a
defaultFacilityPreemptMode :: forall (m :: * -> *) a. FacilityPreemptMode m a
defaultFacilityPreemptMode =
  FacilityPreemptMode { facilityPriorityMode :: Bool
facilityPriorityMode = Bool
False,
                        facilityTransfer :: Maybe (FacilityPreemptTransfer m a)
facilityTransfer = forall a. Maybe a
Nothing,
                        facilityRemoveMode :: Bool
facilityRemoveMode = Bool
False
                      }

-- | Create a new facility.
newFacility :: MonadDES m => Event m (Facility m a)
{-# INLINABLE newFacility #-}
newFacility :: forall (m :: * -> *) a. MonadDES m => Event m (Facility m a)
newFacility =
  forall (m :: * -> *) a. (Point m -> m a) -> Event m a
Event forall a b. (a -> b) -> a -> b
$ \Point m
p ->
  do let r :: Run m
r = forall (m :: * -> *). Point m -> Run m
pointRun Point m
p
         t :: Double
t = forall (m :: * -> *). Point m -> Double
pointTime Point m
p
     Ref m Int
countRef <- forall (m :: * -> *) a. Run m -> Simulation m a -> m a
invokeSimulation Run m
r forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => a -> Simulation m (Ref m a)
newRef Int
1
     Ref m (TimingStats Int)
countStatsRef <- forall (m :: * -> *) a. Run m -> Simulation m a -> m a
invokeSimulation Run m
r forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => a -> Simulation m (Ref m a)
newRef forall a b. (a -> b) -> a -> b
$ forall a. TimingData a => Double -> a -> TimingStats a
returnTimingStats Double
t Int
1
     SignalSource m Int
countSource <- forall (m :: * -> *) a. Run m -> Simulation m a -> m a
invokeSimulation Run m
r forall (m :: * -> *) a.
MonadDES m =>
Simulation m (SignalSource m a)
newSignalSource
     Ref m Int
captureCountRef <- forall (m :: * -> *) a. Run m -> Simulation m a -> m a
invokeSimulation Run m
r forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => a -> Simulation m (Ref m a)
newRef Int
0
     SignalSource m Int
captureCountSource <- forall (m :: * -> *) a. Run m -> Simulation m a -> m a
invokeSimulation Run m
r forall (m :: * -> *) a.
MonadDES m =>
Simulation m (SignalSource m a)
newSignalSource
     Ref m Int
utilCountRef <- forall (m :: * -> *) a. Run m -> Simulation m a -> m a
invokeSimulation Run m
r forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => a -> Simulation m (Ref m a)
newRef Int
0
     Ref m (TimingStats Int)
utilCountStatsRef <- forall (m :: * -> *) a. Run m -> Simulation m a -> m a
invokeSimulation Run m
r forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => a -> Simulation m (Ref m a)
newRef forall a b. (a -> b) -> a -> b
$ forall a. TimingData a => Double -> a -> TimingStats a
returnTimingStats Double
t Int
0
     SignalSource m Int
utilCountSource <- forall (m :: * -> *) a. Run m -> Simulation m a -> m a
invokeSimulation Run m
r forall (m :: * -> *) a.
MonadDES m =>
Simulation m (SignalSource m a)
newSignalSource
     Ref m Int
queueCountRef <- forall (m :: * -> *) a. Run m -> Simulation m a -> m a
invokeSimulation Run m
r forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => a -> Simulation m (Ref m a)
newRef Int
0
     Ref m (TimingStats Int)
queueCountStatsRef <- forall (m :: * -> *) a. Run m -> Simulation m a -> m a
invokeSimulation Run m
r forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => a -> Simulation m (Ref m a)
newRef forall a b. (a -> b) -> a -> b
$ forall a. TimingData a => Double -> a -> TimingStats a
returnTimingStats Double
t Int
0
     SignalSource m Int
queueCountSource <- forall (m :: * -> *) a. Run m -> Simulation m a -> m a
invokeSimulation Run m
r forall (m :: * -> *) a.
MonadDES m =>
Simulation m (SignalSource m a)
newSignalSource
     Ref m Double
totalWaitTimeRef <- forall (m :: * -> *) a. Run m -> Simulation m a -> m a
invokeSimulation Run m
r forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => a -> Simulation m (Ref m a)
newRef Double
0
     Ref m (SamplingStats Double)
waitTimeRef <- forall (m :: * -> *) a. Run m -> Simulation m a -> m a
invokeSimulation Run m
r forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => a -> Simulation m (Ref m a)
newRef forall a. SamplingData a => SamplingStats a
emptySamplingStats
     SignalSource m ()
waitTimeSource <- forall (m :: * -> *) a. Run m -> Simulation m a -> m a
invokeSimulation Run m
r forall (m :: * -> *) a.
MonadDES m =>
Simulation m (SignalSource m a)
newSignalSource
     Ref m Double
totalHoldingTimeRef <- forall (m :: * -> *) a. Run m -> Simulation m a -> m a
invokeSimulation Run m
r forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => a -> Simulation m (Ref m a)
newRef Double
0
     Ref m (SamplingStats Double)
holdingTimeRef <- forall (m :: * -> *) a. Run m -> Simulation m a -> m a
invokeSimulation Run m
r forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => a -> Simulation m (Ref m a)
newRef forall a. SamplingData a => SamplingStats a
emptySamplingStats
     SignalSource m ()
holdingTimeSource <- forall (m :: * -> *) a. Run m -> Simulation m a -> m a
invokeSimulation Run m
r forall (m :: * -> *) a.
MonadDES m =>
Simulation m (SignalSource m a)
newSignalSource
     Ref m (Maybe (FacilityOwnerItem m a))
ownerRef <- forall (m :: * -> *) a. Run m -> Simulation m a -> m a
invokeSimulation Run m
r forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => a -> Simulation m (Ref m a)
newRef forall a. Maybe a
Nothing
     StrategyQueue
  m (TransactQueueStrategy FCFS) (FacilityDelayedItem m a)
delayChain <- forall (m :: * -> *) a. Run m -> Simulation m a -> m a
invokeSimulation Run m
r forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) s a.
QueueStrategy m s =>
s -> Simulation m (StrategyQueue m s a)
newStrategyQueue (forall s. s -> TransactQueueStrategy s
TransactQueueStrategy FCFS
FCFS)
     StrategyQueue
  m (TransactQueueStrategy LCFS) (FacilityInterruptedItem m a)
interruptChain <- forall (m :: * -> *) a. Run m -> Simulation m a -> m a
invokeSimulation Run m
r forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) s a.
QueueStrategy m s =>
s -> Simulation m (StrategyQueue m s a)
newStrategyQueue (forall s. s -> TransactQueueStrategy s
TransactQueueStrategy LCFS
LCFS)
     StrategyQueue
  m (TransactQueueStrategy FCFS) (FacilityPendingItem m a)
pendingChain <- forall (m :: * -> *) a. Run m -> Simulation m a -> m a
invokeSimulation Run m
r forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) s a.
QueueStrategy m s =>
s -> Simulation m (StrategyQueue m s a)
newStrategyQueue (forall s. s -> TransactQueueStrategy s
TransactQueueStrategy FCFS
FCFS)
     forall (m :: * -> *) a. Monad m => a -> m a
return Facility { facilityCountRef :: Ref m Int
facilityCountRef = Ref m Int
countRef,
                       facilityCountStatsRef :: Ref m (TimingStats Int)
facilityCountStatsRef = Ref m (TimingStats Int)
countStatsRef,
                       facilityCountSource :: SignalSource m Int
facilityCountSource = SignalSource m Int
countSource,
                       facilityCaptureCountRef :: Ref m Int
facilityCaptureCountRef = Ref m Int
captureCountRef,
                       facilityCaptureCountSource :: SignalSource m Int
facilityCaptureCountSource = SignalSource m Int
captureCountSource,
                       facilityUtilisationCountRef :: Ref m Int
facilityUtilisationCountRef = Ref m Int
utilCountRef,
                       facilityUtilisationCountStatsRef :: Ref m (TimingStats Int)
facilityUtilisationCountStatsRef = Ref m (TimingStats Int)
utilCountStatsRef,
                       facilityUtilisationCountSource :: SignalSource m Int
facilityUtilisationCountSource = SignalSource m Int
utilCountSource,
                       facilityQueueCountRef :: Ref m Int
facilityQueueCountRef = Ref m Int
queueCountRef,
                       facilityQueueCountStatsRef :: Ref m (TimingStats Int)
facilityQueueCountStatsRef = Ref m (TimingStats Int)
queueCountStatsRef,
                       facilityQueueCountSource :: SignalSource m Int
facilityQueueCountSource = SignalSource m Int
queueCountSource,
                       facilityTotalWaitTimeRef :: Ref m Double
facilityTotalWaitTimeRef = Ref m Double
totalWaitTimeRef,
                       facilityWaitTimeRef :: Ref m (SamplingStats Double)
facilityWaitTimeRef = Ref m (SamplingStats Double)
waitTimeRef,
                       facilityWaitTimeSource :: SignalSource m ()
facilityWaitTimeSource = SignalSource m ()
waitTimeSource,
                       facilityTotalHoldingTimeRef :: Ref m Double
facilityTotalHoldingTimeRef = Ref m Double
totalHoldingTimeRef,
                       facilityHoldingTimeRef :: Ref m (SamplingStats Double)
facilityHoldingTimeRef = Ref m (SamplingStats Double)
holdingTimeRef,
                       facilityHoldingTimeSource :: SignalSource m ()
facilityHoldingTimeSource = SignalSource m ()
holdingTimeSource,
                       facilityOwnerRef :: Ref m (Maybe (FacilityOwnerItem m a))
facilityOwnerRef = Ref m (Maybe (FacilityOwnerItem m a))
ownerRef,
                       facilityDelayChain :: StrategyQueue
  m (TransactQueueStrategy FCFS) (FacilityDelayedItem m a)
facilityDelayChain = StrategyQueue
  m (TransactQueueStrategy FCFS) (FacilityDelayedItem m a)
delayChain,
                       facilityInterruptChain :: StrategyQueue
  m (TransactQueueStrategy LCFS) (FacilityInterruptedItem m a)
facilityInterruptChain = StrategyQueue
  m (TransactQueueStrategy LCFS) (FacilityInterruptedItem m a)
interruptChain,
                       facilityPendingChain :: StrategyQueue
  m (TransactQueueStrategy FCFS) (FacilityPendingItem m a)
facilityPendingChain = StrategyQueue
  m (TransactQueueStrategy FCFS) (FacilityPendingItem m a)
pendingChain }

-- | Return the current available count of the facility.
facilityCount :: MonadDES m => Facility m a -> Event m Int
{-# INLINABLE facilityCount #-}
facilityCount :: forall (m :: * -> *) a. MonadDES m => Facility m a -> Event m Int
facilityCount Facility m a
r =
  forall (m :: * -> *) a. (Point m -> m a) -> Event m a
Event forall a b. (a -> b) -> a -> b
$ \Point m
p -> forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => Ref m a -> Event m a
readRef (forall (m :: * -> *) a. Facility m a -> Ref m Int
facilityCountRef Facility m a
r)

-- | Return the statistics for the available count of the facility.
facilityCountStats :: MonadDES m => Facility m a -> Event m (TimingStats Int)
{-# INLINABLE facilityCountStats #-}
facilityCountStats :: forall (m :: * -> *) a.
MonadDES m =>
Facility m a -> Event m (TimingStats Int)
facilityCountStats Facility m a
r =
  forall (m :: * -> *) a. (Point m -> m a) -> Event m a
Event forall a b. (a -> b) -> a -> b
$ \Point m
p -> forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => Ref m a -> Event m a
readRef (forall (m :: * -> *) a. Facility m a -> Ref m (TimingStats Int)
facilityCountStatsRef Facility m a
r)

-- | Signal triggered when the 'facilityCount' property changes.
facilityCountChanged :: MonadDES m => Facility m a -> Signal m Int
{-# INLINABLE facilityCountChanged #-}
facilityCountChanged :: forall (m :: * -> *) a. MonadDES m => Facility m a -> Signal m Int
facilityCountChanged Facility m a
r =
  forall (m :: * -> *) a. SignalSource m a -> Signal m a
publishSignal forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Facility m a -> SignalSource m Int
facilityCountSource Facility m a
r

-- | Signal triggered when the 'facilityCount' property changes.
facilityCountChanged_ :: MonadDES m => Facility m a -> Signal m ()
{-# INLINABLE facilityCountChanged_ #-}
facilityCountChanged_ :: forall (m :: * -> *) a. MonadDES m => Facility m a -> Signal m ()
facilityCountChanged_ Facility m a
r =
  forall (m :: * -> *) a b.
MonadDES m =>
(a -> b) -> Signal m a -> Signal m b
mapSignal (forall a b. a -> b -> a
const ()) forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => Facility m a -> Signal m Int
facilityCountChanged Facility m a
r

-- | Return the current capture count of the facility.
facilityCaptureCount :: MonadDES m => Facility m a -> Event m Int
{-# INLINABLE facilityCaptureCount #-}
facilityCaptureCount :: forall (m :: * -> *) a. MonadDES m => Facility m a -> Event m Int
facilityCaptureCount Facility m a
r =
  forall (m :: * -> *) a. (Point m -> m a) -> Event m a
Event forall a b. (a -> b) -> a -> b
$ \Point m
p -> forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => Ref m a -> Event m a
readRef (forall (m :: * -> *) a. Facility m a -> Ref m Int
facilityCaptureCountRef Facility m a
r)

-- | Signal triggered when the 'facilityCaptureCount' property changes.
facilityCaptureCountChanged :: MonadDES m => Facility m a -> Signal m Int
{-# INLINABLE facilityCaptureCountChanged #-}
facilityCaptureCountChanged :: forall (m :: * -> *) a. MonadDES m => Facility m a -> Signal m Int
facilityCaptureCountChanged Facility m a
r =
  forall (m :: * -> *) a. SignalSource m a -> Signal m a
publishSignal forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Facility m a -> SignalSource m Int
facilityCaptureCountSource Facility m a
r

-- | Signal triggered when the 'facilityCaptureCount' property changes.
facilityCaptureCountChanged_ :: MonadDES m => Facility m a -> Signal m ()
{-# INLINABLE facilityCaptureCountChanged_ #-}
facilityCaptureCountChanged_ :: forall (m :: * -> *) a. MonadDES m => Facility m a -> Signal m ()
facilityCaptureCountChanged_ Facility m a
r =
  forall (m :: * -> *) a b.
MonadDES m =>
(a -> b) -> Signal m a -> Signal m b
mapSignal (forall a b. a -> b -> a
const ()) forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => Facility m a -> Signal m Int
facilityCaptureCountChanged Facility m a
r

-- | Return the current utilisation count of the facility.
facilityUtilisationCount :: MonadDES m => Facility m a -> Event m Int
{-# INLINABLE facilityUtilisationCount #-}
facilityUtilisationCount :: forall (m :: * -> *) a. MonadDES m => Facility m a -> Event m Int
facilityUtilisationCount Facility m a
r =
  forall (m :: * -> *) a. (Point m -> m a) -> Event m a
Event forall a b. (a -> b) -> a -> b
$ \Point m
p -> forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => Ref m a -> Event m a
readRef (forall (m :: * -> *) a. Facility m a -> Ref m Int
facilityUtilisationCountRef Facility m a
r)

-- | Return the statistics for the utilisation count of the facility.
facilityUtilisationCountStats :: MonadDES m => Facility m a -> Event m (TimingStats Int)
{-# INLINABLE facilityUtilisationCountStats #-}
facilityUtilisationCountStats :: forall (m :: * -> *) a.
MonadDES m =>
Facility m a -> Event m (TimingStats Int)
facilityUtilisationCountStats Facility m a
r =
  forall (m :: * -> *) a. (Point m -> m a) -> Event m a
Event forall a b. (a -> b) -> a -> b
$ \Point m
p -> forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => Ref m a -> Event m a
readRef (forall (m :: * -> *) a. Facility m a -> Ref m (TimingStats Int)
facilityUtilisationCountStatsRef Facility m a
r)

-- | Signal triggered when the 'facilityUtilisationCount' property changes.
facilityUtilisationCountChanged :: MonadDES m => Facility m a -> Signal m Int
{-# INLINABLE facilityUtilisationCountChanged #-}
facilityUtilisationCountChanged :: forall (m :: * -> *) a. MonadDES m => Facility m a -> Signal m Int
facilityUtilisationCountChanged Facility m a
r =
  forall (m :: * -> *) a. SignalSource m a -> Signal m a
publishSignal forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Facility m a -> SignalSource m Int
facilityUtilisationCountSource Facility m a
r

-- | Signal triggered when the 'facilityUtilisationCount' property changes.
facilityUtilisationCountChanged_ :: MonadDES m => Facility m a -> Signal m ()
{-# INLINABLE facilityUtilisationCountChanged_ #-}
facilityUtilisationCountChanged_ :: forall (m :: * -> *) a. MonadDES m => Facility m a -> Signal m ()
facilityUtilisationCountChanged_ Facility m a
r =
  forall (m :: * -> *) a b.
MonadDES m =>
(a -> b) -> Signal m a -> Signal m b
mapSignal (forall a b. a -> b -> a
const ()) forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => Facility m a -> Signal m Int
facilityUtilisationCountChanged Facility m a
r

-- | Return the current queue length of the facility.
facilityQueueCount :: MonadDES m => Facility m a -> Event m Int
{-# INLINABLE facilityQueueCount #-}
facilityQueueCount :: forall (m :: * -> *) a. MonadDES m => Facility m a -> Event m Int
facilityQueueCount Facility m a
r =
  forall (m :: * -> *) a. (Point m -> m a) -> Event m a
Event forall a b. (a -> b) -> a -> b
$ \Point m
p -> forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => Ref m a -> Event m a
readRef (forall (m :: * -> *) a. Facility m a -> Ref m Int
facilityQueueCountRef Facility m a
r)

-- | Return the statistics for the queue length of the facility.
facilityQueueCountStats :: MonadDES m => Facility m a -> Event m (TimingStats Int)
{-# INLINABLE facilityQueueCountStats #-}
facilityQueueCountStats :: forall (m :: * -> *) a.
MonadDES m =>
Facility m a -> Event m (TimingStats Int)
facilityQueueCountStats Facility m a
r =
  forall (m :: * -> *) a. (Point m -> m a) -> Event m a
Event forall a b. (a -> b) -> a -> b
$ \Point m
p -> forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => Ref m a -> Event m a
readRef (forall (m :: * -> *) a. Facility m a -> Ref m (TimingStats Int)
facilityQueueCountStatsRef Facility m a
r)

-- | Signal triggered when the 'facilityQueueCount' property changes.
facilityQueueCountChanged :: MonadDES m => Facility m a -> Signal m Int
{-# INLINABLE facilityQueueCountChanged #-}
facilityQueueCountChanged :: forall (m :: * -> *) a. MonadDES m => Facility m a -> Signal m Int
facilityQueueCountChanged Facility m a
r =
  forall (m :: * -> *) a. SignalSource m a -> Signal m a
publishSignal forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Facility m a -> SignalSource m Int
facilityQueueCountSource Facility m a
r

-- | Signal triggered when the 'facilityQueueCount' property changes.
facilityQueueCountChanged_ :: MonadDES m => Facility m a -> Signal m ()
{-# INLINABLE facilityQueueCountChanged_ #-}
facilityQueueCountChanged_ :: forall (m :: * -> *) a. MonadDES m => Facility m a -> Signal m ()
facilityQueueCountChanged_ Facility m a
r =
  forall (m :: * -> *) a b.
MonadDES m =>
(a -> b) -> Signal m a -> Signal m b
mapSignal (forall a b. a -> b -> a
const ()) forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => Facility m a -> Signal m Int
facilityQueueCountChanged Facility m a
r

-- | Return the total wait time of the facility.
facilityTotalWaitTime :: MonadDES m => Facility m a -> Event m Double
{-# INLINABLE facilityTotalWaitTime #-}
facilityTotalWaitTime :: forall (m :: * -> *) a.
MonadDES m =>
Facility m a -> Event m Double
facilityTotalWaitTime Facility m a
r =
  forall (m :: * -> *) a. (Point m -> m a) -> Event m a
Event forall a b. (a -> b) -> a -> b
$ \Point m
p -> forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => Ref m a -> Event m a
readRef (forall (m :: * -> *) a. Facility m a -> Ref m Double
facilityTotalWaitTimeRef Facility m a
r)

-- | Return the statistics for the wait time of the facility.
facilityWaitTime :: MonadDES m => Facility m a -> Event m (SamplingStats Double)
{-# INLINABLE facilityWaitTime #-}
facilityWaitTime :: forall (m :: * -> *) a.
MonadDES m =>
Facility m a -> Event m (SamplingStats Double)
facilityWaitTime Facility m a
r =
  forall (m :: * -> *) a. (Point m -> m a) -> Event m a
Event forall a b. (a -> b) -> a -> b
$ \Point m
p -> forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => Ref m a -> Event m a
readRef (forall (m :: * -> *) a.
Facility m a -> Ref m (SamplingStats Double)
facilityWaitTimeRef Facility m a
r)

-- | Signal triggered when the 'facilityTotalWaitTime' and 'facilityWaitTime' properties change.
facilityWaitTimeChanged :: MonadDES m => Facility m a -> Signal m (SamplingStats Double)
{-# INLINABLE facilityWaitTimeChanged #-}
facilityWaitTimeChanged :: forall (m :: * -> *) a.
MonadDES m =>
Facility m a -> Signal m (SamplingStats Double)
facilityWaitTimeChanged Facility m a
r =
  forall (m :: * -> *) a b.
MonadDES m =>
(a -> Event m b) -> Signal m a -> Signal m b
mapSignalM (\() -> forall (m :: * -> *) a.
MonadDES m =>
Facility m a -> Event m (SamplingStats Double)
facilityWaitTime Facility m a
r) forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => Facility m a -> Signal m ()
facilityWaitTimeChanged_ Facility m a
r

-- | Signal triggered when the 'facilityTotalWaitTime' and 'facilityWaitTime' properties change.
facilityWaitTimeChanged_ :: MonadDES m => Facility m a -> Signal m ()
{-# INLINABLE facilityWaitTimeChanged_ #-}
facilityWaitTimeChanged_ :: forall (m :: * -> *) a. MonadDES m => Facility m a -> Signal m ()
facilityWaitTimeChanged_ Facility m a
r =
  forall (m :: * -> *) a. SignalSource m a -> Signal m a
publishSignal forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Facility m a -> SignalSource m ()
facilityWaitTimeSource Facility m a
r

-- | Return the total holding time of the facility.
facilityTotalHoldingTime :: MonadDES m => Facility m a -> Event m Double
{-# INLINABLE facilityTotalHoldingTime #-}
facilityTotalHoldingTime :: forall (m :: * -> *) a.
MonadDES m =>
Facility m a -> Event m Double
facilityTotalHoldingTime Facility m a
r =
  forall (m :: * -> *) a. (Point m -> m a) -> Event m a
Event forall a b. (a -> b) -> a -> b
$ \Point m
p -> forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => Ref m a -> Event m a
readRef (forall (m :: * -> *) a. Facility m a -> Ref m Double
facilityTotalHoldingTimeRef Facility m a
r)

-- | Return the statistics for the holding time of the facility.
facilityHoldingTime :: MonadDES m => Facility m a -> Event m (SamplingStats Double)
{-# INLINABLE facilityHoldingTime #-}
facilityHoldingTime :: forall (m :: * -> *) a.
MonadDES m =>
Facility m a -> Event m (SamplingStats Double)
facilityHoldingTime Facility m a
r =
  forall (m :: * -> *) a. (Point m -> m a) -> Event m a
Event forall a b. (a -> b) -> a -> b
$ \Point m
p -> forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => Ref m a -> Event m a
readRef (forall (m :: * -> *) a.
Facility m a -> Ref m (SamplingStats Double)
facilityHoldingTimeRef Facility m a
r)

-- | Signal triggered when the 'facilityTotalHoldingTime' and 'facilityHoldingTime' properties change.
facilityHoldingTimeChanged :: MonadDES m => Facility m a -> Signal m (SamplingStats Double)
{-# INLINABLE facilityHoldingTimeChanged #-}
facilityHoldingTimeChanged :: forall (m :: * -> *) a.
MonadDES m =>
Facility m a -> Signal m (SamplingStats Double)
facilityHoldingTimeChanged Facility m a
r =
  forall (m :: * -> *) a b.
MonadDES m =>
(a -> Event m b) -> Signal m a -> Signal m b
mapSignalM (\() -> forall (m :: * -> *) a.
MonadDES m =>
Facility m a -> Event m (SamplingStats Double)
facilityHoldingTime Facility m a
r) forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => Facility m a -> Signal m ()
facilityHoldingTimeChanged_ Facility m a
r

-- | Signal triggered when the 'facilityTotalHoldingTime' and 'facilityHoldingTime' properties change.
facilityHoldingTimeChanged_ :: MonadDES m => Facility m a -> Signal m ()
{-# INLINABLE facilityHoldingTimeChanged_ #-}
facilityHoldingTimeChanged_ :: forall (m :: * -> *) a. MonadDES m => Facility m a -> Signal m ()
facilityHoldingTimeChanged_ Facility m a
r =
  forall (m :: * -> *) a. SignalSource m a -> Signal m a
publishSignal forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Facility m a -> SignalSource m ()
facilityHoldingTimeSource Facility m a
r

-- | Whether the facility is currently interrupted.
facilityInterrupted :: MonadDES m => Facility m a -> Event m Bool
{-# INLINABLE facilityInterrupted #-}
facilityInterrupted :: forall (m :: * -> *) a. MonadDES m => Facility m a -> Event m Bool
facilityInterrupted Facility m a
r =
  forall (m :: * -> *) a. (Point m -> m a) -> Event m a
Event forall a b. (a -> b) -> a -> b
$ \Point m
p ->
  do Maybe (FacilityOwnerItem m a)
x <- forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => Ref m a -> Event m a
readRef (forall (m :: * -> *) a.
Facility m a -> Ref m (Maybe (FacilityOwnerItem m a))
facilityOwnerRef Facility m a
r)
     case Maybe (FacilityOwnerItem m a)
x of
       Maybe (FacilityOwnerItem m a)
Nothing -> forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
       Just FacilityOwnerItem m a
a  -> forall (m :: * -> *) a. Monad m => a -> m a
return (forall (m :: * -> *) a. FacilityOwnerItem m a -> Bool
ownerItemPreempting FacilityOwnerItem m a
a)

-- | Seize the facility.
seizeFacility :: MonadDES m
                 => Facility m a
                 -- ^ the requested facility
                 -> Transact m a
                 -- ^ the transact that tries to seize the facility
                 -> Process m ()
{-# INLINABLE seizeFacility #-}
seizeFacility :: forall (m :: * -> *) a.
MonadDES m =>
Facility m a -> Transact m a -> Process m ()
seizeFacility Facility m a
r Transact m a
transact =
  forall (m :: * -> *) a. (ProcessId m -> Cont m a) -> Process m a
Process forall a b. (a -> b) -> a -> b
$ \ProcessId m
pid ->
  forall (m :: * -> *) a. (ContParams m a -> Event m ()) -> Cont m a
Cont forall a b. (a -> b) -> a -> b
$ \ContParams m ()
c ->
  forall (m :: * -> *) a. (Point m -> m a) -> Event m a
Event forall a b. (a -> b) -> a -> b
$ \Point m
p ->
  do let t :: Double
t = forall (m :: * -> *). Point m -> Double
pointTime Point m
p
     Bool
f <- do Bool
f1 <- forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) s a.
QueueStrategy m s =>
StrategyQueue m s a -> Event m Bool
strategyQueueNull (forall (m :: * -> *) a.
Facility m a
-> StrategyQueue
     m (TransactQueueStrategy FCFS) (FacilityDelayedItem m a)
facilityDelayChain Facility m a
r)
             if Bool
f1
               then do Bool
f2 <- forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) s a.
QueueStrategy m s =>
StrategyQueue m s a -> Event m Bool
strategyQueueNull (forall (m :: * -> *) a.
Facility m a
-> StrategyQueue
     m (TransactQueueStrategy LCFS) (FacilityInterruptedItem m a)
facilityInterruptChain Facility m a
r)
                       if Bool
f2
                         then forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) s a.
QueueStrategy m s =>
StrategyQueue m s a -> Event m Bool
strategyQueueNull (forall (m :: * -> *) a.
Facility m a
-> StrategyQueue
     m (TransactQueueStrategy FCFS) (FacilityPendingItem m a)
facilityPendingChain Facility m a
r)
                         else forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
               else forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
     if Bool
f
       then forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$
            forall (m :: * -> *) a. ContParams m a -> Cont m a -> Event m ()
invokeCont ContParams m ()
c forall a b. (a -> b) -> a -> b
$
            forall (m :: * -> *) a. ProcessId m -> Process m a -> Cont m a
invokeProcess ProcessId m
pid forall a b. (a -> b) -> a -> b
$
            forall (m :: * -> *) a.
MonadDES m =>
Facility m a -> Transact m a -> Process m ()
seizeFacility' Facility m a
r Transact m a
transact
       else do FrozenCont m ()
c <- forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$
                    forall (m :: * -> *) a.
MonadDES m =>
ContParams m a -> a -> Event m () -> Event m (FrozenCont m a)
freezeContReentering ContParams m ()
c () forall a b. (a -> b) -> a -> b
$
                    forall (m :: * -> *) a. ContParams m a -> Cont m a -> Event m ()
invokeCont ContParams m ()
c forall a b. (a -> b) -> a -> b
$
                    forall (m :: * -> *) a. ProcessId m -> Process m a -> Cont m a
invokeProcess ProcessId m
pid forall a b. (a -> b) -> a -> b
$
                    forall (m :: * -> *) a.
MonadDES m =>
Facility m a -> Transact m a -> Process m ()
seizeFacility Facility m a
r Transact m a
transact
               forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$
                 forall (m :: * -> *) s p a.
PriorityQueueStrategy m s p =>
StrategyQueue m s a -> p -> a -> Event m ()
strategyEnqueueWithPriority
                 (forall (m :: * -> *) a.
Facility m a
-> StrategyQueue
     m (TransactQueueStrategy FCFS) (FacilityDelayedItem m a)
facilityDelayChain Facility m a
r)
                 (forall (m :: * -> *) a. Transact m a -> Int
transactPriority Transact m a
transact)
                 (forall (m :: * -> *) a.
Transact m a
-> Double
-> Bool
-> Bool
-> FrozenCont m ()
-> FacilityDelayedItem m a
FacilityDelayedItem Transact m a
transact Double
t Bool
False Bool
False FrozenCont m ()
c)
               forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
MonadDES m =>
Facility m a -> Int -> Event m ()
updateFacilityQueueCount Facility m a
r Int
1

-- | Seize the facility.
seizeFacility' :: MonadDES m
                  => Facility m a
                  -- ^ the requested facility
                  -> Transact m a
                  -- ^ the transact that tries to seize the facility
                  -> Process m ()
{-# INLINABLE seizeFacility' #-}
seizeFacility' :: forall (m :: * -> *) a.
MonadDES m =>
Facility m a -> Transact m a -> Process m ()
seizeFacility' Facility m a
r Transact m a
transact =
  forall (m :: * -> *) a. (ProcessId m -> Cont m a) -> Process m a
Process forall a b. (a -> b) -> a -> b
$ \ProcessId m
pid ->
  forall (m :: * -> *) a. (ContParams m a -> Event m ()) -> Cont m a
Cont forall a b. (a -> b) -> a -> b
$ \ContParams m ()
c ->
  forall (m :: * -> *) a. (Point m -> m a) -> Event m a
Event forall a b. (a -> b) -> a -> b
$ \Point m
p ->
  do let t :: Double
t = forall (m :: * -> *). Point m -> Double
pointTime Point m
p
     Maybe (FacilityOwnerItem m a)
a <- forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => Ref m a -> Event m a
readRef (forall (m :: * -> *) a.
Facility m a -> Ref m (Maybe (FacilityOwnerItem m a))
facilityOwnerRef Facility m a
r)
     case Maybe (FacilityOwnerItem m a)
a of
       Maybe (FacilityOwnerItem m a)
Nothing ->
         do forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => Ref m a -> a -> Event m ()
writeRef (forall (m :: * -> *) a.
Facility m a -> Ref m (Maybe (FacilityOwnerItem m a))
facilityOwnerRef Facility m a
r) forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a
Just (forall (m :: * -> *) a.
Transact m a
-> Double -> Bool -> Bool -> Double -> FacilityOwnerItem m a
FacilityOwnerItem Transact m a
transact Double
t Bool
False Bool
False Double
0)
            forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
MonadDES m =>
Facility m a -> Double -> Event m ()
updateFacilityWaitTime Facility m a
r Double
0
            forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
MonadDES m =>
Facility m a -> Int -> Event m ()
updateFacilityCount Facility m a
r (-Int
1)
            forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
MonadDES m =>
Facility m a -> Int -> Event m ()
updateFacilityCaptureCount Facility m a
r Int
1
            forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
MonadDES m =>
Facility m a -> Int -> Event m ()
updateFacilityUtilisationCount Facility m a
r Int
1
            forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
MonadDES m =>
ContParams m a -> a -> Event m ()
resumeCont ContParams m ()
c ()
       Just FacilityOwnerItem m a
owner ->
         do FrozenCont m ()
c <- forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$
                 forall (m :: * -> *) a.
MonadDES m =>
ContParams m a -> a -> Event m () -> Event m (FrozenCont m a)
freezeContReentering ContParams m ()
c () forall a b. (a -> b) -> a -> b
$
                 forall (m :: * -> *) a. ContParams m a -> Cont m a -> Event m ()
invokeCont ContParams m ()
c forall a b. (a -> b) -> a -> b
$
                 forall (m :: * -> *) a. ProcessId m -> Process m a -> Cont m a
invokeProcess ProcessId m
pid forall a b. (a -> b) -> a -> b
$
                 forall (m :: * -> *) a.
MonadDES m =>
Facility m a -> Transact m a -> Process m ()
seizeFacility Facility m a
r Transact m a
transact
            forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$
              forall (m :: * -> *) s p a.
PriorityQueueStrategy m s p =>
StrategyQueue m s a -> p -> a -> Event m ()
strategyEnqueueWithPriority
              (forall (m :: * -> *) a.
Facility m a
-> StrategyQueue
     m (TransactQueueStrategy FCFS) (FacilityDelayedItem m a)
facilityDelayChain Facility m a
r)
              (forall (m :: * -> *) a. Transact m a -> Int
transactPriority Transact m a
transact)
              (forall (m :: * -> *) a.
Transact m a
-> Double
-> Bool
-> Bool
-> FrozenCont m ()
-> FacilityDelayedItem m a
FacilityDelayedItem Transact m a
transact Double
t Bool
False Bool
False FrozenCont m ()
c)
            forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
MonadDES m =>
Facility m a -> Int -> Event m ()
updateFacilityQueueCount Facility m a
r Int
1

-- | Preempt the facility.
preemptFacility :: MonadDES m
                   => Facility m a
                   -- ^ the requested facility
                   -> Transact m a
                   -- ^ the transact that tries to preempt the facility
                   -> FacilityPreemptMode m a
                   -- ^ the Preempt mode
                   -> Process m ()
{-# INLINABLE preemptFacility #-}
preemptFacility :: forall (m :: * -> *) a.
MonadDES m =>
Facility m a
-> Transact m a -> FacilityPreemptMode m a -> Process m ()
preemptFacility Facility m a
r Transact m a
transact FacilityPreemptMode m a
mode =
  forall (m :: * -> *) a. (ProcessId m -> Cont m a) -> Process m a
Process forall a b. (a -> b) -> a -> b
$ \ProcessId m
pid ->
  forall (m :: * -> *) a. (ContParams m a -> Event m ()) -> Cont m a
Cont forall a b. (a -> b) -> a -> b
$ \ContParams m ()
c ->
  forall (m :: * -> *) a. (Point m -> m a) -> Event m a
Event forall a b. (a -> b) -> a -> b
$ \Point m
p ->
  do let t :: Double
t = forall (m :: * -> *). Point m -> Double
pointTime Point m
p
     Maybe (FacilityOwnerItem m a)
a <- forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => Ref m a -> Event m a
readRef (forall (m :: * -> *) a.
Facility m a -> Ref m (Maybe (FacilityOwnerItem m a))
facilityOwnerRef Facility m a
r)
     case Maybe (FacilityOwnerItem m a)
a of
       Maybe (FacilityOwnerItem m a)
Nothing ->
         do forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => Ref m a -> a -> Event m ()
writeRef (forall (m :: * -> *) a.
Facility m a -> Ref m (Maybe (FacilityOwnerItem m a))
facilityOwnerRef Facility m a
r) forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a
Just (forall (m :: * -> *) a.
Transact m a
-> Double -> Bool -> Bool -> Double -> FacilityOwnerItem m a
FacilityOwnerItem Transact m a
transact Double
t Bool
True Bool
False Double
0)
            forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
MonadDES m =>
Facility m a -> Double -> Event m ()
updateFacilityWaitTime Facility m a
r Double
0
            forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
MonadDES m =>
Facility m a -> Int -> Event m ()
updateFacilityCount Facility m a
r (-Int
1)
            forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
MonadDES m =>
Facility m a -> Int -> Event m ()
updateFacilityCaptureCount Facility m a
r Int
1
            forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
MonadDES m =>
Facility m a -> Int -> Event m ()
updateFacilityUtilisationCount Facility m a
r Int
1
            forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
MonadDES m =>
ContParams m a -> a -> Event m ()
resumeCont ContParams m ()
c ()
       Just owner :: FacilityOwnerItem m a
owner@(FacilityOwnerItem Transact m a
transact0 Double
t0 Bool
preempting0 Bool
interrupting0 Double
acc0)
         | (Bool -> Bool
not forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. FacilityPreemptMode m a -> Bool
facilityPriorityMode FacilityPreemptMode m a
mode) Bool -> Bool -> Bool
&& Bool
interrupting0 ->
         do FrozenCont m ()
c <- forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$
                 forall (m :: * -> *) a.
MonadDES m =>
ContParams m a -> a -> Event m () -> Event m (FrozenCont m a)
freezeContReentering ContParams m ()
c () forall a b. (a -> b) -> a -> b
$
                 forall (m :: * -> *) a. ContParams m a -> Cont m a -> Event m ()
invokeCont ContParams m ()
c forall a b. (a -> b) -> a -> b
$
                 forall (m :: * -> *) a. ProcessId m -> Process m a -> Cont m a
invokeProcess ProcessId m
pid forall a b. (a -> b) -> a -> b
$
                 forall (m :: * -> *) a.
MonadDES m =>
Facility m a
-> Transact m a -> FacilityPreemptMode m a -> Process m ()
preemptFacility Facility m a
r Transact m a
transact FacilityPreemptMode m a
mode
            forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$
              forall (m :: * -> *) s p a.
PriorityQueueStrategy m s p =>
StrategyQueue m s a -> p -> a -> Event m ()
strategyEnqueueWithPriority
              (forall (m :: * -> *) a.
Facility m a
-> StrategyQueue
     m (TransactQueueStrategy FCFS) (FacilityPendingItem m a)
facilityPendingChain Facility m a
r)
              (forall (m :: * -> *) a. Transact m a -> Int
transactPriority Transact m a
transact)
              (forall (m :: * -> *) a.
Transact m a
-> Double
-> Bool
-> Bool
-> FrozenCont m ()
-> FacilityPendingItem m a
FacilityPendingItem Transact m a
transact Double
t Bool
True Bool
True FrozenCont m ()
c)
            forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
MonadDES m =>
Facility m a -> Int -> Event m ()
updateFacilityQueueCount Facility m a
r Int
1
       Just owner :: FacilityOwnerItem m a
owner@(FacilityOwnerItem Transact m a
transact0 Double
t0 Bool
preempting0 Bool
interrupting0 Double
acc0)
         | forall (m :: * -> *) a. FacilityPreemptMode m a -> Bool
facilityPriorityMode FacilityPreemptMode m a
mode Bool -> Bool -> Bool
&& (forall (m :: * -> *) a. Transact m a -> Int
transactPriority Transact m a
transact forall a. Ord a => a -> a -> Bool
<= forall (m :: * -> *) a. Transact m a -> Int
transactPriority Transact m a
transact0) ->
         do FrozenCont m ()
c <- forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$
                 forall (m :: * -> *) a.
MonadDES m =>
ContParams m a -> a -> Event m () -> Event m (FrozenCont m a)
freezeContReentering ContParams m ()
c () forall a b. (a -> b) -> a -> b
$
                 forall (m :: * -> *) a. ContParams m a -> Cont m a -> Event m ()
invokeCont ContParams m ()
c forall a b. (a -> b) -> a -> b
$
                 forall (m :: * -> *) a. ProcessId m -> Process m a -> Cont m a
invokeProcess ProcessId m
pid forall a b. (a -> b) -> a -> b
$
                 forall (m :: * -> *) a.
MonadDES m =>
Facility m a
-> Transact m a -> FacilityPreemptMode m a -> Process m ()
preemptFacility Facility m a
r Transact m a
transact FacilityPreemptMode m a
mode
            forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$
              forall (m :: * -> *) s p a.
PriorityQueueStrategy m s p =>
StrategyQueue m s a -> p -> a -> Event m ()
strategyEnqueueWithPriority
              (forall (m :: * -> *) a.
Facility m a
-> StrategyQueue
     m (TransactQueueStrategy FCFS) (FacilityDelayedItem m a)
facilityDelayChain Facility m a
r)
              (forall (m :: * -> *) a. Transact m a -> Int
transactPriority Transact m a
transact)
              (forall (m :: * -> *) a.
Transact m a
-> Double
-> Bool
-> Bool
-> FrozenCont m ()
-> FacilityDelayedItem m a
FacilityDelayedItem Transact m a
transact Double
t Bool
True Bool
True FrozenCont m ()
c)
            forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
MonadDES m =>
Facility m a -> Int -> Event m ()
updateFacilityQueueCount Facility m a
r Int
1
       Just owner :: FacilityOwnerItem m a
owner@(FacilityOwnerItem Transact m a
transact0 Double
t0 Bool
preempting0 Bool
interrupting0 Double
acc0)
         | (Bool -> Bool
not forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. FacilityPreemptMode m a -> Bool
facilityRemoveMode FacilityPreemptMode m a
mode) ->
         do forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => Ref m a -> a -> Event m ()
writeRef (forall (m :: * -> *) a.
Facility m a -> Ref m (Maybe (FacilityOwnerItem m a))
facilityOwnerRef Facility m a
r) forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a
Just (forall (m :: * -> *) a.
Transact m a
-> Double -> Bool -> Bool -> Double -> FacilityOwnerItem m a
FacilityOwnerItem Transact m a
transact Double
t Bool
True Bool
True Double
0)
            ProcessId m
pid0 <- forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
MonadDES m =>
Transact m a -> Event m (ProcessId m)
requireTransactProcessId Transact m a
transact0
            Maybe Double
t2   <- forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *).
MonadDES m =>
ProcessId m -> Event m (Maybe Double)
processInterruptionTime ProcessId m
pid0
            let dt0 :: Maybe Double
dt0 = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\Double
x -> Double
x forall a. Num a => a -> a -> a
- Double
t) Maybe Double
t2
            forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$
              forall (m :: * -> *) s p a.
PriorityQueueStrategy m s p =>
StrategyQueue m s a -> p -> a -> Event m ()
strategyEnqueueWithPriority
              (forall (m :: * -> *) a.
Facility m a
-> StrategyQueue
     m (TransactQueueStrategy LCFS) (FacilityInterruptedItem m a)
facilityInterruptChain Facility m a
r)
              (forall (m :: * -> *) a. Transact m a -> Int
transactPriority Transact m a
transact0)
              (forall (m :: * -> *) a.
Transact m a
-> Double
-> Bool
-> Bool
-> Maybe Double
-> Maybe (FacilityPreemptTransfer m a)
-> Double
-> FacilityInterruptedItem m a
FacilityInterruptedItem Transact m a
transact0 Double
t Bool
preempting0 Bool
interrupting0 Maybe Double
dt0 (forall (m :: * -> *) a.
FacilityPreemptMode m a -> Maybe (FacilityPreemptTransfer m a)
facilityTransfer FacilityPreemptMode m a
mode) (Double
acc0 forall a. Num a => a -> a -> a
+ (Double
t forall a. Num a => a -> a -> a
- Double
t0)))
            forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
MonadDES m =>
Facility m a -> Int -> Event m ()
updateFacilityQueueCount Facility m a
r Int
1
            forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
MonadDES m =>
Facility m a -> Double -> Event m ()
updateFacilityWaitTime Facility m a
r Double
0
            forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
MonadDES m =>
Facility m a -> Int -> Event m ()
updateFacilityCaptureCount Facility m a
r Int
1
            forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => Transact m a -> Event m ()
transactPreemptionBegin Transact m a
transact0
            forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
MonadDES m =>
ContParams m a -> a -> Event m ()
resumeCont ContParams m ()
c ()
       Just owner :: FacilityOwnerItem m a
owner@(FacilityOwnerItem Transact m a
transact0 Double
t0 Bool
preempting0 Bool
interruptin0 Double
acc0)
         | forall (m :: * -> *) a. FacilityPreemptMode m a -> Bool
facilityRemoveMode FacilityPreemptMode m a
mode ->
         do forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => Ref m a -> a -> Event m ()
writeRef (forall (m :: * -> *) a.
Facility m a -> Ref m (Maybe (FacilityOwnerItem m a))
facilityOwnerRef Facility m a
r) forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a
Just (forall (m :: * -> *) a.
Transact m a
-> Double -> Bool -> Bool -> Double -> FacilityOwnerItem m a
FacilityOwnerItem Transact m a
transact Double
t Bool
True Bool
True Double
0)
            ProcessId m
pid0 <- forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
MonadDES m =>
Transact m a -> Event m (ProcessId m)
requireTransactProcessId Transact m a
transact0
            Maybe Double
t2   <- forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *).
MonadDES m =>
ProcessId m -> Event m (Maybe Double)
processInterruptionTime ProcessId m
pid0
            let dt0 :: Maybe Double
dt0 = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\Double
x -> Double
x forall a. Num a => a -> a -> a
- Double
t) Maybe Double
t2
            forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
MonadDES m =>
Facility m a -> Double -> Event m ()
updateFacilityWaitTime Facility m a
r Double
0
            forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
MonadDES m =>
Facility m a -> Int -> Event m ()
updateFacilityCaptureCount Facility m a
r Int
1
            forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
MonadDES m =>
Facility m a -> Double -> Event m ()
updateFacilityHoldingTime Facility m a
r (Double
acc0 forall a. Num a => a -> a -> a
+ (Double
t forall a. Num a => a -> a -> a
- Double
t0))
            case forall (m :: * -> *) a.
FacilityPreemptMode m a -> Maybe (FacilityPreemptTransfer m a)
facilityTransfer FacilityPreemptMode m a
mode of
              Maybe (FacilityPreemptTransfer m a)
Nothing ->
                forall (m :: * -> *) e a.
(MonadException m, Exception e) =>
e -> m a
throwComp forall a b. (a -> b) -> a -> b
$
                String -> SimulationRetry
SimulationRetry
                String
"The transfer destination is not specified for the removed preempted transact: preemptFacility"
              Just FacilityPreemptTransfer m a
transfer ->
                forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
MonadDES m =>
Transact m a -> Process m () -> Event m ()
transferTransact Transact m a
transact0 (FacilityPreemptTransfer m a
transfer Transact m a
transact0 Maybe Double
dt0)
            forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
MonadDES m =>
ContParams m a -> a -> Event m ()
resumeCont ContParams m ()
c ()

-- | Return the facility by the active transact.
returnFacility :: MonadDES m
                  => Facility m a
                  -- ^ the facility to return
                  -> Transact m a
                  -- ^ the active transact that tries to return the facility
                  -> Process m ()
{-# INLINABLE returnFacility #-}
returnFacility :: forall (m :: * -> *) a.
MonadDES m =>
Facility m a -> Transact m a -> Process m ()
returnFacility Facility m a
r Transact m a
transact = forall (m :: * -> *) a.
MonadDES m =>
Facility m a -> Transact m a -> Bool -> Process m ()
releaseFacility' Facility m a
r Transact m a
transact Bool
True 

-- | Release the facility by the active transact.
releaseFacility :: MonadDES m
                   => Facility m a
                   -- ^ the facility to release
                   -> Transact m a
                   -- ^ the active transact that tries to release the facility
                   -> Process m ()
{-# INLINABLE releaseFacility #-}
releaseFacility :: forall (m :: * -> *) a.
MonadDES m =>
Facility m a -> Transact m a -> Process m ()
releaseFacility Facility m a
r Transact m a
transact = forall (m :: * -> *) a.
MonadDES m =>
Facility m a -> Transact m a -> Bool -> Process m ()
releaseFacility' Facility m a
r Transact m a
transact Bool
False 

-- | Release the facility by the active transact.
releaseFacility' :: MonadDES m
                    => Facility m a
                    -- ^ the facility to release
                    -> Transact m a
                    -- ^ the active transact that tries to release the facility
                    -> Bool
                    -- ^ whether the transact is preempting
                    -> Process m ()
{-# INLINABLE releaseFacility' #-}
releaseFacility' :: forall (m :: * -> *) a.
MonadDES m =>
Facility m a -> Transact m a -> Bool -> Process m ()
releaseFacility' Facility m a
r Transact m a
transact Bool
preempting = 
  forall (m :: * -> *) a. (ProcessId m -> Cont m a) -> Process m a
Process forall a b. (a -> b) -> a -> b
$ \ProcessId m
pid ->
  forall (m :: * -> *) a. (ContParams m a -> Event m ()) -> Cont m a
Cont forall a b. (a -> b) -> a -> b
$ \ContParams m ()
c ->
  forall (m :: * -> *) a. (Point m -> m a) -> Event m a
Event forall a b. (a -> b) -> a -> b
$ \Point m
p ->
  do let t :: Double
t = forall (m :: * -> *). Point m -> Double
pointTime Point m
p
     Maybe (FacilityOwnerItem m a)
a <- forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => Ref m a -> Event m a
readRef (forall (m :: * -> *) a.
Facility m a -> Ref m (Maybe (FacilityOwnerItem m a))
facilityOwnerRef Facility m a
r)
     case Maybe (FacilityOwnerItem m a)
a of
       Maybe (FacilityOwnerItem m a)
Nothing ->
         forall (m :: * -> *) e a.
(MonadException m, Exception e) =>
e -> m a
throwComp forall a b. (a -> b) -> a -> b
$
         String -> SimulationRetry
SimulationRetry
         String
"There is no owner of the facility: releaseFacility'"
       Just owner :: FacilityOwnerItem m a
owner@(FacilityOwnerItem Transact m a
transact0 Double
t0 Bool
preempting0 Bool
interrupting0 Double
acc0) | Transact m a
transact0 forall a. Eq a => a -> a -> Bool
== Transact m a
transact Bool -> Bool -> Bool
&& Bool
preempting0 forall a. Eq a => a -> a -> Bool
/= Bool
preempting ->
         forall (m :: * -> *) e a.
(MonadException m, Exception e) =>
e -> m a
throwComp forall a b. (a -> b) -> a -> b
$
         String -> SimulationRetry
SimulationRetry
         String
"The mismatch use of releaseFacility and returnFacility: releaseFacility'"
       Just owner :: FacilityOwnerItem m a
owner@(FacilityOwnerItem Transact m a
transact0 Double
t0 Bool
preempting0 Bool
interrupting0 Double
acc0) | Transact m a
transact0 forall a. Eq a => a -> a -> Bool
== Transact m a
transact ->
         do forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => Ref m a -> a -> Event m ()
writeRef (forall (m :: * -> *) a.
Facility m a -> Ref m (Maybe (FacilityOwnerItem m a))
facilityOwnerRef Facility m a
r) forall a. Maybe a
Nothing
            forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
MonadDES m =>
Facility m a -> Int -> Event m ()
updateFacilityUtilisationCount Facility m a
r (-Int
1)
            forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
MonadDES m =>
Facility m a -> Double -> Event m ()
updateFacilityHoldingTime Facility m a
r (Double
acc0 forall a. Num a => a -> a -> a
+ (Double
t forall a. Num a => a -> a -> a
- Double
t0))
            forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
MonadDES m =>
Facility m a -> Int -> Event m ()
updateFacilityCount Facility m a
r Int
1
            forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *).
EventQueueing m =>
Double -> Event m () -> Event m ()
enqueueEvent Double
t forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => Facility m a -> Event m ()
tryCaptureFacility Facility m a
r
            forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
MonadDES m =>
ContParams m a -> a -> Event m ()
resumeCont ContParams m ()
c ()
       Just FacilityOwnerItem m a
owner ->
         forall (m :: * -> *) e a.
(MonadException m, Exception e) =>
e -> m a
throwComp forall a b. (a -> b) -> a -> b
$
         String -> SimulationRetry
SimulationRetry
         String
"The facility has another owner: releaseFacility'"

-- | Try to capture the facility.
tryCaptureFacility :: MonadDES m => Facility m a -> Event m ()
{-# INLINABLE tryCaptureFacility #-}
tryCaptureFacility :: forall (m :: * -> *) a. MonadDES m => Facility m a -> Event m ()
tryCaptureFacility Facility m a
r =
  forall (m :: * -> *) a. (Point m -> m a) -> Event m a
Event forall a b. (a -> b) -> a -> b
$ \Point m
p ->
  do let t :: Double
t = forall (m :: * -> *). Point m -> Double
pointTime Point m
p
     Maybe (FacilityOwnerItem m a)
a <- forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => Ref m a -> Event m a
readRef (forall (m :: * -> *) a.
Facility m a -> Ref m (Maybe (FacilityOwnerItem m a))
facilityOwnerRef Facility m a
r)
     case Maybe (FacilityOwnerItem m a)
a of
       Maybe (FacilityOwnerItem m a)
Nothing ->
         forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => Facility m a -> Event m ()
captureFacility Facility m a
r
       Just FacilityOwnerItem m a
owner -> forall (m :: * -> *) a. Monad m => a -> m a
return ()

-- | Find another owner of the facility.
captureFacility :: MonadDES m => Facility m a -> Event m ()
{-# INLINABLE captureFacility #-}
captureFacility :: forall (m :: * -> *) a. MonadDES m => Facility m a -> Event m ()
captureFacility Facility m a
r =
  forall (m :: * -> *) a. (Point m -> m a) -> Event m a
Event forall a b. (a -> b) -> a -> b
$ \Point m
p ->
  do let t :: Double
t = forall (m :: * -> *). Point m -> Double
pointTime Point m
p
     Bool
f <- forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) s a.
QueueStrategy m s =>
StrategyQueue m s a -> Event m Bool
strategyQueueNull (forall (m :: * -> *) a.
Facility m a
-> StrategyQueue
     m (TransactQueueStrategy FCFS) (FacilityPendingItem m a)
facilityPendingChain Facility m a
r)
     if Bool -> Bool
not Bool
f
       then do FacilityPendingItem Transact m a
transact Double
t0 Bool
preempting Bool
interrupting FrozenCont m ()
c0 <- forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) s a.
DequeueStrategy m s =>
StrategyQueue m s a -> Event m a
strategyDequeue (forall (m :: * -> *) a.
Facility m a
-> StrategyQueue
     m (TransactQueueStrategy FCFS) (FacilityPendingItem m a)
facilityPendingChain Facility m a
r)
               forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
MonadDES m =>
Facility m a -> Int -> Event m ()
updateFacilityQueueCount Facility m a
r (-Int
1)
               Maybe (ContParams m ())
c <- forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
FrozenCont m a -> Event m (Maybe (ContParams m a))
unfreezeCont FrozenCont m ()
c0
               case Maybe (ContParams m ())
c of
                 Maybe (ContParams m ())
Nothing ->
                   forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => Facility m a -> Event m ()
captureFacility Facility m a
r
                 Just ContParams m ()
c ->
                   do forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => Ref m a -> a -> Event m ()
writeRef (forall (m :: * -> *) a.
Facility m a -> Ref m (Maybe (FacilityOwnerItem m a))
facilityOwnerRef Facility m a
r) forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a
Just (forall (m :: * -> *) a.
Transact m a
-> Double -> Bool -> Bool -> Double -> FacilityOwnerItem m a
FacilityOwnerItem Transact m a
transact Double
t Bool
preempting Bool
interrupting Double
0)
                      forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
MonadDES m =>
Facility m a -> Double -> Event m ()
updateFacilityWaitTime Facility m a
r (Double
t forall a. Num a => a -> a -> a
- Double
t0)
                      forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
MonadDES m =>
Facility m a -> Int -> Event m ()
updateFacilityUtilisationCount Facility m a
r Int
1
                      forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
MonadDES m =>
Facility m a -> Int -> Event m ()
updateFacilityCaptureCount Facility m a
r Int
1
                      forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
MonadDES m =>
Facility m a -> Int -> Event m ()
updateFacilityCount Facility m a
r (-Int
1)
                      forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *).
EventQueueing m =>
Double -> Event m () -> Event m ()
enqueueEvent Double
t forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
MonadDES m =>
ContParams m a -> a -> Event m ()
reenterCont ContParams m ()
c ()
       else do Bool
f <- forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) s a.
QueueStrategy m s =>
StrategyQueue m s a -> Event m Bool
strategyQueueNull (forall (m :: * -> *) a.
Facility m a
-> StrategyQueue
     m (TransactQueueStrategy LCFS) (FacilityInterruptedItem m a)
facilityInterruptChain Facility m a
r)
               if Bool -> Bool
not Bool
f
                  then do FacilityInterruptedItem Transact m a
transact Double
t0 Bool
preempting Bool
interrupting Maybe Double
dt0 Maybe (FacilityPreemptTransfer m a)
transfer0 Double
acc0 <- forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) s a.
DequeueStrategy m s =>
StrategyQueue m s a -> Event m a
strategyDequeue (forall (m :: * -> *) a.
Facility m a
-> StrategyQueue
     m (TransactQueueStrategy LCFS) (FacilityInterruptedItem m a)
facilityInterruptChain Facility m a
r)
                          ProcessId m
pid <- forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
MonadDES m =>
Transact m a -> Event m (ProcessId m)
requireTransactProcessId Transact m a
transact
                          forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
MonadDES m =>
Facility m a -> Int -> Event m ()
updateFacilityQueueCount Facility m a
r (-Int
1)
                          Bool
f <- forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *). MonadDES m => ProcessId m -> Event m Bool
processCancelled ProcessId m
pid
                          case Bool
f of
                            Bool
True ->
                              forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => Facility m a -> Event m ()
captureFacility Facility m a
r
                            Bool
False ->
                              do forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => Ref m a -> a -> Event m ()
writeRef (forall (m :: * -> *) a.
Facility m a -> Ref m (Maybe (FacilityOwnerItem m a))
facilityOwnerRef Facility m a
r) forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a
Just (forall (m :: * -> *) a.
Transact m a
-> Double -> Bool -> Bool -> Double -> FacilityOwnerItem m a
FacilityOwnerItem Transact m a
transact Double
t Bool
preempting Bool
interrupting Double
acc0)
                                 forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
MonadDES m =>
Facility m a -> Double -> Event m ()
updateFacilityWaitTime Facility m a
r (Double
t forall a. Num a => a -> a -> a
- Double
t0)
                                 forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
MonadDES m =>
Facility m a -> Int -> Event m ()
updateFacilityUtilisationCount Facility m a
r Int
1
                                 forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
MonadDES m =>
Facility m a -> Int -> Event m ()
updateFacilityCount Facility m a
r (-Int
1)
                                 case Maybe (FacilityPreemptTransfer m a)
transfer0 of
                                   Maybe (FacilityPreemptTransfer m a)
Nothing -> forall (m :: * -> *) a. Monad m => a -> m a
return ()
                                   Just FacilityPreemptTransfer m a
transfer ->
                                     forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
MonadDES m =>
Transact m a -> Process m () -> Event m ()
transferTransact Transact m a
transact (FacilityPreemptTransfer m a
transfer Transact m a
transact Maybe Double
dt0)
                                 forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => Transact m a -> Event m ()
transactPreemptionEnd Transact m a
transact
                 else do Bool
f <- forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) s a.
QueueStrategy m s =>
StrategyQueue m s a -> Event m Bool
strategyQueueNull (forall (m :: * -> *) a.
Facility m a
-> StrategyQueue
     m (TransactQueueStrategy FCFS) (FacilityDelayedItem m a)
facilityDelayChain Facility m a
r)
                         if Bool -> Bool
not Bool
f
                           then do FacilityDelayedItem Transact m a
transact Double
t0 Bool
preempting Bool
interrupting FrozenCont m ()
c0 <- forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) s a.
DequeueStrategy m s =>
StrategyQueue m s a -> Event m a
strategyDequeue (forall (m :: * -> *) a.
Facility m a
-> StrategyQueue
     m (TransactQueueStrategy FCFS) (FacilityDelayedItem m a)
facilityDelayChain Facility m a
r)
                                   forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
MonadDES m =>
Facility m a -> Int -> Event m ()
updateFacilityQueueCount Facility m a
r (-Int
1)
                                   Maybe (ContParams m ())
c <- forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
FrozenCont m a -> Event m (Maybe (ContParams m a))
unfreezeCont FrozenCont m ()
c0
                                   case Maybe (ContParams m ())
c of
                                     Maybe (ContParams m ())
Nothing ->
                                       forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => Facility m a -> Event m ()
captureFacility Facility m a
r
                                     Just ContParams m ()
c ->
                                       do forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => Ref m a -> a -> Event m ()
writeRef (forall (m :: * -> *) a.
Facility m a -> Ref m (Maybe (FacilityOwnerItem m a))
facilityOwnerRef Facility m a
r) forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a
Just (forall (m :: * -> *) a.
Transact m a
-> Double -> Bool -> Bool -> Double -> FacilityOwnerItem m a
FacilityOwnerItem Transact m a
transact Double
t Bool
preempting Bool
interrupting Double
0)
                                          forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
MonadDES m =>
Facility m a -> Double -> Event m ()
updateFacilityWaitTime Facility m a
r (Double
t forall a. Num a => a -> a -> a
- Double
t0)
                                          forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
MonadDES m =>
Facility m a -> Int -> Event m ()
updateFacilityUtilisationCount Facility m a
r Int
1
                                          forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
MonadDES m =>
Facility m a -> Int -> Event m ()
updateFacilityCaptureCount Facility m a
r Int
1
                                          forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
MonadDES m =>
Facility m a -> Int -> Event m ()
updateFacilityCount Facility m a
r (-Int
1)
                                          forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *).
EventQueueing m =>
Double -> Event m () -> Event m ()
enqueueEvent Double
t forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
MonadDES m =>
ContParams m a -> a -> Event m ()
reenterCont ContParams m ()
c ()
                           else forall (m :: * -> *) a. Monad m => a -> m a
return ()

-- | Signal triggered when one of the facility counters changes.
facilityChanged_ :: MonadDES m => Facility m a -> Signal m ()
{-# INLINABLE facilityChanged_ #-}
facilityChanged_ :: forall (m :: * -> *) a. MonadDES m => Facility m a -> Signal m ()
facilityChanged_ Facility m a
r =
  forall (m :: * -> *) a. MonadDES m => Facility m a -> Signal m ()
facilityCountChanged_ Facility m a
r forall a. Semigroup a => a -> a -> a
<>
  forall (m :: * -> *) a. MonadDES m => Facility m a -> Signal m ()
facilityCaptureCountChanged_ Facility m a
r forall a. Semigroup a => a -> a -> a
<>
  forall (m :: * -> *) a. MonadDES m => Facility m a -> Signal m ()
facilityUtilisationCountChanged_ Facility m a
r forall a. Semigroup a => a -> a -> a
<>
  forall (m :: * -> *) a. MonadDES m => Facility m a -> Signal m ()
facilityQueueCountChanged_ Facility m a
r

-- | Update the facility count and its statistics.
updateFacilityCount :: MonadDES m => Facility m a -> Int -> Event m ()
{-# INLINABLE updateFacilityCount #-}
updateFacilityCount :: forall (m :: * -> *) a.
MonadDES m =>
Facility m a -> Int -> Event m ()
updateFacilityCount Facility m a
r Int
delta =
  forall (m :: * -> *) a. (Point m -> m a) -> Event m a
Event forall a b. (a -> b) -> a -> b
$ \Point m
p ->
  do Int
a <- forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => Ref m a -> Event m a
readRef (forall (m :: * -> *) a. Facility m a -> Ref m Int
facilityCountRef Facility m a
r)
     let a' :: Int
a' = Int
a forall a. Num a => a -> a -> a
+ Int
delta
     forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$
       forall (m :: * -> *) a. MonadDES m => Ref m a -> a -> Event m ()
writeRef (forall (m :: * -> *) a. Facility m a -> Ref m Int
facilityCountRef Facility m a
r) Int
a'
     forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$
       forall (m :: * -> *) a.
MonadDES m =>
Ref m a -> (a -> a) -> Event m ()
modifyRef (forall (m :: * -> *) a. Facility m a -> Ref m (TimingStats Int)
facilityCountStatsRef Facility m a
r) forall a b. (a -> b) -> a -> b
$
       forall a.
TimingData a =>
Double -> a -> TimingStats a -> TimingStats a
addTimingStats (forall (m :: * -> *). Point m -> Double
pointTime Point m
p) Int
a'
     forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$
       forall (m :: * -> *) a. SignalSource m a -> a -> Event m ()
triggerSignal (forall (m :: * -> *) a. Facility m a -> SignalSource m Int
facilityCountSource Facility m a
r) Int
a'

-- | Update the facility capture count.
updateFacilityCaptureCount :: MonadDES m => Facility m a -> Int -> Event m ()
{-# INLINABLE updateFacilityCaptureCount #-}
updateFacilityCaptureCount :: forall (m :: * -> *) a.
MonadDES m =>
Facility m a -> Int -> Event m ()
updateFacilityCaptureCount Facility m a
r Int
delta =
  forall (m :: * -> *) a. (Point m -> m a) -> Event m a
Event forall a b. (a -> b) -> a -> b
$ \Point m
p ->
  do Int
a <- forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => Ref m a -> Event m a
readRef (forall (m :: * -> *) a. Facility m a -> Ref m Int
facilityCaptureCountRef Facility m a
r)
     let a' :: Int
a' = Int
a forall a. Num a => a -> a -> a
+ Int
delta
     forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$
       forall (m :: * -> *) a. MonadDES m => Ref m a -> a -> Event m ()
writeRef (forall (m :: * -> *) a. Facility m a -> Ref m Int
facilityCaptureCountRef Facility m a
r) Int
a'
     forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$
       forall (m :: * -> *) a. SignalSource m a -> a -> Event m ()
triggerSignal (forall (m :: * -> *) a. Facility m a -> SignalSource m Int
facilityCaptureCountSource Facility m a
r) Int
a'

-- | Update the facility queue length and its statistics.
updateFacilityQueueCount :: MonadDES m => Facility m a -> Int -> Event m ()
{-# INLINABLE updateFacilityQueueCount #-}
updateFacilityQueueCount :: forall (m :: * -> *) a.
MonadDES m =>
Facility m a -> Int -> Event m ()
updateFacilityQueueCount Facility m a
r Int
delta =
  forall (m :: * -> *) a. (Point m -> m a) -> Event m a
Event forall a b. (a -> b) -> a -> b
$ \Point m
p ->
  do Int
a <- forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => Ref m a -> Event m a
readRef (forall (m :: * -> *) a. Facility m a -> Ref m Int
facilityQueueCountRef Facility m a
r)
     let a' :: Int
a' = Int
a forall a. Num a => a -> a -> a
+ Int
delta
     forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$
       forall (m :: * -> *) a. MonadDES m => Ref m a -> a -> Event m ()
writeRef (forall (m :: * -> *) a. Facility m a -> Ref m Int
facilityQueueCountRef Facility m a
r) Int
a'
     forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$
       forall (m :: * -> *) a.
MonadDES m =>
Ref m a -> (a -> a) -> Event m ()
modifyRef (forall (m :: * -> *) a. Facility m a -> Ref m (TimingStats Int)
facilityQueueCountStatsRef Facility m a
r) forall a b. (a -> b) -> a -> b
$
       forall a.
TimingData a =>
Double -> a -> TimingStats a -> TimingStats a
addTimingStats (forall (m :: * -> *). Point m -> Double
pointTime Point m
p) Int
a'
     forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$
       forall (m :: * -> *) a. SignalSource m a -> a -> Event m ()
triggerSignal (forall (m :: * -> *) a. Facility m a -> SignalSource m Int
facilityQueueCountSource Facility m a
r) Int
a'

-- | Update the facility utilisation count and its statistics.
updateFacilityUtilisationCount :: MonadDES m => Facility m a -> Int -> Event m ()
{-# INLINABLE updateFacilityUtilisationCount #-}
updateFacilityUtilisationCount :: forall (m :: * -> *) a.
MonadDES m =>
Facility m a -> Int -> Event m ()
updateFacilityUtilisationCount Facility m a
r Int
delta =
  forall (m :: * -> *) a. (Point m -> m a) -> Event m a
Event forall a b. (a -> b) -> a -> b
$ \Point m
p ->
  do Int
a <- forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => Ref m a -> Event m a
readRef (forall (m :: * -> *) a. Facility m a -> Ref m Int
facilityUtilisationCountRef Facility m a
r)
     let a' :: Int
a' = Int
a forall a. Num a => a -> a -> a
+ Int
delta
     forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$
       forall (m :: * -> *) a. MonadDES m => Ref m a -> a -> Event m ()
writeRef (forall (m :: * -> *) a. Facility m a -> Ref m Int
facilityUtilisationCountRef Facility m a
r) Int
a'
     forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$
       forall (m :: * -> *) a.
MonadDES m =>
Ref m a -> (a -> a) -> Event m ()
modifyRef (forall (m :: * -> *) a. Facility m a -> Ref m (TimingStats Int)
facilityUtilisationCountStatsRef Facility m a
r) forall a b. (a -> b) -> a -> b
$
       forall a.
TimingData a =>
Double -> a -> TimingStats a -> TimingStats a
addTimingStats (forall (m :: * -> *). Point m -> Double
pointTime Point m
p) Int
a'
     forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$
       forall (m :: * -> *) a. SignalSource m a -> a -> Event m ()
triggerSignal (forall (m :: * -> *) a. Facility m a -> SignalSource m Int
facilityUtilisationCountSource Facility m a
r) Int
a'

-- | Update the facility wait time and its statistics.
updateFacilityWaitTime :: MonadDES m => Facility m a -> Double -> Event m ()
{-# INLINABLE updateFacilityWaitTime #-}
updateFacilityWaitTime :: forall (m :: * -> *) a.
MonadDES m =>
Facility m a -> Double -> Event m ()
updateFacilityWaitTime Facility m a
r Double
delta =
  forall (m :: * -> *) a. (Point m -> m a) -> Event m a
Event forall a b. (a -> b) -> a -> b
$ \Point m
p ->
  do Double
a <- forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => Ref m a -> Event m a
readRef (forall (m :: * -> *) a. Facility m a -> Ref m Double
facilityTotalWaitTimeRef Facility m a
r)
     let a' :: Double
a' = Double
a forall a. Num a => a -> a -> a
+ Double
delta
     forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$
       forall (m :: * -> *) a. MonadDES m => Ref m a -> a -> Event m ()
writeRef (forall (m :: * -> *) a. Facility m a -> Ref m Double
facilityTotalWaitTimeRef Facility m a
r) Double
a'
     forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$
       forall (m :: * -> *) a.
MonadDES m =>
Ref m a -> (a -> a) -> Event m ()
modifyRef (forall (m :: * -> *) a.
Facility m a -> Ref m (SamplingStats Double)
facilityWaitTimeRef Facility m a
r) forall a b. (a -> b) -> a -> b
$
       forall a. SamplingData a => a -> SamplingStats a -> SamplingStats a
addSamplingStats Double
delta
     forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$
       forall (m :: * -> *) a. SignalSource m a -> a -> Event m ()
triggerSignal (forall (m :: * -> *) a. Facility m a -> SignalSource m ()
facilityWaitTimeSource Facility m a
r) ()

-- | Update the facility holding time and its statistics.
updateFacilityHoldingTime :: MonadDES m => Facility m a -> Double -> Event m ()
{-# INLINABLE updateFacilityHoldingTime #-}
updateFacilityHoldingTime :: forall (m :: * -> *) a.
MonadDES m =>
Facility m a -> Double -> Event m ()
updateFacilityHoldingTime Facility m a
r Double
delta =
  forall (m :: * -> *) a. (Point m -> m a) -> Event m a
Event forall a b. (a -> b) -> a -> b
$ \Point m
p ->
  do Double
a <- forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => Ref m a -> Event m a
readRef (forall (m :: * -> *) a. Facility m a -> Ref m Double
facilityTotalHoldingTimeRef Facility m a
r)
     let a' :: Double
a' = Double
a forall a. Num a => a -> a -> a
+ Double
delta
     forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$
       forall (m :: * -> *) a. MonadDES m => Ref m a -> a -> Event m ()
writeRef (forall (m :: * -> *) a. Facility m a -> Ref m Double
facilityTotalHoldingTimeRef Facility m a
r) Double
a'
     forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$
       forall (m :: * -> *) a.
MonadDES m =>
Ref m a -> (a -> a) -> Event m ()
modifyRef (forall (m :: * -> *) a.
Facility m a -> Ref m (SamplingStats Double)
facilityHoldingTimeRef Facility m a
r) forall a b. (a -> b) -> a -> b
$
       forall a. SamplingData a => a -> SamplingStats a -> SamplingStats a
addSamplingStats Double
delta
     forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$
       forall (m :: * -> *) a. SignalSource m a -> a -> Event m ()
triggerSignal (forall (m :: * -> *) a. Facility m a -> SignalSource m ()
facilityHoldingTimeSource Facility m a
r) ()

-- | Reset the statistics.
resetFacility :: MonadDES m => Facility m a -> Event m ()
{-# INLINABLE resetFacility #-}
resetFacility :: forall (m :: * -> *) a. MonadDES m => Facility m a -> Event m ()
resetFacility Facility m a
r =
  forall (m :: * -> *) a. (Point m -> m a) -> Event m a
Event forall a b. (a -> b) -> a -> b
$ \Point m
p ->
  do let t :: Double
t = forall (m :: * -> *). Point m -> Double
pointTime Point m
p
     Int
count <- forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => Ref m a -> Event m a
readRef (forall (m :: * -> *) a. Facility m a -> Ref m Int
facilityCountRef Facility m a
r)
     forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => Ref m a -> a -> Event m ()
writeRef (forall (m :: * -> *) a. Facility m a -> Ref m (TimingStats Int)
facilityCountStatsRef Facility m a
r) forall a b. (a -> b) -> a -> b
$
       forall a. TimingData a => Double -> a -> TimingStats a
returnTimingStats Double
t Int
count
     forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => Ref m a -> a -> Event m ()
writeRef (forall (m :: * -> *) a. Facility m a -> Ref m Int
facilityCaptureCountRef Facility m a
r) Int
0
     Int
utilCount <- forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => Ref m a -> Event m a
readRef (forall (m :: * -> *) a. Facility m a -> Ref m Int
facilityUtilisationCountRef Facility m a
r)
     forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => Ref m a -> a -> Event m ()
writeRef (forall (m :: * -> *) a. Facility m a -> Ref m (TimingStats Int)
facilityUtilisationCountStatsRef Facility m a
r) forall a b. (a -> b) -> a -> b
$
       forall a. TimingData a => Double -> a -> TimingStats a
returnTimingStats Double
t Int
utilCount
     Int
queueCount <- forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => Ref m a -> Event m a
readRef (forall (m :: * -> *) a. Facility m a -> Ref m Int
facilityQueueCountRef Facility m a
r)
     forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => Ref m a -> a -> Event m ()
writeRef (forall (m :: * -> *) a. Facility m a -> Ref m (TimingStats Int)
facilityQueueCountStatsRef Facility m a
r) forall a b. (a -> b) -> a -> b
$
       forall a. TimingData a => Double -> a -> TimingStats a
returnTimingStats Double
t Int
queueCount
     forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => Ref m a -> a -> Event m ()
writeRef (forall (m :: * -> *) a. Facility m a -> Ref m Double
facilityTotalWaitTimeRef Facility m a
r) Double
0
     forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => Ref m a -> a -> Event m ()
writeRef (forall (m :: * -> *) a.
Facility m a -> Ref m (SamplingStats Double)
facilityWaitTimeRef Facility m a
r) forall a. SamplingData a => SamplingStats a
emptySamplingStats
     forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => Ref m a -> a -> Event m ()
writeRef (forall (m :: * -> *) a. Facility m a -> Ref m Double
facilityTotalHoldingTimeRef Facility m a
r) Double
0
     forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadDES m => Ref m a -> a -> Event m ()
writeRef (forall (m :: * -> *) a.
Facility m a -> Ref m (SamplingStats Double)
facilityHoldingTimeRef Facility m a
r) forall a. SamplingData a => SamplingStats a
emptySamplingStats
     forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$
       forall (m :: * -> *) a. SignalSource m a -> a -> Event m ()
triggerSignal (forall (m :: * -> *) a. Facility m a -> SignalSource m Int
facilityCaptureCountSource Facility m a
r) Int
0
     forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$
       forall (m :: * -> *) a. SignalSource m a -> a -> Event m ()
triggerSignal (forall (m :: * -> *) a. Facility m a -> SignalSource m ()
facilityWaitTimeSource Facility m a
r) ()
     forall (m :: * -> *) a. Point m -> Event m a -> m a
invokeEvent Point m
p forall a b. (a -> b) -> a -> b
$
       forall (m :: * -> *) a. SignalSource m a -> a -> Event m ()
triggerSignal (forall (m :: * -> *) a. Facility m a -> SignalSource m ()
facilityHoldingTimeSource Facility m a
r) ()