elevator_core/dispatch/
look.rs1use std::collections::HashMap;
14
15use crate::entity::EntityId;
16use crate::world::World;
17
18use super::sweep::{self, SweepDirection, SweepMode};
19use super::{DispatchManifest, DispatchStrategy, ElevatorGroup, RankContext};
20
21pub struct LookDispatch {
23 direction: HashMap<EntityId, SweepDirection>,
25 mode: HashMap<EntityId, SweepMode>,
27}
28
29impl LookDispatch {
30 #[must_use]
32 pub fn new() -> Self {
33 Self {
34 direction: HashMap::new(),
35 mode: HashMap::new(),
36 }
37 }
38
39 fn direction_for(&self, car: EntityId) -> SweepDirection {
41 self.direction
42 .get(&car)
43 .copied()
44 .unwrap_or(SweepDirection::Up)
45 }
46
47 fn mode_for(&self, car: EntityId) -> SweepMode {
49 self.mode.get(&car).copied().unwrap_or(SweepMode::Strict)
50 }
51}
52
53impl Default for LookDispatch {
54 fn default() -> Self {
55 Self::new()
56 }
57}
58
59impl DispatchStrategy for LookDispatch {
60 fn prepare_car(
61 &mut self,
62 car: EntityId,
63 car_position: f64,
64 group: &ElevatorGroup,
65 manifest: &DispatchManifest,
66 world: &World,
67 ) {
68 let current = self.direction_for(car);
69 if sweep::strict_demand_ahead(current, car_position, group, manifest, world) {
70 self.mode.insert(car, SweepMode::Strict);
71 } else {
72 self.direction.insert(car, current.reversed());
73 self.mode.insert(car, SweepMode::Lenient);
74 }
75 }
76
77 fn rank(&mut self, ctx: &RankContext<'_>) -> Option<f64> {
78 sweep::rank(
79 self.mode_for(ctx.car),
80 self.direction_for(ctx.car),
81 ctx.car_position,
82 ctx.stop_position,
83 )
84 }
85
86 fn notify_removed(&mut self, elevator: EntityId) {
87 self.direction.remove(&elevator);
88 self.mode.remove(&elevator);
89 }
90}