1use std::any::{Any, TypeId};
4use std::collections::HashMap;
5use std::marker::PhantomData;
6
7use slotmap::{SecondaryMap, SlotMap};
8
9use crate::components::{
10 AccessControl, CallDirection, CarCall, DestinationQueue, Elevator, HallCall, Line, Patience,
11 Position, Preferences, Rider, Route, ServiceMode, Stop, Velocity,
12};
13#[cfg(feature = "energy")]
14use crate::energy::{EnergyMetrics, EnergyProfile};
15use crate::entity::EntityId;
16use crate::query::storage::AnyExtMap;
17
18#[derive(Debug)]
23pub struct ExtKey<T> {
24 name: &'static str,
26 _marker: PhantomData<T>,
28}
29
30impl<T> Clone for ExtKey<T> {
31 fn clone(&self) -> Self {
32 *self
33 }
34}
35impl<T> Copy for ExtKey<T> {}
36
37impl<T> ExtKey<T> {
38 #[must_use]
40 pub const fn new(name: &'static str) -> Self {
41 Self {
42 name,
43 _marker: PhantomData,
44 }
45 }
46
47 #[must_use]
49 pub fn from_type_name() -> Self {
50 Self {
51 name: std::any::type_name::<T>(),
52 _marker: PhantomData,
53 }
54 }
55
56 #[must_use]
58 pub const fn name(&self) -> &'static str {
59 self.name
60 }
61}
62
63impl<T> Default for ExtKey<T> {
64 fn default() -> Self {
65 Self::from_type_name()
66 }
67}
68
69pub struct World {
79 pub(crate) alive: SlotMap<EntityId, ()>,
81
82 pub(crate) positions: SecondaryMap<EntityId, Position>,
85 pub(crate) prev_positions: SecondaryMap<EntityId, Position>,
88 pub(crate) velocities: SecondaryMap<EntityId, Velocity>,
90 pub(crate) elevators: SecondaryMap<EntityId, Elevator>,
92 pub(crate) stops: SecondaryMap<EntityId, Stop>,
94 pub(crate) riders: SecondaryMap<EntityId, Rider>,
96 pub(crate) routes: SecondaryMap<EntityId, Route>,
98 pub(crate) lines: SecondaryMap<EntityId, Line>,
100 pub(crate) patience: SecondaryMap<EntityId, Patience>,
102 pub(crate) preferences: SecondaryMap<EntityId, Preferences>,
104 pub(crate) access_controls: SecondaryMap<EntityId, AccessControl>,
106
107 #[cfg(feature = "energy")]
109 pub(crate) energy_profiles: SecondaryMap<EntityId, EnergyProfile>,
110 #[cfg(feature = "energy")]
112 pub(crate) energy_metrics: SecondaryMap<EntityId, EnergyMetrics>,
113 pub(crate) service_modes: SecondaryMap<EntityId, ServiceMode>,
115 pub(crate) destination_queues: SecondaryMap<EntityId, DestinationQueue>,
117 pub(crate) hall_calls: SecondaryMap<EntityId, StopCalls>,
119 pub(crate) car_calls: SecondaryMap<EntityId, Vec<CarCall>>,
121
122 pub(crate) disabled: SecondaryMap<EntityId, ()>,
124
125 extensions: HashMap<TypeId, Box<dyn AnyExtMap>>,
128 ext_names: HashMap<TypeId, String>,
130
131 resources: HashMap<TypeId, Box<dyn Any + Send + Sync>>,
134}
135
136impl World {
137 #[must_use]
139 pub fn new() -> Self {
140 Self {
141 alive: SlotMap::with_key(),
142 positions: SecondaryMap::new(),
143 prev_positions: SecondaryMap::new(),
144 velocities: SecondaryMap::new(),
145 elevators: SecondaryMap::new(),
146 stops: SecondaryMap::new(),
147 riders: SecondaryMap::new(),
148 routes: SecondaryMap::new(),
149 lines: SecondaryMap::new(),
150 patience: SecondaryMap::new(),
151 preferences: SecondaryMap::new(),
152 access_controls: SecondaryMap::new(),
153 #[cfg(feature = "energy")]
154 energy_profiles: SecondaryMap::new(),
155 #[cfg(feature = "energy")]
156 energy_metrics: SecondaryMap::new(),
157 service_modes: SecondaryMap::new(),
158 destination_queues: SecondaryMap::new(),
159 hall_calls: SecondaryMap::new(),
160 car_calls: SecondaryMap::new(),
161 disabled: SecondaryMap::new(),
162 extensions: HashMap::new(),
163 ext_names: HashMap::new(),
164 resources: HashMap::new(),
165 }
166 }
167
168 pub fn spawn(&mut self) -> EntityId {
170 self.alive.insert(())
171 }
172
173 pub fn despawn(&mut self, id: EntityId) {
180 if let Some(rider) = self.riders.get(id) {
182 let weight = rider.weight;
183 match rider.phase {
185 crate::components::RiderPhase::Boarding(elev)
186 | crate::components::RiderPhase::Riding(elev)
187 | crate::components::RiderPhase::Exiting(elev) => {
188 if let Some(car) = self.elevators.get_mut(elev) {
189 car.riders.retain(|r| *r != id);
190 car.current_load -= weight;
191 }
192 }
193 _ => {}
194 }
195 }
196
197 if let Some(car) = self.elevators.get(id) {
199 let rider_ids: Vec<EntityId> = car.riders.clone();
200 let elev_pos = self.positions.get(id).map(|p| p.value);
201 let nearest_stop = elev_pos.and_then(|p| self.find_nearest_stop(p));
202 for rid in rider_ids {
203 if let Some(rider) = self.riders.get_mut(rid) {
204 rider.phase = crate::components::RiderPhase::Waiting;
205 rider.current_stop = nearest_stop;
206 }
207 }
208 }
209
210 self.alive.remove(id);
211 self.positions.remove(id);
212 self.prev_positions.remove(id);
213 self.velocities.remove(id);
214 self.elevators.remove(id);
215 self.stops.remove(id);
216 self.riders.remove(id);
217 self.routes.remove(id);
218 self.lines.remove(id);
219 self.patience.remove(id);
220 self.preferences.remove(id);
221 self.access_controls.remove(id);
222 #[cfg(feature = "energy")]
223 self.energy_profiles.remove(id);
224 #[cfg(feature = "energy")]
225 self.energy_metrics.remove(id);
226 self.service_modes.remove(id);
227 self.destination_queues.remove(id);
228 self.disabled.remove(id);
229 self.hall_calls.remove(id);
230 self.car_calls.remove(id);
231
232 for ext in self.extensions.values_mut() {
233 ext.remove(id);
234 }
235 }
236
237 #[must_use]
239 pub fn is_alive(&self, id: EntityId) -> bool {
240 self.alive.contains_key(id)
241 }
242
243 #[must_use]
245 pub fn entity_count(&self) -> usize {
246 self.alive.len()
247 }
248
249 pub(crate) fn alive_keys(&self) -> slotmap::basic::Keys<'_, EntityId, ()> {
251 self.alive.keys()
252 }
253
254 #[must_use]
258 pub fn position(&self, id: EntityId) -> Option<&Position> {
259 self.positions.get(id)
260 }
261
262 pub fn position_mut(&mut self, id: EntityId) -> Option<&mut Position> {
264 self.positions.get_mut(id)
265 }
266
267 pub fn set_position(&mut self, id: EntityId, pos: Position) {
269 self.positions.insert(id, pos);
270 }
271
272 #[must_use]
277 pub fn prev_position(&self, id: EntityId) -> Option<&Position> {
278 self.prev_positions.get(id)
279 }
280
281 pub(crate) fn snapshot_prev_positions(&mut self) {
287 self.prev_positions.clear();
288 for (id, pos) in &self.positions {
289 self.prev_positions.insert(id, *pos);
290 }
291 }
292
293 #[must_use]
297 pub fn velocity(&self, id: EntityId) -> Option<&Velocity> {
298 self.velocities.get(id)
299 }
300
301 pub fn velocity_mut(&mut self, id: EntityId) -> Option<&mut Velocity> {
303 self.velocities.get_mut(id)
304 }
305
306 pub fn set_velocity(&mut self, id: EntityId, vel: Velocity) {
308 self.velocities.insert(id, vel);
309 }
310
311 #[must_use]
315 pub fn elevator(&self, id: EntityId) -> Option<&Elevator> {
316 self.elevators.get(id)
317 }
318
319 pub fn elevator_mut(&mut self, id: EntityId) -> Option<&mut Elevator> {
321 self.elevators.get_mut(id)
322 }
323
324 pub fn set_elevator(&mut self, id: EntityId, elev: Elevator) {
326 self.elevators.insert(id, elev);
327 }
328
329 #[must_use]
333 pub fn rider(&self, id: EntityId) -> Option<&Rider> {
334 self.riders.get(id)
335 }
336
337 pub fn rider_mut(&mut self, id: EntityId) -> Option<&mut Rider> {
339 self.riders.get_mut(id)
340 }
341
342 pub fn set_rider(&mut self, id: EntityId, rider: Rider) {
344 self.riders.insert(id, rider);
345 }
346
347 #[must_use]
351 pub fn stop(&self, id: EntityId) -> Option<&Stop> {
352 self.stops.get(id)
353 }
354
355 pub fn stop_mut(&mut self, id: EntityId) -> Option<&mut Stop> {
357 self.stops.get_mut(id)
358 }
359
360 pub fn set_stop(&mut self, id: EntityId, stop: Stop) {
362 self.stops.insert(id, stop);
363 }
364
365 #[must_use]
369 pub fn route(&self, id: EntityId) -> Option<&Route> {
370 self.routes.get(id)
371 }
372
373 pub fn route_mut(&mut self, id: EntityId) -> Option<&mut Route> {
375 self.routes.get_mut(id)
376 }
377
378 pub fn set_route(&mut self, id: EntityId, route: Route) {
380 self.routes.insert(id, route);
381 }
382
383 #[must_use]
387 pub fn line(&self, id: EntityId) -> Option<&Line> {
388 self.lines.get(id)
389 }
390
391 pub fn line_mut(&mut self, id: EntityId) -> Option<&mut Line> {
393 self.lines.get_mut(id)
394 }
395
396 pub fn set_line(&mut self, id: EntityId, line: Line) {
398 self.lines.insert(id, line);
399 }
400
401 pub fn remove_line(&mut self, id: EntityId) -> Option<Line> {
403 self.lines.remove(id)
404 }
405
406 pub fn iter_lines(&self) -> impl Iterator<Item = (EntityId, &Line)> {
408 self.lines.iter()
409 }
410
411 #[must_use]
415 pub fn patience(&self, id: EntityId) -> Option<&Patience> {
416 self.patience.get(id)
417 }
418
419 pub fn patience_mut(&mut self, id: EntityId) -> Option<&mut Patience> {
421 self.patience.get_mut(id)
422 }
423
424 pub fn set_patience(&mut self, id: EntityId, patience: Patience) {
426 self.patience.insert(id, patience);
427 }
428
429 #[must_use]
433 pub fn preferences(&self, id: EntityId) -> Option<&Preferences> {
434 self.preferences.get(id)
435 }
436
437 pub fn set_preferences(&mut self, id: EntityId, prefs: Preferences) {
439 self.preferences.insert(id, prefs);
440 }
441
442 #[must_use]
446 pub fn access_control(&self, id: EntityId) -> Option<&AccessControl> {
447 self.access_controls.get(id)
448 }
449
450 pub fn access_control_mut(&mut self, id: EntityId) -> Option<&mut AccessControl> {
452 self.access_controls.get_mut(id)
453 }
454
455 pub fn set_access_control(&mut self, id: EntityId, ac: AccessControl) {
457 self.access_controls.insert(id, ac);
458 }
459
460 #[cfg(feature = "energy")]
463 #[must_use]
465 pub fn energy_profile(&self, id: EntityId) -> Option<&EnergyProfile> {
466 self.energy_profiles.get(id)
467 }
468
469 #[cfg(feature = "energy")]
470 #[must_use]
472 pub fn energy_metrics(&self, id: EntityId) -> Option<&EnergyMetrics> {
473 self.energy_metrics.get(id)
474 }
475
476 #[cfg(feature = "energy")]
477 pub fn energy_metrics_mut(&mut self, id: EntityId) -> Option<&mut EnergyMetrics> {
479 self.energy_metrics.get_mut(id)
480 }
481
482 #[cfg(feature = "energy")]
483 pub fn set_energy_profile(&mut self, id: EntityId, profile: EnergyProfile) {
485 self.energy_profiles.insert(id, profile);
486 }
487
488 #[cfg(feature = "energy")]
489 pub fn set_energy_metrics(&mut self, id: EntityId, metrics: EnergyMetrics) {
491 self.energy_metrics.insert(id, metrics);
492 }
493
494 #[must_use]
498 pub fn service_mode(&self, id: EntityId) -> Option<&ServiceMode> {
499 self.service_modes.get(id)
500 }
501
502 pub fn set_service_mode(&mut self, id: EntityId, mode: ServiceMode) {
504 self.service_modes.insert(id, mode);
505 }
506
507 #[must_use]
511 pub fn destination_queue(&self, id: EntityId) -> Option<&DestinationQueue> {
512 self.destination_queues.get(id)
513 }
514
515 pub(crate) fn destination_queue_mut(&mut self, id: EntityId) -> Option<&mut DestinationQueue> {
518 self.destination_queues.get_mut(id)
519 }
520
521 pub fn set_destination_queue(&mut self, id: EntityId, queue: DestinationQueue) {
523 self.destination_queues.insert(id, queue);
524 }
525
526 #[must_use]
534 pub fn stop_calls(&self, stop: EntityId) -> Option<&StopCalls> {
535 self.hall_calls.get(stop)
536 }
537
538 #[must_use]
540 pub fn hall_call(&self, stop: EntityId, direction: CallDirection) -> Option<&HallCall> {
541 self.hall_calls.get(stop).and_then(|c| c.get(direction))
542 }
543
544 #[allow(dead_code)]
546 pub(crate) fn hall_call_mut(
547 &mut self,
548 stop: EntityId,
549 direction: CallDirection,
550 ) -> Option<&mut HallCall> {
551 self.hall_calls
552 .get_mut(stop)
553 .and_then(|c| c.get_mut(direction))
554 }
555
556 #[allow(dead_code)]
559 pub(crate) fn set_hall_call(&mut self, call: HallCall) -> bool {
560 let Some(entry) = self.hall_calls.entry(call.stop) else {
561 return false;
562 };
563 let slot = entry.or_default();
564 match call.direction {
565 CallDirection::Up => slot.up = Some(call),
566 CallDirection::Down => slot.down = Some(call),
567 }
568 true
569 }
570
571 #[allow(dead_code)]
573 pub(crate) fn remove_hall_call(
574 &mut self,
575 stop: EntityId,
576 direction: CallDirection,
577 ) -> Option<HallCall> {
578 let entry = self.hall_calls.get_mut(stop)?;
579 match direction {
580 CallDirection::Up => entry.up.take(),
581 CallDirection::Down => entry.down.take(),
582 }
583 }
584
585 pub fn iter_hall_calls(&self) -> impl Iterator<Item = &HallCall> {
587 self.hall_calls.values().flat_map(StopCalls::iter)
588 }
589
590 #[allow(dead_code)]
592 pub(crate) fn iter_hall_calls_mut(&mut self) -> impl Iterator<Item = &mut HallCall> {
593 self.hall_calls.values_mut().flat_map(StopCalls::iter_mut)
594 }
595
596 #[must_use]
598 pub fn car_calls(&self, car: EntityId) -> &[CarCall] {
599 self.car_calls.get(car).map_or(&[], Vec::as_slice)
600 }
601
602 #[allow(dead_code)]
605 pub(crate) fn car_calls_mut(&mut self, car: EntityId) -> Option<&mut Vec<CarCall>> {
606 Some(self.car_calls.entry(car)?.or_default())
607 }
608
609 pub fn iter_elevators(&self) -> impl Iterator<Item = (EntityId, &Position, &Elevator)> {
613 self.elevators
614 .iter()
615 .filter_map(|(id, car)| self.positions.get(id).map(|pos| (id, pos, car)))
616 }
617
618 #[must_use]
620 pub fn elevator_ids(&self) -> Vec<EntityId> {
621 self.elevators.keys().collect()
622 }
623
624 pub fn elevator_ids_into(&self, buf: &mut Vec<EntityId>) {
626 buf.clear();
627 buf.extend(self.elevators.keys());
628 }
629
630 pub fn iter_riders(&self) -> impl Iterator<Item = (EntityId, &Rider)> {
632 self.riders.iter()
633 }
634
635 pub fn iter_riders_mut(&mut self) -> impl Iterator<Item = (EntityId, &mut Rider)> {
637 self.riders.iter_mut()
638 }
639
640 #[must_use]
642 pub fn rider_ids(&self) -> Vec<EntityId> {
643 self.riders.keys().collect()
644 }
645
646 pub fn iter_stops(&self) -> impl Iterator<Item = (EntityId, &Stop)> {
648 self.stops.iter()
649 }
650
651 #[must_use]
653 pub fn stop_ids(&self) -> Vec<EntityId> {
654 self.stops.keys().collect()
655 }
656
657 pub fn iter_idle_elevators(&self) -> impl Iterator<Item = (EntityId, &Position, &Elevator)> {
659 use crate::components::ElevatorPhase;
660 self.iter_elevators()
661 .filter(|(id, _, car)| car.phase == ElevatorPhase::Idle && !self.is_disabled(*id))
662 }
663
664 pub fn iter_moving_elevators(&self) -> impl Iterator<Item = (EntityId, &Position, &Elevator)> {
668 self.iter_elevators()
669 .filter(|(id, _, car)| car.phase.is_moving() && !self.is_disabled(*id))
670 }
671
672 pub fn iter_waiting_riders(&self) -> impl Iterator<Item = (EntityId, &Rider)> {
674 use crate::components::RiderPhase;
675 self.iter_riders()
676 .filter(|(id, r)| r.phase == RiderPhase::Waiting && !self.is_disabled(*id))
677 }
678
679 #[must_use]
681 pub fn find_stop_at_position(&self, position: f64) -> Option<EntityId> {
682 const EPSILON: f64 = 1e-6;
683 self.stops.iter().find_map(|(id, stop)| {
684 if (stop.position - position).abs() < EPSILON {
685 Some(id)
686 } else {
687 None
688 }
689 })
690 }
691
692 #[must_use]
698 pub fn find_nearest_stop(&self, position: f64) -> Option<EntityId> {
699 self.stops
700 .iter()
701 .min_by(|(_, a), (_, b)| {
702 (a.position - position)
703 .abs()
704 .total_cmp(&(b.position - position).abs())
705 })
706 .map(|(id, _)| id)
707 }
708
709 #[must_use]
711 pub fn stop_position(&self, id: EntityId) -> Option<f64> {
712 self.stops.get(id).map(|s| s.position)
713 }
714
715 pub fn insert_ext<T: 'static + Send + Sync + serde::Serialize + serde::de::DeserializeOwned>(
736 &mut self,
737 id: EntityId,
738 value: T,
739 key: ExtKey<T>,
740 ) {
741 let type_id = TypeId::of::<T>();
742 let map = self
743 .extensions
744 .entry(type_id)
745 .or_insert_with(|| Box::new(SecondaryMap::<EntityId, T>::new()));
746 if let Some(m) = map.as_any_mut().downcast_mut::<SecondaryMap<EntityId, T>>() {
747 m.insert(id, value);
748 }
749 self.ext_names.insert(type_id, key.name().to_owned());
750 }
751
752 #[must_use]
754 pub fn ext<T: 'static + Send + Sync + Clone>(&self, id: EntityId) -> Option<T> {
755 self.ext_map::<T>()?.get(id).cloned()
756 }
757
758 #[must_use]
764 pub fn ext_ref<T: 'static + Send + Sync>(&self, id: EntityId) -> Option<&T> {
765 self.ext_map::<T>()?.get(id)
766 }
767
768 pub fn ext_mut<T: 'static + Send + Sync>(&mut self, id: EntityId) -> Option<&mut T> {
770 self.ext_map_mut::<T>()?.get_mut(id)
771 }
772
773 pub fn remove_ext<T: 'static + Send + Sync>(&mut self, id: EntityId) -> Option<T> {
775 self.ext_map_mut::<T>()?.remove(id)
776 }
777
778 pub(crate) fn ext_map<T: 'static + Send + Sync>(&self) -> Option<&SecondaryMap<EntityId, T>> {
780 self.extensions
781 .get(&TypeId::of::<T>())?
782 .as_any()
783 .downcast_ref::<SecondaryMap<EntityId, T>>()
784 }
785
786 fn ext_map_mut<T: 'static + Send + Sync>(&mut self) -> Option<&mut SecondaryMap<EntityId, T>> {
788 self.extensions
789 .get_mut(&TypeId::of::<T>())?
790 .as_any_mut()
791 .downcast_mut::<SecondaryMap<EntityId, T>>()
792 }
793
794 pub(crate) fn serialize_extensions(&self) -> HashMap<String, HashMap<EntityId, String>> {
797 let mut result = HashMap::new();
798 for (type_id, map) in &self.extensions {
799 if let Some(name) = self.ext_names.get(type_id) {
800 result.insert(name.clone(), map.serialize_entries());
801 }
802 }
803 result
804 }
805
806 pub(crate) fn deserialize_extensions(
809 &mut self,
810 data: &HashMap<String, HashMap<EntityId, String>>,
811 ) {
812 for (name, entries) in data {
813 if let Some((&type_id, _)) = self.ext_names.iter().find(|(_, n)| *n == name)
815 && let Some(map) = self.extensions.get_mut(&type_id)
816 {
817 map.deserialize_entries(entries);
818 }
819 }
820 }
821
822 pub(crate) fn unregistered_ext_names<'a>(
824 &self,
825 snapshot_names: impl Iterator<Item = &'a String>,
826 ) -> Vec<String> {
827 let registered: std::collections::HashSet<&str> =
828 self.ext_names.values().map(String::as_str).collect();
829 snapshot_names
830 .filter(|name| !registered.contains(name.as_str()))
831 .cloned()
832 .collect()
833 }
834
835 pub fn register_ext<
840 T: 'static + Send + Sync + serde::Serialize + serde::de::DeserializeOwned,
841 >(
842 &mut self,
843 key: ExtKey<T>,
844 ) -> ExtKey<T> {
845 let type_id = TypeId::of::<T>();
846 self.extensions
847 .entry(type_id)
848 .or_insert_with(|| Box::new(SecondaryMap::<EntityId, T>::new()));
849 self.ext_names.insert(type_id, key.name().to_owned());
850 key
851 }
852
853 pub fn disable(&mut self, id: EntityId) {
857 self.disabled.insert(id, ());
858 }
859
860 pub fn enable(&mut self, id: EntityId) {
862 self.disabled.remove(id);
863 }
864
865 #[must_use]
867 pub fn is_disabled(&self, id: EntityId) -> bool {
868 self.disabled.contains_key(id)
869 }
870
871 pub fn insert_resource<T: 'static + Send + Sync>(&mut self, value: T) {
889 self.resources.insert(TypeId::of::<T>(), Box::new(value));
890 }
891
892 #[must_use]
894 pub fn resource<T: 'static + Send + Sync>(&self) -> Option<&T> {
895 self.resources.get(&TypeId::of::<T>())?.downcast_ref()
896 }
897
898 pub fn resource_mut<T: 'static + Send + Sync>(&mut self) -> Option<&mut T> {
900 self.resources.get_mut(&TypeId::of::<T>())?.downcast_mut()
901 }
902
903 pub fn remove_resource<T: 'static + Send + Sync>(&mut self) -> Option<T> {
905 self.resources
906 .remove(&TypeId::of::<T>())
907 .and_then(|b| b.downcast().ok())
908 .map(|b| *b)
909 }
910
911 #[must_use]
927 pub const fn query<Q: crate::query::WorldQuery>(&self) -> crate::query::QueryBuilder<'_, Q> {
928 crate::query::QueryBuilder::new(self)
929 }
930
931 pub fn query_ext_mut<T: 'static + Send + Sync>(&mut self) -> crate::query::ExtQueryMut<'_, T> {
945 crate::query::ExtQueryMut::new(self)
946 }
947}
948
949impl Default for World {
950 fn default() -> Self {
951 Self::new()
952 }
953}
954
955pub(crate) struct SortedStops(pub(crate) Vec<(f64, EntityId)>);
960
961#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)]
967pub struct StopCalls {
968 pub up: Option<HallCall>,
970 pub down: Option<HallCall>,
972}
973
974impl StopCalls {
975 #[must_use]
977 pub const fn get(&self, direction: CallDirection) -> Option<&HallCall> {
978 match direction {
979 CallDirection::Up => self.up.as_ref(),
980 CallDirection::Down => self.down.as_ref(),
981 }
982 }
983
984 pub const fn get_mut(&mut self, direction: CallDirection) -> Option<&mut HallCall> {
986 match direction {
987 CallDirection::Up => self.up.as_mut(),
988 CallDirection::Down => self.down.as_mut(),
989 }
990 }
991
992 pub fn iter(&self) -> impl Iterator<Item = &HallCall> {
994 self.up.iter().chain(self.down.iter())
995 }
996
997 pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut HallCall> {
999 self.up.iter_mut().chain(self.down.iter_mut())
1000 }
1001}