DemandForwarder

open class DemandForwarder @JvmOverloads constructor(parent: ModelElement, val upstreamSupplier: () -> DemandFillerIfc?, val sender: DemandSenderIfc, val onUpstreamDelivered: (original: SupplyChainModel.Demand) -> Unit? = null, val shouldFillOnReceive: (DemandFillerIfc) -> Boolean = { true }, name: String? = null) : ModelElement, DemandFillerIfc(source)

A DemandFillerIfc that doesn't fulfil demands from local stock — instead it forwards each incoming demand to an upstream supplier, waits for delivery, and runs a user-supplied callback when the upstream delivers. Analogous to a real-world freight forwarder or drop-shipper: takes the order, places it with a supplier, takes delivery, hands the goods to the original customer.

Typical use is to assign a DemandForwarder to a routing node's demandFiller slot. When the network sends a demand to that node, the forwarder receives it for processing, propagates an equivalent request upstream, and on upstream delivery runs whatever finalisation the node needs (typically original.fulfillAndDispatch(carrier) to ship the original onward, or letting a receiving-dock mechanism handle it).

On receive(demand) the forwarder:

  1. Receives the demand for processing via receiveForProcessing — the demand transitions to IN_PROCESS and waits here for upstream delivery.

  2. Sends an equivalent request to the upstream filler resolved by upstreamSupplier.

  3. When the upstream receives the forwarded request, the forwarder asks the upstream to fill it (filler.fillDemand(...)) unless shouldFillOnReceive returns false (used to opt out for upstreams that drive their own fill cycle, like a routing facility).

  4. When the upstream eventually delivers the forwarded request, onUpstreamDelivered is invoked (if non-null) with the original demand — the node now does whatever is needed to complete it (typically fulfil and dispatch via the node's outbound carrier).

The forwarder is itself a persistent DemandFillerIfc — its remaining surface (fillDemand, negotiate, item-type predicates, etc.) is routing-only stubs.

Parameters

parent

the model element that owns this forwarder (typically the routing node it's attached to)

upstreamSupplier

resolves the upstream filler at call time, so callers can configure the upstream after construction (the typical pattern when a node's demandFiller is set by network attachment)

sender

the DemandSenderIfc to stamp on the forwarded request — typically the routing node so the upstream knows where to return the delivery

onUpstreamDelivered

optional callback fired when the upstream delivers the forwarded request; receives the original demand that was forwarded. Leave null when a receiving-dock mechanism will handle finalisation.

shouldFillOnReceive

predicate that gates whether to ask the upstream to fillDemand on RECEIVED. Defaults to always true; pass a predicate returning false for upstreams that drive their own fill cycle.

name

optional model-element name

See also

Constructors

Link copied to clipboard
constructor(parent: ModelElement, upstreamSupplier: () -> DemandFillerIfc?, sender: DemandSenderIfc, onUpstreamDelivered: (original: SupplyChainModel.Demand) -> Unit? = null, shouldFillOnReceive: (DemandFillerIfc) -> Boolean = { true }, name: String? = null)

Properties

Link copied to clipboard
open override var demandCarrier: DemandCarrierIfc?

Carrier used to send filled demands to their destination.

Link copied to clipboard
open override var demandPreparer: DemandPreparerIfc?

Optional pre-shipment preparer.

Link copied to clipboard
open override val isAvailable: Boolean = true

True when this object can currently be selected for use.

Link copied to clipboard
open override val itemTypes: Collection<ItemType>

All item types this filler is willing to fill.

Link copied to clipboard
Link copied to clipboard
Link copied to clipboard
Link copied to clipboard

Functions

Link copied to clipboard
open override fun canFillItemType(type: ItemType): Boolean

True if this filler can fill demands of type.

open override fun canFillItemType(demand: SupplyChainModel.Demand): Boolean

True if this filler can fill demands of demand's item type.

Link copied to clipboard

The status demand would receive if filled now. Only valid at the current simulation time.

Link copied to clipboard
open override fun fillDemand(demand: SupplyChainModel.Demand)

Fill a previously received demand. Must be called at the same simulation time as the receipt — no time may elapse between receive and fillDemand.

Link copied to clipboard

Returns a DemandMessageIfc describing what would happen if demand were sent now, or null if negotiation is not supported.

Link copied to clipboard
open override fun receive(demand: SupplyChainModel.Demand)

Receive demand and place it in SupplyChainModel.received, or reject by transitioning to SupplyChainModel.rejected. The filler may set the demand's SupplyChainModel.Demand.status to indicate the rejection reason but is not required to.

Link copied to clipboard
open override fun willReject(demand: SupplyChainModel.Demand): Boolean

True if demand would be rejected if filled now.