1use std::any::{Any, TypeId};
4use std::collections::HashMap;
5
6use slotmap::{SecondaryMap, SlotMap};
7
8use crate::components::{
9 AccessControl, DestinationQueue, Elevator, Line, Patience, Position, Preferences, Rider, Route,
10 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
66 pub(crate) disabled: SecondaryMap<EntityId, ()>,
68
69 extensions: HashMap<TypeId, Box<dyn AnyExtMap>>,
72 ext_names: HashMap<TypeId, String>,
74
75 resources: HashMap<TypeId, Box<dyn Any + Send + Sync>>,
78}
79
80impl World {
81 #[must_use]
83 pub fn new() -> Self {
84 Self {
85 alive: SlotMap::with_key(),
86 positions: SecondaryMap::new(),
87 prev_positions: SecondaryMap::new(),
88 velocities: SecondaryMap::new(),
89 elevators: SecondaryMap::new(),
90 stops: SecondaryMap::new(),
91 riders: SecondaryMap::new(),
92 routes: SecondaryMap::new(),
93 lines: SecondaryMap::new(),
94 patience: SecondaryMap::new(),
95 preferences: SecondaryMap::new(),
96 access_controls: SecondaryMap::new(),
97 #[cfg(feature = "energy")]
98 energy_profiles: SecondaryMap::new(),
99 #[cfg(feature = "energy")]
100 energy_metrics: SecondaryMap::new(),
101 service_modes: SecondaryMap::new(),
102 destination_queues: SecondaryMap::new(),
103 disabled: SecondaryMap::new(),
104 extensions: HashMap::new(),
105 ext_names: HashMap::new(),
106 resources: HashMap::new(),
107 }
108 }
109
110 pub fn spawn(&mut self) -> EntityId {
112 self.alive.insert(())
113 }
114
115 pub fn despawn(&mut self, id: EntityId) {
122 if let Some(rider) = self.riders.get(id) {
124 let weight = rider.weight;
125 match rider.phase {
127 crate::components::RiderPhase::Boarding(elev)
128 | crate::components::RiderPhase::Riding(elev)
129 | crate::components::RiderPhase::Exiting(elev) => {
130 if let Some(car) = self.elevators.get_mut(elev) {
131 car.riders.retain(|r| *r != id);
132 car.current_load = (car.current_load - weight).max(0.0);
133 }
134 }
135 _ => {}
136 }
137 }
138
139 if let Some(car) = self.elevators.get(id) {
141 let rider_ids: Vec<EntityId> = car.riders.clone();
142 let elev_pos = self.positions.get(id).map(|p| p.value);
143 let nearest_stop = elev_pos.and_then(|p| self.find_nearest_stop(p));
144 for rid in rider_ids {
145 if let Some(rider) = self.riders.get_mut(rid) {
146 rider.phase = crate::components::RiderPhase::Waiting;
147 rider.current_stop = nearest_stop;
148 }
149 }
150 }
151
152 self.alive.remove(id);
153 self.positions.remove(id);
154 self.prev_positions.remove(id);
155 self.velocities.remove(id);
156 self.elevators.remove(id);
157 self.stops.remove(id);
158 self.riders.remove(id);
159 self.routes.remove(id);
160 self.lines.remove(id);
161 self.patience.remove(id);
162 self.preferences.remove(id);
163 self.access_controls.remove(id);
164 #[cfg(feature = "energy")]
165 self.energy_profiles.remove(id);
166 #[cfg(feature = "energy")]
167 self.energy_metrics.remove(id);
168 self.service_modes.remove(id);
169 self.destination_queues.remove(id);
170 self.disabled.remove(id);
171
172 for ext in self.extensions.values_mut() {
173 ext.remove(id);
174 }
175 }
176
177 #[must_use]
179 pub fn is_alive(&self, id: EntityId) -> bool {
180 self.alive.contains_key(id)
181 }
182
183 #[must_use]
185 pub fn entity_count(&self) -> usize {
186 self.alive.len()
187 }
188
189 pub(crate) fn alive_keys(&self) -> slotmap::basic::Keys<'_, EntityId, ()> {
191 self.alive.keys()
192 }
193
194 #[must_use]
198 pub fn position(&self, id: EntityId) -> Option<&Position> {
199 self.positions.get(id)
200 }
201
202 pub fn position_mut(&mut self, id: EntityId) -> Option<&mut Position> {
204 self.positions.get_mut(id)
205 }
206
207 pub fn set_position(&mut self, id: EntityId, pos: Position) {
209 self.positions.insert(id, pos);
210 }
211
212 #[must_use]
217 pub fn prev_position(&self, id: EntityId) -> Option<&Position> {
218 self.prev_positions.get(id)
219 }
220
221 pub(crate) fn snapshot_prev_positions(&mut self) {
227 self.prev_positions.clear();
228 for (id, pos) in &self.positions {
229 self.prev_positions.insert(id, *pos);
230 }
231 }
232
233 #[must_use]
237 pub fn velocity(&self, id: EntityId) -> Option<&Velocity> {
238 self.velocities.get(id)
239 }
240
241 pub fn velocity_mut(&mut self, id: EntityId) -> Option<&mut Velocity> {
243 self.velocities.get_mut(id)
244 }
245
246 pub fn set_velocity(&mut self, id: EntityId, vel: Velocity) {
248 self.velocities.insert(id, vel);
249 }
250
251 #[must_use]
255 pub fn elevator(&self, id: EntityId) -> Option<&Elevator> {
256 self.elevators.get(id)
257 }
258
259 pub fn elevator_mut(&mut self, id: EntityId) -> Option<&mut Elevator> {
261 self.elevators.get_mut(id)
262 }
263
264 pub fn set_elevator(&mut self, id: EntityId, elev: Elevator) {
266 self.elevators.insert(id, elev);
267 }
268
269 #[must_use]
273 pub fn rider(&self, id: EntityId) -> Option<&Rider> {
274 self.riders.get(id)
275 }
276
277 pub fn rider_mut(&mut self, id: EntityId) -> Option<&mut Rider> {
279 self.riders.get_mut(id)
280 }
281
282 pub fn set_rider(&mut self, id: EntityId, rider: Rider) {
284 self.riders.insert(id, rider);
285 }
286
287 #[must_use]
291 pub fn stop(&self, id: EntityId) -> Option<&Stop> {
292 self.stops.get(id)
293 }
294
295 pub fn stop_mut(&mut self, id: EntityId) -> Option<&mut Stop> {
297 self.stops.get_mut(id)
298 }
299
300 pub fn set_stop(&mut self, id: EntityId, stop: Stop) {
302 self.stops.insert(id, stop);
303 }
304
305 #[must_use]
309 pub fn route(&self, id: EntityId) -> Option<&Route> {
310 self.routes.get(id)
311 }
312
313 pub fn route_mut(&mut self, id: EntityId) -> Option<&mut Route> {
315 self.routes.get_mut(id)
316 }
317
318 pub fn set_route(&mut self, id: EntityId, route: Route) {
320 self.routes.insert(id, route);
321 }
322
323 #[must_use]
327 pub fn line(&self, id: EntityId) -> Option<&Line> {
328 self.lines.get(id)
329 }
330
331 pub fn line_mut(&mut self, id: EntityId) -> Option<&mut Line> {
333 self.lines.get_mut(id)
334 }
335
336 pub fn set_line(&mut self, id: EntityId, line: Line) {
338 self.lines.insert(id, line);
339 }
340
341 pub fn remove_line(&mut self, id: EntityId) -> Option<Line> {
343 self.lines.remove(id)
344 }
345
346 pub fn iter_lines(&self) -> impl Iterator<Item = (EntityId, &Line)> {
348 self.lines.iter()
349 }
350
351 #[must_use]
355 pub fn patience(&self, id: EntityId) -> Option<&Patience> {
356 self.patience.get(id)
357 }
358
359 pub fn patience_mut(&mut self, id: EntityId) -> Option<&mut Patience> {
361 self.patience.get_mut(id)
362 }
363
364 pub fn set_patience(&mut self, id: EntityId, patience: Patience) {
366 self.patience.insert(id, patience);
367 }
368
369 #[must_use]
373 pub fn preferences(&self, id: EntityId) -> Option<&Preferences> {
374 self.preferences.get(id)
375 }
376
377 pub fn set_preferences(&mut self, id: EntityId, prefs: Preferences) {
379 self.preferences.insert(id, prefs);
380 }
381
382 #[must_use]
386 pub fn access_control(&self, id: EntityId) -> Option<&AccessControl> {
387 self.access_controls.get(id)
388 }
389
390 pub fn access_control_mut(&mut self, id: EntityId) -> Option<&mut AccessControl> {
392 self.access_controls.get_mut(id)
393 }
394
395 pub fn set_access_control(&mut self, id: EntityId, ac: AccessControl) {
397 self.access_controls.insert(id, ac);
398 }
399
400 #[cfg(feature = "energy")]
403 #[must_use]
405 pub fn energy_profile(&self, id: EntityId) -> Option<&EnergyProfile> {
406 self.energy_profiles.get(id)
407 }
408
409 #[cfg(feature = "energy")]
410 #[must_use]
412 pub fn energy_metrics(&self, id: EntityId) -> Option<&EnergyMetrics> {
413 self.energy_metrics.get(id)
414 }
415
416 #[cfg(feature = "energy")]
417 pub fn energy_metrics_mut(&mut self, id: EntityId) -> Option<&mut EnergyMetrics> {
419 self.energy_metrics.get_mut(id)
420 }
421
422 #[cfg(feature = "energy")]
423 pub fn set_energy_profile(&mut self, id: EntityId, profile: EnergyProfile) {
425 self.energy_profiles.insert(id, profile);
426 }
427
428 #[cfg(feature = "energy")]
429 pub fn set_energy_metrics(&mut self, id: EntityId, metrics: EnergyMetrics) {
431 self.energy_metrics.insert(id, metrics);
432 }
433
434 #[must_use]
438 pub fn service_mode(&self, id: EntityId) -> Option<&ServiceMode> {
439 self.service_modes.get(id)
440 }
441
442 pub fn set_service_mode(&mut self, id: EntityId, mode: ServiceMode) {
444 self.service_modes.insert(id, mode);
445 }
446
447 #[must_use]
451 pub fn destination_queue(&self, id: EntityId) -> Option<&DestinationQueue> {
452 self.destination_queues.get(id)
453 }
454
455 pub(crate) fn destination_queue_mut(&mut self, id: EntityId) -> Option<&mut DestinationQueue> {
458 self.destination_queues.get_mut(id)
459 }
460
461 pub fn set_destination_queue(&mut self, id: EntityId, queue: DestinationQueue) {
463 self.destination_queues.insert(id, queue);
464 }
465
466 pub fn iter_elevators(&self) -> impl Iterator<Item = (EntityId, &Position, &Elevator)> {
470 self.elevators
471 .iter()
472 .filter_map(|(id, car)| self.positions.get(id).map(|pos| (id, pos, car)))
473 }
474
475 #[must_use]
477 pub fn elevator_ids(&self) -> Vec<EntityId> {
478 self.elevators.keys().collect()
479 }
480
481 pub fn elevator_ids_into(&self, buf: &mut Vec<EntityId>) {
483 buf.clear();
484 buf.extend(self.elevators.keys());
485 }
486
487 pub fn iter_riders(&self) -> impl Iterator<Item = (EntityId, &Rider)> {
489 self.riders.iter()
490 }
491
492 pub fn iter_riders_mut(&mut self) -> impl Iterator<Item = (EntityId, &mut Rider)> {
494 self.riders.iter_mut()
495 }
496
497 #[must_use]
499 pub fn rider_ids(&self) -> Vec<EntityId> {
500 self.riders.keys().collect()
501 }
502
503 pub fn iter_stops(&self) -> impl Iterator<Item = (EntityId, &Stop)> {
505 self.stops.iter()
506 }
507
508 #[must_use]
510 pub fn stop_ids(&self) -> Vec<EntityId> {
511 self.stops.keys().collect()
512 }
513
514 pub fn iter_idle_elevators(&self) -> impl Iterator<Item = (EntityId, &Position, &Elevator)> {
516 use crate::components::ElevatorPhase;
517 self.iter_elevators()
518 .filter(|(id, _, car)| car.phase == ElevatorPhase::Idle && !self.is_disabled(*id))
519 }
520
521 pub fn iter_moving_elevators(&self) -> impl Iterator<Item = (EntityId, &Position, &Elevator)> {
525 self.iter_elevators()
526 .filter(|(id, _, car)| car.phase.is_moving() && !self.is_disabled(*id))
527 }
528
529 pub fn iter_waiting_riders(&self) -> impl Iterator<Item = (EntityId, &Rider)> {
531 use crate::components::RiderPhase;
532 self.iter_riders()
533 .filter(|(id, r)| r.phase == RiderPhase::Waiting && !self.is_disabled(*id))
534 }
535
536 #[must_use]
538 pub fn find_stop_at_position(&self, position: f64) -> Option<EntityId> {
539 const EPSILON: f64 = 1e-6;
540 self.stops.iter().find_map(|(id, stop)| {
541 if (stop.position - position).abs() < EPSILON {
542 Some(id)
543 } else {
544 None
545 }
546 })
547 }
548
549 #[must_use]
555 pub fn find_nearest_stop(&self, position: f64) -> Option<EntityId> {
556 self.stops
557 .iter()
558 .min_by(|(_, a), (_, b)| {
559 (a.position - position)
560 .abs()
561 .total_cmp(&(b.position - position).abs())
562 })
563 .map(|(id, _)| id)
564 }
565
566 #[must_use]
568 pub fn stop_position(&self, id: EntityId) -> Option<f64> {
569 self.stops.get(id).map(|s| s.position)
570 }
571
572 pub fn insert_ext<T: 'static + Send + Sync + serde::Serialize + serde::de::DeserializeOwned>(
593 &mut self,
594 id: EntityId,
595 value: T,
596 name: &str,
597 ) {
598 let type_id = TypeId::of::<T>();
599 let map = self
600 .extensions
601 .entry(type_id)
602 .or_insert_with(|| Box::new(SecondaryMap::<EntityId, T>::new()));
603 if let Some(m) = map.as_any_mut().downcast_mut::<SecondaryMap<EntityId, T>>() {
604 m.insert(id, value);
605 }
606 self.ext_names.insert(type_id, name.to_owned());
607 }
608
609 #[must_use]
611 pub fn get_ext<T: 'static + Send + Sync + Clone>(&self, id: EntityId) -> Option<T> {
612 self.ext_map::<T>()?.get(id).cloned()
613 }
614
615 pub fn get_ext_mut<T: 'static + Send + Sync>(&mut self, id: EntityId) -> Option<&mut T> {
617 self.ext_map_mut::<T>()?.get_mut(id)
618 }
619
620 pub fn remove_ext<T: 'static + Send + Sync>(&mut self, id: EntityId) -> Option<T> {
622 self.ext_map_mut::<T>()?.remove(id)
623 }
624
625 pub(crate) fn ext_map<T: 'static + Send + Sync>(&self) -> Option<&SecondaryMap<EntityId, T>> {
627 self.extensions
628 .get(&TypeId::of::<T>())?
629 .as_any()
630 .downcast_ref::<SecondaryMap<EntityId, T>>()
631 }
632
633 fn ext_map_mut<T: 'static + Send + Sync>(&mut self) -> Option<&mut SecondaryMap<EntityId, T>> {
635 self.extensions
636 .get_mut(&TypeId::of::<T>())?
637 .as_any_mut()
638 .downcast_mut::<SecondaryMap<EntityId, T>>()
639 }
640
641 pub(crate) fn serialize_extensions(&self) -> HashMap<String, HashMap<EntityId, String>> {
644 let mut result = HashMap::new();
645 for (type_id, map) in &self.extensions {
646 if let Some(name) = self.ext_names.get(type_id) {
647 result.insert(name.clone(), map.serialize_entries());
648 }
649 }
650 result
651 }
652
653 pub(crate) fn deserialize_extensions(
656 &mut self,
657 data: &HashMap<String, HashMap<EntityId, String>>,
658 ) {
659 for (name, entries) in data {
660 if let Some((&type_id, _)) = self.ext_names.iter().find(|(_, n)| *n == name)
662 && let Some(map) = self.extensions.get_mut(&type_id)
663 {
664 map.deserialize_entries(entries);
665 }
666 }
667 }
668
669 pub fn register_ext<
674 T: 'static + Send + Sync + serde::Serialize + serde::de::DeserializeOwned,
675 >(
676 &mut self,
677 name: &str,
678 ) {
679 let type_id = TypeId::of::<T>();
680 self.extensions
681 .entry(type_id)
682 .or_insert_with(|| Box::new(SecondaryMap::<EntityId, T>::new()));
683 self.ext_names.insert(type_id, name.to_owned());
684 }
685
686 pub fn disable(&mut self, id: EntityId) {
690 self.disabled.insert(id, ());
691 }
692
693 pub fn enable(&mut self, id: EntityId) {
695 self.disabled.remove(id);
696 }
697
698 #[must_use]
700 pub fn is_disabled(&self, id: EntityId) -> bool {
701 self.disabled.contains_key(id)
702 }
703
704 pub fn insert_resource<T: 'static + Send + Sync>(&mut self, value: T) {
722 self.resources.insert(TypeId::of::<T>(), Box::new(value));
723 }
724
725 #[must_use]
727 pub fn resource<T: 'static + Send + Sync>(&self) -> Option<&T> {
728 self.resources.get(&TypeId::of::<T>())?.downcast_ref()
729 }
730
731 pub fn resource_mut<T: 'static + Send + Sync>(&mut self) -> Option<&mut T> {
733 self.resources.get_mut(&TypeId::of::<T>())?.downcast_mut()
734 }
735
736 pub fn remove_resource<T: 'static + Send + Sync>(&mut self) -> Option<T> {
738 self.resources
739 .remove(&TypeId::of::<T>())
740 .and_then(|b| b.downcast().ok())
741 .map(|b| *b)
742 }
743
744 #[must_use]
760 pub const fn query<Q: crate::query::WorldQuery>(&self) -> crate::query::QueryBuilder<'_, Q> {
761 crate::query::QueryBuilder::new(self)
762 }
763
764 pub fn query_ext_mut<T: 'static + Send + Sync>(&mut self) -> crate::query::ExtQueryMut<'_, T> {
778 crate::query::ExtQueryMut::new(self)
779 }
780}
781
782impl Default for World {
783 fn default() -> Self {
784 Self::new()
785 }
786}
787
788pub(crate) struct SortedStops(pub(crate) Vec<(f64, EntityId)>);