Skip to main content

DispatchStrategy

Trait DispatchStrategy 

Source
pub trait DispatchStrategy: Send + Sync {
    // Required method
    fn rank(&self, ctx: &RankContext<'_>) -> Option<f64>;

    // Provided methods
    fn pre_dispatch(
        &mut self,
        _group: &ElevatorGroup,
        _manifest: &DispatchManifest,
        _world: &mut World,
    ) { ... }
    fn prepare_car(
        &mut self,
        _car: EntityId,
        _car_position: f64,
        _group: &ElevatorGroup,
        _manifest: &DispatchManifest,
        _world: &World,
    ) { ... }
    fn fallback(
        &mut self,
        _car: EntityId,
        _car_position: f64,
        _group: &ElevatorGroup,
        _manifest: &DispatchManifest,
        _world: &World,
    ) -> DispatchDecision { ... }
    fn notify_removed(&mut self, _elevator: EntityId) { ... }
    fn builtin_id(&self) -> Option<BuiltinStrategy> { ... }
    fn snapshot_config(&self) -> Option<String> { ... }
    fn restore_config(&mut self, _serialized: &str) -> Result<(), String> { ... }
}
Expand description

Pluggable dispatch algorithm.

Strategies implement rank to score each (car, stop) pair; the dispatch system then performs an optimal assignment across the whole group, guaranteeing that no two cars are sent to the same hall call.

Returning None from rank excludes a pair from assignment — useful for capacity limits, direction preferences, restricted stops, or sticky commitments.

Cars that receive no stop fall through to fallback, which returns the policy for that car (idle, park, etc.).

Required Methods§

Source

fn rank(&self, ctx: &RankContext<'_>) -> Option<f64>

Score the cost of sending car to stop. Lower is better.

Returning None marks this (car, stop) pair as unavailable; the assignment algorithm will never pair them. Use this for capacity limits, wrong-direction stops, stops outside the line’s topology, or pairs already committed via a sticky assignment.

Must return a finite, non-negative value if Some — infinities and NaN can destabilize the underlying Hungarian solver.

Takes &self so the assignment loop can score (car, stop) pairs in any order without producing an asymmetric cost matrix. Compute any per-car scratch in prepare_car (which takes &mut self) before this method is called.

Provided Methods§

Source

fn pre_dispatch( &mut self, _group: &ElevatorGroup, _manifest: &DispatchManifest, _world: &mut World, )

Optional hook called once per group before the assignment pass.

Strategies that need to mutate World extension storage (e.g. DestinationDispatch writing sticky rider → car assignments) or pre-populate crate::components::DestinationQueue entries override this. Default: no-op.

Source

fn prepare_car( &mut self, _car: EntityId, _car_position: f64, _group: &ElevatorGroup, _manifest: &DispatchManifest, _world: &World, )

Optional hook called once per candidate car, before any rank calls for that car in the current pass.

Strategies whose ranking depends on stable per-car state (e.g. the sweep direction used by SCAN/LOOK) set that state here so later rank calls see a consistent view regardless of iteration order. The default is a no-op.

Source

fn fallback( &mut self, _car: EntityId, _car_position: f64, _group: &ElevatorGroup, _manifest: &DispatchManifest, _world: &World, ) -> DispatchDecision

Decide what an idle car should do when no stop was assigned to it.

Called for each car the assignment phase could not pair with a stop (because there were no stops, or all candidate stops had rank None for this car). Default: DispatchDecision::Idle.

Source

fn notify_removed(&mut self, _elevator: EntityId)

Notify the strategy that an elevator has been removed.

Implementations with per-elevator state (e.g. direction tracking) should clean up here to prevent unbounded memory growth.

Source

fn builtin_id(&self) -> Option<BuiltinStrategy>

If this strategy is a known built-in variant, return it so Simulation::new can stamp the correct BuiltinStrategy into the group’s snapshot identity.

Without this, legacy-topology sims constructed via Simulation::new(config, SomeNonScanStrategy::new()) silently recorded BuiltinStrategy::Scan as their identity — so a snapshot round-trip replaced the running strategy with Scan and produced different dispatch decisions post-restore (determinism regression).

Default: None (unidentified — the constructor falls back to recording BuiltinStrategy::Scan, matching pre-fix behaviour for callers that never cared about round-trip identity). Custom strategies that DO care should override this to return BuiltinStrategy::Custom with a stable name.

Source

fn snapshot_config(&self) -> Option<String>

Serialize this strategy’s tunable configuration to a string that restore_config can apply to a freshly-instantiated instance.

Returning Some(..) makes the configuration survive snapshot round-trip: without it, crate::snapshot::WorldSnapshot::restore instantiates each built-in via BuiltinStrategy::instantiate, which calls ::new() with default weights — silently dropping any tuning applied via with_* builder methods (e.g. EtdDispatch::with_delay_weight(2.5) degrades to the default 1.0 on the restored sim).

Default: None (no configuration to save). Built-ins with tunable weights override to return a RON-serialized copy of themselves; strategies with transient per-pass scratch should use #[serde(skip)] on those fields so the snapshot stays compact and deterministic.

Source

fn restore_config(&mut self, _serialized: &str) -> Result<(), String>

Restore tunable configuration from a string previously produced by snapshot_config on the same strategy variant. Called by crate::snapshot::WorldSnapshot::restore immediately after BuiltinStrategy::instantiate builds the default instance, so the restore writes over the defaults.

§Errors

Returns the underlying parse error as a String when the serialized form doesn’t round-trip. Default implementation ignores the argument and returns Ok(()) — paired with the None default of snapshot_config, this means strategies that don’t override either method skip configuration round-trip, matching pre-fix behaviour.

Implementors§