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, pair_is_useful};
20
21#[derive(serde::Serialize, serde::Deserialize)]
23pub struct LookDispatch {
24 direction: HashMap<EntityId, SweepDirection>,
30 #[serde(skip)]
34 mode: HashMap<EntityId, SweepMode>,
35}
36
37impl LookDispatch {
38 #[must_use]
40 pub fn new() -> Self {
41 Self {
42 direction: HashMap::new(),
43 mode: HashMap::new(),
44 }
45 }
46
47 fn direction_for(&self, car: EntityId) -> SweepDirection {
49 self.direction
50 .get(&car)
51 .copied()
52 .unwrap_or(SweepDirection::Up)
53 }
54
55 fn mode_for(&self, car: EntityId) -> SweepMode {
57 self.mode.get(&car).copied().unwrap_or(SweepMode::Strict)
58 }
59}
60
61impl Default for LookDispatch {
62 fn default() -> Self {
63 Self::new()
64 }
65}
66
67impl DispatchStrategy for LookDispatch {
68 fn prepare_car(
69 &mut self,
70 car: EntityId,
71 car_position: f64,
72 group: &ElevatorGroup,
73 manifest: &DispatchManifest,
74 world: &World,
75 ) {
76 let current = self.direction_for(car);
77 if sweep::strict_demand_ahead(current, car_position, group, manifest, world) {
78 self.mode.insert(car, SweepMode::Strict);
79 } else {
80 self.direction.insert(car, current.reversed());
81 self.mode.insert(car, SweepMode::Lenient);
82 }
83 }
84
85 fn rank(&mut self, ctx: &RankContext<'_>) -> Option<f64> {
86 if !pair_is_useful(ctx, false) {
90 return None;
91 }
92 sweep::rank(
93 self.mode_for(ctx.car),
94 self.direction_for(ctx.car),
95 ctx.car_position,
96 ctx.stop_position,
97 )
98 }
99
100 fn notify_removed(&mut self, elevator: EntityId) {
101 self.direction.remove(&elevator);
102 self.mode.remove(&elevator);
103 }
104
105 fn builtin_id(&self) -> Option<super::BuiltinStrategy> {
106 Some(super::BuiltinStrategy::Look)
107 }
108
109 fn snapshot_config(&self) -> Option<String> {
110 ron::to_string(self).ok()
111 }
112
113 fn restore_config(&mut self, serialized: &str) -> Result<(), String> {
114 let restored: Self = ron::from_str(serialized).map_err(|e| e.to_string())?;
115 *self = restored;
116 Ok(())
117 }
118}