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 = (car.current_load - weight).max(0.0);
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
230 for ext in self.extensions.values_mut() {
231 ext.remove(id);
232 }
233 }
234
235 #[must_use]
237 pub fn is_alive(&self, id: EntityId) -> bool {
238 self.alive.contains_key(id)
239 }
240
241 #[must_use]
243 pub fn entity_count(&self) -> usize {
244 self.alive.len()
245 }
246
247 pub(crate) fn alive_keys(&self) -> slotmap::basic::Keys<'_, EntityId, ()> {
249 self.alive.keys()
250 }
251
252 #[must_use]
256 pub fn position(&self, id: EntityId) -> Option<&Position> {
257 self.positions.get(id)
258 }
259
260 pub fn position_mut(&mut self, id: EntityId) -> Option<&mut Position> {
262 self.positions.get_mut(id)
263 }
264
265 pub fn set_position(&mut self, id: EntityId, pos: Position) {
267 self.positions.insert(id, pos);
268 }
269
270 #[must_use]
275 pub fn prev_position(&self, id: EntityId) -> Option<&Position> {
276 self.prev_positions.get(id)
277 }
278
279 pub(crate) fn snapshot_prev_positions(&mut self) {
285 self.prev_positions.clear();
286 for (id, pos) in &self.positions {
287 self.prev_positions.insert(id, *pos);
288 }
289 }
290
291 #[must_use]
295 pub fn velocity(&self, id: EntityId) -> Option<&Velocity> {
296 self.velocities.get(id)
297 }
298
299 pub fn velocity_mut(&mut self, id: EntityId) -> Option<&mut Velocity> {
301 self.velocities.get_mut(id)
302 }
303
304 pub fn set_velocity(&mut self, id: EntityId, vel: Velocity) {
306 self.velocities.insert(id, vel);
307 }
308
309 #[must_use]
313 pub fn elevator(&self, id: EntityId) -> Option<&Elevator> {
314 self.elevators.get(id)
315 }
316
317 pub fn elevator_mut(&mut self, id: EntityId) -> Option<&mut Elevator> {
319 self.elevators.get_mut(id)
320 }
321
322 pub fn set_elevator(&mut self, id: EntityId, elev: Elevator) {
324 self.elevators.insert(id, elev);
325 }
326
327 #[must_use]
331 pub fn rider(&self, id: EntityId) -> Option<&Rider> {
332 self.riders.get(id)
333 }
334
335 pub fn rider_mut(&mut self, id: EntityId) -> Option<&mut Rider> {
337 self.riders.get_mut(id)
338 }
339
340 pub fn set_rider(&mut self, id: EntityId, rider: Rider) {
342 self.riders.insert(id, rider);
343 }
344
345 #[must_use]
349 pub fn stop(&self, id: EntityId) -> Option<&Stop> {
350 self.stops.get(id)
351 }
352
353 pub fn stop_mut(&mut self, id: EntityId) -> Option<&mut Stop> {
355 self.stops.get_mut(id)
356 }
357
358 pub fn set_stop(&mut self, id: EntityId, stop: Stop) {
360 self.stops.insert(id, stop);
361 }
362
363 #[must_use]
367 pub fn route(&self, id: EntityId) -> Option<&Route> {
368 self.routes.get(id)
369 }
370
371 pub fn route_mut(&mut self, id: EntityId) -> Option<&mut Route> {
373 self.routes.get_mut(id)
374 }
375
376 pub fn set_route(&mut self, id: EntityId, route: Route) {
378 self.routes.insert(id, route);
379 }
380
381 #[must_use]
385 pub fn line(&self, id: EntityId) -> Option<&Line> {
386 self.lines.get(id)
387 }
388
389 pub fn line_mut(&mut self, id: EntityId) -> Option<&mut Line> {
391 self.lines.get_mut(id)
392 }
393
394 pub fn set_line(&mut self, id: EntityId, line: Line) {
396 self.lines.insert(id, line);
397 }
398
399 pub fn remove_line(&mut self, id: EntityId) -> Option<Line> {
401 self.lines.remove(id)
402 }
403
404 pub fn iter_lines(&self) -> impl Iterator<Item = (EntityId, &Line)> {
406 self.lines.iter()
407 }
408
409 #[must_use]
413 pub fn patience(&self, id: EntityId) -> Option<&Patience> {
414 self.patience.get(id)
415 }
416
417 pub fn patience_mut(&mut self, id: EntityId) -> Option<&mut Patience> {
419 self.patience.get_mut(id)
420 }
421
422 pub fn set_patience(&mut self, id: EntityId, patience: Patience) {
424 self.patience.insert(id, patience);
425 }
426
427 #[must_use]
431 pub fn preferences(&self, id: EntityId) -> Option<&Preferences> {
432 self.preferences.get(id)
433 }
434
435 pub fn set_preferences(&mut self, id: EntityId, prefs: Preferences) {
437 self.preferences.insert(id, prefs);
438 }
439
440 #[must_use]
444 pub fn access_control(&self, id: EntityId) -> Option<&AccessControl> {
445 self.access_controls.get(id)
446 }
447
448 pub fn access_control_mut(&mut self, id: EntityId) -> Option<&mut AccessControl> {
450 self.access_controls.get_mut(id)
451 }
452
453 pub fn set_access_control(&mut self, id: EntityId, ac: AccessControl) {
455 self.access_controls.insert(id, ac);
456 }
457
458 #[cfg(feature = "energy")]
461 #[must_use]
463 pub fn energy_profile(&self, id: EntityId) -> Option<&EnergyProfile> {
464 self.energy_profiles.get(id)
465 }
466
467 #[cfg(feature = "energy")]
468 #[must_use]
470 pub fn energy_metrics(&self, id: EntityId) -> Option<&EnergyMetrics> {
471 self.energy_metrics.get(id)
472 }
473
474 #[cfg(feature = "energy")]
475 pub fn energy_metrics_mut(&mut self, id: EntityId) -> Option<&mut EnergyMetrics> {
477 self.energy_metrics.get_mut(id)
478 }
479
480 #[cfg(feature = "energy")]
481 pub fn set_energy_profile(&mut self, id: EntityId, profile: EnergyProfile) {
483 self.energy_profiles.insert(id, profile);
484 }
485
486 #[cfg(feature = "energy")]
487 pub fn set_energy_metrics(&mut self, id: EntityId, metrics: EnergyMetrics) {
489 self.energy_metrics.insert(id, metrics);
490 }
491
492 #[must_use]
496 pub fn service_mode(&self, id: EntityId) -> Option<&ServiceMode> {
497 self.service_modes.get(id)
498 }
499
500 pub fn set_service_mode(&mut self, id: EntityId, mode: ServiceMode) {
502 self.service_modes.insert(id, mode);
503 }
504
505 #[must_use]
509 pub fn destination_queue(&self, id: EntityId) -> Option<&DestinationQueue> {
510 self.destination_queues.get(id)
511 }
512
513 pub(crate) fn destination_queue_mut(&mut self, id: EntityId) -> Option<&mut DestinationQueue> {
516 self.destination_queues.get_mut(id)
517 }
518
519 pub fn set_destination_queue(&mut self, id: EntityId, queue: DestinationQueue) {
521 self.destination_queues.insert(id, queue);
522 }
523
524 #[must_use]
532 pub fn stop_calls(&self, stop: EntityId) -> Option<&StopCalls> {
533 self.hall_calls.get(stop)
534 }
535
536 #[must_use]
538 pub fn hall_call(&self, stop: EntityId, direction: CallDirection) -> Option<&HallCall> {
539 self.hall_calls.get(stop).and_then(|c| c.get(direction))
540 }
541
542 #[allow(dead_code)]
544 pub(crate) fn hall_call_mut(
545 &mut self,
546 stop: EntityId,
547 direction: CallDirection,
548 ) -> Option<&mut HallCall> {
549 self.hall_calls
550 .get_mut(stop)
551 .and_then(|c| c.get_mut(direction))
552 }
553
554 #[allow(dead_code)]
557 pub(crate) fn set_hall_call(&mut self, call: HallCall) -> bool {
558 let Some(entry) = self.hall_calls.entry(call.stop) else {
559 return false;
560 };
561 let slot = entry.or_default();
562 match call.direction {
563 CallDirection::Up => slot.up = Some(call),
564 CallDirection::Down => slot.down = Some(call),
565 }
566 true
567 }
568
569 #[allow(dead_code)]
571 pub(crate) fn remove_hall_call(
572 &mut self,
573 stop: EntityId,
574 direction: CallDirection,
575 ) -> Option<HallCall> {
576 let entry = self.hall_calls.get_mut(stop)?;
577 match direction {
578 CallDirection::Up => entry.up.take(),
579 CallDirection::Down => entry.down.take(),
580 }
581 }
582
583 pub fn iter_hall_calls(&self) -> impl Iterator<Item = &HallCall> {
585 self.hall_calls.values().flat_map(StopCalls::iter)
586 }
587
588 #[allow(dead_code)]
590 pub(crate) fn iter_hall_calls_mut(&mut self) -> impl Iterator<Item = &mut HallCall> {
591 self.hall_calls.values_mut().flat_map(StopCalls::iter_mut)
592 }
593
594 #[must_use]
596 pub fn car_calls(&self, car: EntityId) -> &[CarCall] {
597 self.car_calls.get(car).map_or(&[], Vec::as_slice)
598 }
599
600 #[allow(dead_code)]
603 pub(crate) fn car_calls_mut(&mut self, car: EntityId) -> Option<&mut Vec<CarCall>> {
604 Some(self.car_calls.entry(car)?.or_default())
605 }
606
607 pub fn iter_elevators(&self) -> impl Iterator<Item = (EntityId, &Position, &Elevator)> {
611 self.elevators
612 .iter()
613 .filter_map(|(id, car)| self.positions.get(id).map(|pos| (id, pos, car)))
614 }
615
616 #[must_use]
618 pub fn elevator_ids(&self) -> Vec<EntityId> {
619 self.elevators.keys().collect()
620 }
621
622 pub fn elevator_ids_into(&self, buf: &mut Vec<EntityId>) {
624 buf.clear();
625 buf.extend(self.elevators.keys());
626 }
627
628 pub fn iter_riders(&self) -> impl Iterator<Item = (EntityId, &Rider)> {
630 self.riders.iter()
631 }
632
633 pub fn iter_riders_mut(&mut self) -> impl Iterator<Item = (EntityId, &mut Rider)> {
635 self.riders.iter_mut()
636 }
637
638 #[must_use]
640 pub fn rider_ids(&self) -> Vec<EntityId> {
641 self.riders.keys().collect()
642 }
643
644 pub fn iter_stops(&self) -> impl Iterator<Item = (EntityId, &Stop)> {
646 self.stops.iter()
647 }
648
649 #[must_use]
651 pub fn stop_ids(&self) -> Vec<EntityId> {
652 self.stops.keys().collect()
653 }
654
655 pub fn iter_idle_elevators(&self) -> impl Iterator<Item = (EntityId, &Position, &Elevator)> {
657 use crate::components::ElevatorPhase;
658 self.iter_elevators()
659 .filter(|(id, _, car)| car.phase == ElevatorPhase::Idle && !self.is_disabled(*id))
660 }
661
662 pub fn iter_moving_elevators(&self) -> impl Iterator<Item = (EntityId, &Position, &Elevator)> {
666 self.iter_elevators()
667 .filter(|(id, _, car)| car.phase.is_moving() && !self.is_disabled(*id))
668 }
669
670 pub fn iter_waiting_riders(&self) -> impl Iterator<Item = (EntityId, &Rider)> {
672 use crate::components::RiderPhase;
673 self.iter_riders()
674 .filter(|(id, r)| r.phase == RiderPhase::Waiting && !self.is_disabled(*id))
675 }
676
677 #[must_use]
679 pub fn find_stop_at_position(&self, position: f64) -> Option<EntityId> {
680 const EPSILON: f64 = 1e-6;
681 self.stops.iter().find_map(|(id, stop)| {
682 if (stop.position - position).abs() < EPSILON {
683 Some(id)
684 } else {
685 None
686 }
687 })
688 }
689
690 #[must_use]
696 pub fn find_nearest_stop(&self, position: f64) -> Option<EntityId> {
697 self.stops
698 .iter()
699 .min_by(|(_, a), (_, b)| {
700 (a.position - position)
701 .abs()
702 .total_cmp(&(b.position - position).abs())
703 })
704 .map(|(id, _)| id)
705 }
706
707 #[must_use]
709 pub fn stop_position(&self, id: EntityId) -> Option<f64> {
710 self.stops.get(id).map(|s| s.position)
711 }
712
713 pub fn insert_ext<T: 'static + Send + Sync + serde::Serialize + serde::de::DeserializeOwned>(
734 &mut self,
735 id: EntityId,
736 value: T,
737 key: ExtKey<T>,
738 ) {
739 let type_id = TypeId::of::<T>();
740 let map = self
741 .extensions
742 .entry(type_id)
743 .or_insert_with(|| Box::new(SecondaryMap::<EntityId, T>::new()));
744 if let Some(m) = map.as_any_mut().downcast_mut::<SecondaryMap<EntityId, T>>() {
745 m.insert(id, value);
746 }
747 self.ext_names.insert(type_id, key.name().to_owned());
748 }
749
750 #[must_use]
752 pub fn get_ext<T: 'static + Send + Sync + Clone>(&self, id: EntityId) -> Option<T> {
753 self.ext_map::<T>()?.get(id).cloned()
754 }
755
756 #[must_use]
762 pub fn get_ext_ref<T: 'static + Send + Sync>(&self, id: EntityId) -> Option<&T> {
763 self.ext_map::<T>()?.get(id)
764 }
765
766 pub fn get_ext_mut<T: 'static + Send + Sync>(&mut self, id: EntityId) -> Option<&mut T> {
768 self.ext_map_mut::<T>()?.get_mut(id)
769 }
770
771 pub fn remove_ext<T: 'static + Send + Sync>(&mut self, id: EntityId) -> Option<T> {
773 self.ext_map_mut::<T>()?.remove(id)
774 }
775
776 pub(crate) fn ext_map<T: 'static + Send + Sync>(&self) -> Option<&SecondaryMap<EntityId, T>> {
778 self.extensions
779 .get(&TypeId::of::<T>())?
780 .as_any()
781 .downcast_ref::<SecondaryMap<EntityId, T>>()
782 }
783
784 fn ext_map_mut<T: 'static + Send + Sync>(&mut self) -> Option<&mut SecondaryMap<EntityId, T>> {
786 self.extensions
787 .get_mut(&TypeId::of::<T>())?
788 .as_any_mut()
789 .downcast_mut::<SecondaryMap<EntityId, T>>()
790 }
791
792 pub(crate) fn serialize_extensions(&self) -> HashMap<String, HashMap<EntityId, String>> {
795 let mut result = HashMap::new();
796 for (type_id, map) in &self.extensions {
797 if let Some(name) = self.ext_names.get(type_id) {
798 result.insert(name.clone(), map.serialize_entries());
799 }
800 }
801 result
802 }
803
804 pub(crate) fn deserialize_extensions(
807 &mut self,
808 data: &HashMap<String, HashMap<EntityId, String>>,
809 ) {
810 for (name, entries) in data {
811 if let Some((&type_id, _)) = self.ext_names.iter().find(|(_, n)| *n == name)
813 && let Some(map) = self.extensions.get_mut(&type_id)
814 {
815 map.deserialize_entries(entries);
816 }
817 }
818 }
819
820 pub fn register_ext<
825 T: 'static + Send + Sync + serde::Serialize + serde::de::DeserializeOwned,
826 >(
827 &mut self,
828 key: ExtKey<T>,
829 ) -> ExtKey<T> {
830 let type_id = TypeId::of::<T>();
831 self.extensions
832 .entry(type_id)
833 .or_insert_with(|| Box::new(SecondaryMap::<EntityId, T>::new()));
834 self.ext_names.insert(type_id, key.name().to_owned());
835 key
836 }
837
838 pub fn disable(&mut self, id: EntityId) {
842 self.disabled.insert(id, ());
843 }
844
845 pub fn enable(&mut self, id: EntityId) {
847 self.disabled.remove(id);
848 }
849
850 #[must_use]
852 pub fn is_disabled(&self, id: EntityId) -> bool {
853 self.disabled.contains_key(id)
854 }
855
856 pub fn insert_resource<T: 'static + Send + Sync>(&mut self, value: T) {
874 self.resources.insert(TypeId::of::<T>(), Box::new(value));
875 }
876
877 #[must_use]
879 pub fn resource<T: 'static + Send + Sync>(&self) -> Option<&T> {
880 self.resources.get(&TypeId::of::<T>())?.downcast_ref()
881 }
882
883 pub fn resource_mut<T: 'static + Send + Sync>(&mut self) -> Option<&mut T> {
885 self.resources.get_mut(&TypeId::of::<T>())?.downcast_mut()
886 }
887
888 pub fn remove_resource<T: 'static + Send + Sync>(&mut self) -> Option<T> {
890 self.resources
891 .remove(&TypeId::of::<T>())
892 .and_then(|b| b.downcast().ok())
893 .map(|b| *b)
894 }
895
896 #[must_use]
912 pub const fn query<Q: crate::query::WorldQuery>(&self) -> crate::query::QueryBuilder<'_, Q> {
913 crate::query::QueryBuilder::new(self)
914 }
915
916 pub fn query_ext_mut<T: 'static + Send + Sync>(&mut self) -> crate::query::ExtQueryMut<'_, T> {
930 crate::query::ExtQueryMut::new(self)
931 }
932}
933
934impl Default for World {
935 fn default() -> Self {
936 Self::new()
937 }
938}
939
940pub(crate) struct SortedStops(pub(crate) Vec<(f64, EntityId)>);
945
946#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)]
952pub struct StopCalls {
953 pub up: Option<HallCall>,
955 pub down: Option<HallCall>,
957}
958
959impl StopCalls {
960 #[must_use]
962 pub const fn get(&self, direction: CallDirection) -> Option<&HallCall> {
963 match direction {
964 CallDirection::Up => self.up.as_ref(),
965 CallDirection::Down => self.down.as_ref(),
966 }
967 }
968
969 pub const fn get_mut(&mut self, direction: CallDirection) -> Option<&mut HallCall> {
971 match direction {
972 CallDirection::Up => self.up.as_mut(),
973 CallDirection::Down => self.down.as_mut(),
974 }
975 }
976
977 pub fn iter(&self) -> impl Iterator<Item = &HallCall> {
979 self.up.iter().chain(self.down.iter())
980 }
981
982 pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut HallCall> {
984 self.up.iter_mut().chain(self.down.iter_mut())
985 }
986}