1use std::any::{Any, TypeId};
4use std::collections::HashMap;
5
6use slotmap::{SecondaryMap, SlotMap};
7
8use crate::components::{
9 AccessControl, CallDirection, CarCall, DestinationQueue, Elevator, HallCall, Line, Patience,
10 Position, Preferences, Rider, Route, ServiceMode, Stop, Velocity,
11};
12#[cfg(feature = "energy")]
13use crate::energy::{EnergyMetrics, EnergyProfile};
14use crate::entity::EntityId;
15use crate::query::storage::AnyExtMap;
16
17pub struct World {
27 pub(crate) alive: SlotMap<EntityId, ()>,
29
30 pub(crate) positions: SecondaryMap<EntityId, Position>,
33 pub(crate) prev_positions: SecondaryMap<EntityId, Position>,
36 pub(crate) velocities: SecondaryMap<EntityId, Velocity>,
38 pub(crate) elevators: SecondaryMap<EntityId, Elevator>,
40 pub(crate) stops: SecondaryMap<EntityId, Stop>,
42 pub(crate) riders: SecondaryMap<EntityId, Rider>,
44 pub(crate) routes: SecondaryMap<EntityId, Route>,
46 pub(crate) lines: SecondaryMap<EntityId, Line>,
48 pub(crate) patience: SecondaryMap<EntityId, Patience>,
50 pub(crate) preferences: SecondaryMap<EntityId, Preferences>,
52 pub(crate) access_controls: SecondaryMap<EntityId, AccessControl>,
54
55 #[cfg(feature = "energy")]
57 pub(crate) energy_profiles: SecondaryMap<EntityId, EnergyProfile>,
58 #[cfg(feature = "energy")]
60 pub(crate) energy_metrics: SecondaryMap<EntityId, EnergyMetrics>,
61 pub(crate) service_modes: SecondaryMap<EntityId, ServiceMode>,
63 pub(crate) destination_queues: SecondaryMap<EntityId, DestinationQueue>,
65 pub(crate) hall_calls: SecondaryMap<EntityId, StopCalls>,
67 pub(crate) car_calls: SecondaryMap<EntityId, Vec<CarCall>>,
69
70 pub(crate) disabled: SecondaryMap<EntityId, ()>,
72
73 extensions: HashMap<TypeId, Box<dyn AnyExtMap>>,
76 ext_names: HashMap<TypeId, String>,
78
79 resources: HashMap<TypeId, Box<dyn Any + Send + Sync>>,
82}
83
84impl World {
85 #[must_use]
87 pub fn new() -> Self {
88 Self {
89 alive: SlotMap::with_key(),
90 positions: SecondaryMap::new(),
91 prev_positions: SecondaryMap::new(),
92 velocities: SecondaryMap::new(),
93 elevators: SecondaryMap::new(),
94 stops: SecondaryMap::new(),
95 riders: SecondaryMap::new(),
96 routes: SecondaryMap::new(),
97 lines: SecondaryMap::new(),
98 patience: SecondaryMap::new(),
99 preferences: SecondaryMap::new(),
100 access_controls: SecondaryMap::new(),
101 #[cfg(feature = "energy")]
102 energy_profiles: SecondaryMap::new(),
103 #[cfg(feature = "energy")]
104 energy_metrics: SecondaryMap::new(),
105 service_modes: SecondaryMap::new(),
106 destination_queues: SecondaryMap::new(),
107 hall_calls: SecondaryMap::new(),
108 car_calls: SecondaryMap::new(),
109 disabled: SecondaryMap::new(),
110 extensions: HashMap::new(),
111 ext_names: HashMap::new(),
112 resources: HashMap::new(),
113 }
114 }
115
116 pub fn spawn(&mut self) -> EntityId {
118 self.alive.insert(())
119 }
120
121 pub fn despawn(&mut self, id: EntityId) {
128 if let Some(rider) = self.riders.get(id) {
130 let weight = rider.weight;
131 match rider.phase {
133 crate::components::RiderPhase::Boarding(elev)
134 | crate::components::RiderPhase::Riding(elev)
135 | crate::components::RiderPhase::Exiting(elev) => {
136 if let Some(car) = self.elevators.get_mut(elev) {
137 car.riders.retain(|r| *r != id);
138 car.current_load = (car.current_load - weight).max(0.0);
139 }
140 }
141 _ => {}
142 }
143 }
144
145 if let Some(car) = self.elevators.get(id) {
147 let rider_ids: Vec<EntityId> = car.riders.clone();
148 let elev_pos = self.positions.get(id).map(|p| p.value);
149 let nearest_stop = elev_pos.and_then(|p| self.find_nearest_stop(p));
150 for rid in rider_ids {
151 if let Some(rider) = self.riders.get_mut(rid) {
152 rider.phase = crate::components::RiderPhase::Waiting;
153 rider.current_stop = nearest_stop;
154 }
155 }
156 }
157
158 self.alive.remove(id);
159 self.positions.remove(id);
160 self.prev_positions.remove(id);
161 self.velocities.remove(id);
162 self.elevators.remove(id);
163 self.stops.remove(id);
164 self.riders.remove(id);
165 self.routes.remove(id);
166 self.lines.remove(id);
167 self.patience.remove(id);
168 self.preferences.remove(id);
169 self.access_controls.remove(id);
170 #[cfg(feature = "energy")]
171 self.energy_profiles.remove(id);
172 #[cfg(feature = "energy")]
173 self.energy_metrics.remove(id);
174 self.service_modes.remove(id);
175 self.destination_queues.remove(id);
176 self.disabled.remove(id);
177
178 for ext in self.extensions.values_mut() {
179 ext.remove(id);
180 }
181 }
182
183 #[must_use]
185 pub fn is_alive(&self, id: EntityId) -> bool {
186 self.alive.contains_key(id)
187 }
188
189 #[must_use]
191 pub fn entity_count(&self) -> usize {
192 self.alive.len()
193 }
194
195 pub(crate) fn alive_keys(&self) -> slotmap::basic::Keys<'_, EntityId, ()> {
197 self.alive.keys()
198 }
199
200 #[must_use]
204 pub fn position(&self, id: EntityId) -> Option<&Position> {
205 self.positions.get(id)
206 }
207
208 pub fn position_mut(&mut self, id: EntityId) -> Option<&mut Position> {
210 self.positions.get_mut(id)
211 }
212
213 pub fn set_position(&mut self, id: EntityId, pos: Position) {
215 self.positions.insert(id, pos);
216 }
217
218 #[must_use]
223 pub fn prev_position(&self, id: EntityId) -> Option<&Position> {
224 self.prev_positions.get(id)
225 }
226
227 pub(crate) fn snapshot_prev_positions(&mut self) {
233 self.prev_positions.clear();
234 for (id, pos) in &self.positions {
235 self.prev_positions.insert(id, *pos);
236 }
237 }
238
239 #[must_use]
243 pub fn velocity(&self, id: EntityId) -> Option<&Velocity> {
244 self.velocities.get(id)
245 }
246
247 pub fn velocity_mut(&mut self, id: EntityId) -> Option<&mut Velocity> {
249 self.velocities.get_mut(id)
250 }
251
252 pub fn set_velocity(&mut self, id: EntityId, vel: Velocity) {
254 self.velocities.insert(id, vel);
255 }
256
257 #[must_use]
261 pub fn elevator(&self, id: EntityId) -> Option<&Elevator> {
262 self.elevators.get(id)
263 }
264
265 pub fn elevator_mut(&mut self, id: EntityId) -> Option<&mut Elevator> {
267 self.elevators.get_mut(id)
268 }
269
270 pub fn set_elevator(&mut self, id: EntityId, elev: Elevator) {
272 self.elevators.insert(id, elev);
273 }
274
275 #[must_use]
279 pub fn rider(&self, id: EntityId) -> Option<&Rider> {
280 self.riders.get(id)
281 }
282
283 pub fn rider_mut(&mut self, id: EntityId) -> Option<&mut Rider> {
285 self.riders.get_mut(id)
286 }
287
288 pub fn set_rider(&mut self, id: EntityId, rider: Rider) {
290 self.riders.insert(id, rider);
291 }
292
293 #[must_use]
297 pub fn stop(&self, id: EntityId) -> Option<&Stop> {
298 self.stops.get(id)
299 }
300
301 pub fn stop_mut(&mut self, id: EntityId) -> Option<&mut Stop> {
303 self.stops.get_mut(id)
304 }
305
306 pub fn set_stop(&mut self, id: EntityId, stop: Stop) {
308 self.stops.insert(id, stop);
309 }
310
311 #[must_use]
315 pub fn route(&self, id: EntityId) -> Option<&Route> {
316 self.routes.get(id)
317 }
318
319 pub fn route_mut(&mut self, id: EntityId) -> Option<&mut Route> {
321 self.routes.get_mut(id)
322 }
323
324 pub fn set_route(&mut self, id: EntityId, route: Route) {
326 self.routes.insert(id, route);
327 }
328
329 #[must_use]
333 pub fn line(&self, id: EntityId) -> Option<&Line> {
334 self.lines.get(id)
335 }
336
337 pub fn line_mut(&mut self, id: EntityId) -> Option<&mut Line> {
339 self.lines.get_mut(id)
340 }
341
342 pub fn set_line(&mut self, id: EntityId, line: Line) {
344 self.lines.insert(id, line);
345 }
346
347 pub fn remove_line(&mut self, id: EntityId) -> Option<Line> {
349 self.lines.remove(id)
350 }
351
352 pub fn iter_lines(&self) -> impl Iterator<Item = (EntityId, &Line)> {
354 self.lines.iter()
355 }
356
357 #[must_use]
361 pub fn patience(&self, id: EntityId) -> Option<&Patience> {
362 self.patience.get(id)
363 }
364
365 pub fn patience_mut(&mut self, id: EntityId) -> Option<&mut Patience> {
367 self.patience.get_mut(id)
368 }
369
370 pub fn set_patience(&mut self, id: EntityId, patience: Patience) {
372 self.patience.insert(id, patience);
373 }
374
375 #[must_use]
379 pub fn preferences(&self, id: EntityId) -> Option<&Preferences> {
380 self.preferences.get(id)
381 }
382
383 pub fn set_preferences(&mut self, id: EntityId, prefs: Preferences) {
385 self.preferences.insert(id, prefs);
386 }
387
388 #[must_use]
392 pub fn access_control(&self, id: EntityId) -> Option<&AccessControl> {
393 self.access_controls.get(id)
394 }
395
396 pub fn access_control_mut(&mut self, id: EntityId) -> Option<&mut AccessControl> {
398 self.access_controls.get_mut(id)
399 }
400
401 pub fn set_access_control(&mut self, id: EntityId, ac: AccessControl) {
403 self.access_controls.insert(id, ac);
404 }
405
406 #[cfg(feature = "energy")]
409 #[must_use]
411 pub fn energy_profile(&self, id: EntityId) -> Option<&EnergyProfile> {
412 self.energy_profiles.get(id)
413 }
414
415 #[cfg(feature = "energy")]
416 #[must_use]
418 pub fn energy_metrics(&self, id: EntityId) -> Option<&EnergyMetrics> {
419 self.energy_metrics.get(id)
420 }
421
422 #[cfg(feature = "energy")]
423 pub fn energy_metrics_mut(&mut self, id: EntityId) -> Option<&mut EnergyMetrics> {
425 self.energy_metrics.get_mut(id)
426 }
427
428 #[cfg(feature = "energy")]
429 pub fn set_energy_profile(&mut self, id: EntityId, profile: EnergyProfile) {
431 self.energy_profiles.insert(id, profile);
432 }
433
434 #[cfg(feature = "energy")]
435 pub fn set_energy_metrics(&mut self, id: EntityId, metrics: EnergyMetrics) {
437 self.energy_metrics.insert(id, metrics);
438 }
439
440 #[must_use]
444 pub fn service_mode(&self, id: EntityId) -> Option<&ServiceMode> {
445 self.service_modes.get(id)
446 }
447
448 pub fn set_service_mode(&mut self, id: EntityId, mode: ServiceMode) {
450 self.service_modes.insert(id, mode);
451 }
452
453 #[must_use]
457 pub fn destination_queue(&self, id: EntityId) -> Option<&DestinationQueue> {
458 self.destination_queues.get(id)
459 }
460
461 pub(crate) fn destination_queue_mut(&mut self, id: EntityId) -> Option<&mut DestinationQueue> {
464 self.destination_queues.get_mut(id)
465 }
466
467 pub fn set_destination_queue(&mut self, id: EntityId, queue: DestinationQueue) {
469 self.destination_queues.insert(id, queue);
470 }
471
472 #[must_use]
480 pub fn stop_calls(&self, stop: EntityId) -> Option<&StopCalls> {
481 self.hall_calls.get(stop)
482 }
483
484 #[must_use]
486 pub fn hall_call(&self, stop: EntityId, direction: CallDirection) -> Option<&HallCall> {
487 self.hall_calls.get(stop).and_then(|c| c.get(direction))
488 }
489
490 #[allow(dead_code)]
492 pub(crate) fn hall_call_mut(
493 &mut self,
494 stop: EntityId,
495 direction: CallDirection,
496 ) -> Option<&mut HallCall> {
497 self.hall_calls
498 .get_mut(stop)
499 .and_then(|c| c.get_mut(direction))
500 }
501
502 #[allow(dead_code)]
505 pub(crate) fn set_hall_call(&mut self, call: HallCall) -> bool {
506 let Some(entry) = self.hall_calls.entry(call.stop) else {
507 return false;
508 };
509 let slot = entry.or_default();
510 match call.direction {
511 CallDirection::Up => slot.up = Some(call),
512 CallDirection::Down => slot.down = Some(call),
513 }
514 true
515 }
516
517 #[allow(dead_code)]
519 pub(crate) fn remove_hall_call(
520 &mut self,
521 stop: EntityId,
522 direction: CallDirection,
523 ) -> Option<HallCall> {
524 let entry = self.hall_calls.get_mut(stop)?;
525 match direction {
526 CallDirection::Up => entry.up.take(),
527 CallDirection::Down => entry.down.take(),
528 }
529 }
530
531 pub fn iter_hall_calls(&self) -> impl Iterator<Item = &HallCall> {
533 self.hall_calls.values().flat_map(StopCalls::iter)
534 }
535
536 #[allow(dead_code)]
538 pub(crate) fn iter_hall_calls_mut(&mut self) -> impl Iterator<Item = &mut HallCall> {
539 self.hall_calls.values_mut().flat_map(StopCalls::iter_mut)
540 }
541
542 #[must_use]
544 pub fn car_calls(&self, car: EntityId) -> &[CarCall] {
545 self.car_calls.get(car).map_or(&[], Vec::as_slice)
546 }
547
548 #[allow(dead_code)]
551 pub(crate) fn car_calls_mut(&mut self, car: EntityId) -> Option<&mut Vec<CarCall>> {
552 Some(self.car_calls.entry(car)?.or_default())
553 }
554
555 pub fn iter_elevators(&self) -> impl Iterator<Item = (EntityId, &Position, &Elevator)> {
559 self.elevators
560 .iter()
561 .filter_map(|(id, car)| self.positions.get(id).map(|pos| (id, pos, car)))
562 }
563
564 #[must_use]
566 pub fn elevator_ids(&self) -> Vec<EntityId> {
567 self.elevators.keys().collect()
568 }
569
570 pub fn elevator_ids_into(&self, buf: &mut Vec<EntityId>) {
572 buf.clear();
573 buf.extend(self.elevators.keys());
574 }
575
576 pub fn iter_riders(&self) -> impl Iterator<Item = (EntityId, &Rider)> {
578 self.riders.iter()
579 }
580
581 pub fn iter_riders_mut(&mut self) -> impl Iterator<Item = (EntityId, &mut Rider)> {
583 self.riders.iter_mut()
584 }
585
586 #[must_use]
588 pub fn rider_ids(&self) -> Vec<EntityId> {
589 self.riders.keys().collect()
590 }
591
592 pub fn iter_stops(&self) -> impl Iterator<Item = (EntityId, &Stop)> {
594 self.stops.iter()
595 }
596
597 #[must_use]
599 pub fn stop_ids(&self) -> Vec<EntityId> {
600 self.stops.keys().collect()
601 }
602
603 pub fn iter_idle_elevators(&self) -> impl Iterator<Item = (EntityId, &Position, &Elevator)> {
605 use crate::components::ElevatorPhase;
606 self.iter_elevators()
607 .filter(|(id, _, car)| car.phase == ElevatorPhase::Idle && !self.is_disabled(*id))
608 }
609
610 pub fn iter_moving_elevators(&self) -> impl Iterator<Item = (EntityId, &Position, &Elevator)> {
614 self.iter_elevators()
615 .filter(|(id, _, car)| car.phase.is_moving() && !self.is_disabled(*id))
616 }
617
618 pub fn iter_waiting_riders(&self) -> impl Iterator<Item = (EntityId, &Rider)> {
620 use crate::components::RiderPhase;
621 self.iter_riders()
622 .filter(|(id, r)| r.phase == RiderPhase::Waiting && !self.is_disabled(*id))
623 }
624
625 #[must_use]
627 pub fn find_stop_at_position(&self, position: f64) -> Option<EntityId> {
628 const EPSILON: f64 = 1e-6;
629 self.stops.iter().find_map(|(id, stop)| {
630 if (stop.position - position).abs() < EPSILON {
631 Some(id)
632 } else {
633 None
634 }
635 })
636 }
637
638 #[must_use]
644 pub fn find_nearest_stop(&self, position: f64) -> Option<EntityId> {
645 self.stops
646 .iter()
647 .min_by(|(_, a), (_, b)| {
648 (a.position - position)
649 .abs()
650 .total_cmp(&(b.position - position).abs())
651 })
652 .map(|(id, _)| id)
653 }
654
655 #[must_use]
657 pub fn stop_position(&self, id: EntityId) -> Option<f64> {
658 self.stops.get(id).map(|s| s.position)
659 }
660
661 pub fn insert_ext<T: 'static + Send + Sync + serde::Serialize + serde::de::DeserializeOwned>(
682 &mut self,
683 id: EntityId,
684 value: T,
685 name: &str,
686 ) {
687 let type_id = TypeId::of::<T>();
688 let map = self
689 .extensions
690 .entry(type_id)
691 .or_insert_with(|| Box::new(SecondaryMap::<EntityId, T>::new()));
692 if let Some(m) = map.as_any_mut().downcast_mut::<SecondaryMap<EntityId, T>>() {
693 m.insert(id, value);
694 }
695 self.ext_names.insert(type_id, name.to_owned());
696 }
697
698 #[must_use]
700 pub fn get_ext<T: 'static + Send + Sync + Clone>(&self, id: EntityId) -> Option<T> {
701 self.ext_map::<T>()?.get(id).cloned()
702 }
703
704 pub fn get_ext_mut<T: 'static + Send + Sync>(&mut self, id: EntityId) -> Option<&mut T> {
706 self.ext_map_mut::<T>()?.get_mut(id)
707 }
708
709 pub fn remove_ext<T: 'static + Send + Sync>(&mut self, id: EntityId) -> Option<T> {
711 self.ext_map_mut::<T>()?.remove(id)
712 }
713
714 pub(crate) fn ext_map<T: 'static + Send + Sync>(&self) -> Option<&SecondaryMap<EntityId, T>> {
716 self.extensions
717 .get(&TypeId::of::<T>())?
718 .as_any()
719 .downcast_ref::<SecondaryMap<EntityId, T>>()
720 }
721
722 fn ext_map_mut<T: 'static + Send + Sync>(&mut self) -> Option<&mut SecondaryMap<EntityId, T>> {
724 self.extensions
725 .get_mut(&TypeId::of::<T>())?
726 .as_any_mut()
727 .downcast_mut::<SecondaryMap<EntityId, T>>()
728 }
729
730 pub(crate) fn serialize_extensions(&self) -> HashMap<String, HashMap<EntityId, String>> {
733 let mut result = HashMap::new();
734 for (type_id, map) in &self.extensions {
735 if let Some(name) = self.ext_names.get(type_id) {
736 result.insert(name.clone(), map.serialize_entries());
737 }
738 }
739 result
740 }
741
742 pub(crate) fn deserialize_extensions(
745 &mut self,
746 data: &HashMap<String, HashMap<EntityId, String>>,
747 ) {
748 for (name, entries) in data {
749 if let Some((&type_id, _)) = self.ext_names.iter().find(|(_, n)| *n == name)
751 && let Some(map) = self.extensions.get_mut(&type_id)
752 {
753 map.deserialize_entries(entries);
754 }
755 }
756 }
757
758 pub fn register_ext<
763 T: 'static + Send + Sync + serde::Serialize + serde::de::DeserializeOwned,
764 >(
765 &mut self,
766 name: &str,
767 ) {
768 let type_id = TypeId::of::<T>();
769 self.extensions
770 .entry(type_id)
771 .or_insert_with(|| Box::new(SecondaryMap::<EntityId, T>::new()));
772 self.ext_names.insert(type_id, name.to_owned());
773 }
774
775 pub fn disable(&mut self, id: EntityId) {
779 self.disabled.insert(id, ());
780 }
781
782 pub fn enable(&mut self, id: EntityId) {
784 self.disabled.remove(id);
785 }
786
787 #[must_use]
789 pub fn is_disabled(&self, id: EntityId) -> bool {
790 self.disabled.contains_key(id)
791 }
792
793 pub fn insert_resource<T: 'static + Send + Sync>(&mut self, value: T) {
811 self.resources.insert(TypeId::of::<T>(), Box::new(value));
812 }
813
814 #[must_use]
816 pub fn resource<T: 'static + Send + Sync>(&self) -> Option<&T> {
817 self.resources.get(&TypeId::of::<T>())?.downcast_ref()
818 }
819
820 pub fn resource_mut<T: 'static + Send + Sync>(&mut self) -> Option<&mut T> {
822 self.resources.get_mut(&TypeId::of::<T>())?.downcast_mut()
823 }
824
825 pub fn remove_resource<T: 'static + Send + Sync>(&mut self) -> Option<T> {
827 self.resources
828 .remove(&TypeId::of::<T>())
829 .and_then(|b| b.downcast().ok())
830 .map(|b| *b)
831 }
832
833 #[must_use]
849 pub const fn query<Q: crate::query::WorldQuery>(&self) -> crate::query::QueryBuilder<'_, Q> {
850 crate::query::QueryBuilder::new(self)
851 }
852
853 pub fn query_ext_mut<T: 'static + Send + Sync>(&mut self) -> crate::query::ExtQueryMut<'_, T> {
867 crate::query::ExtQueryMut::new(self)
868 }
869}
870
871impl Default for World {
872 fn default() -> Self {
873 Self::new()
874 }
875}
876
877pub(crate) struct SortedStops(pub(crate) Vec<(f64, EntityId)>);
882
883#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)]
889pub struct StopCalls {
890 pub up: Option<HallCall>,
892 pub down: Option<HallCall>,
894}
895
896impl StopCalls {
897 #[must_use]
899 pub const fn get(&self, direction: CallDirection) -> Option<&HallCall> {
900 match direction {
901 CallDirection::Up => self.up.as_ref(),
902 CallDirection::Down => self.down.as_ref(),
903 }
904 }
905
906 pub const fn get_mut(&mut self, direction: CallDirection) -> Option<&mut HallCall> {
908 match direction {
909 CallDirection::Up => self.up.as_mut(),
910 CallDirection::Down => self.down.as_mut(),
911 }
912 }
913
914 pub fn iter(&self) -> impl Iterator<Item = &HallCall> {
916 self.up.iter().chain(self.down.iter())
917 }
918
919 pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut HallCall> {
921 self.up.iter_mut().chain(self.down.iter_mut())
922 }
923}