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