1use std::any::{Any, TypeId};
4use std::collections::{BTreeMap, 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(crate) fn set_rider(&mut self, id: EntityId, rider: Rider) {
350 self.riders.insert(id, rider);
351 }
352
353 #[must_use]
357 pub fn stop(&self, id: EntityId) -> Option<&Stop> {
358 self.stops.get(id)
359 }
360
361 pub fn stop_mut(&mut self, id: EntityId) -> Option<&mut Stop> {
363 self.stops.get_mut(id)
364 }
365
366 pub fn set_stop(&mut self, id: EntityId, stop: Stop) {
368 self.stops.insert(id, stop);
369 }
370
371 #[must_use]
375 pub fn route(&self, id: EntityId) -> Option<&Route> {
376 self.routes.get(id)
377 }
378
379 pub fn route_mut(&mut self, id: EntityId) -> Option<&mut Route> {
381 self.routes.get_mut(id)
382 }
383
384 pub fn set_route(&mut self, id: EntityId, route: Route) {
386 self.routes.insert(id, route);
387 }
388
389 #[must_use]
393 pub fn line(&self, id: EntityId) -> Option<&Line> {
394 self.lines.get(id)
395 }
396
397 pub fn line_mut(&mut self, id: EntityId) -> Option<&mut Line> {
399 self.lines.get_mut(id)
400 }
401
402 pub fn set_line(&mut self, id: EntityId, line: Line) {
404 self.lines.insert(id, line);
405 }
406
407 pub fn remove_line(&mut self, id: EntityId) -> Option<Line> {
409 self.lines.remove(id)
410 }
411
412 pub fn iter_lines(&self) -> impl Iterator<Item = (EntityId, &Line)> {
414 self.lines.iter()
415 }
416
417 #[must_use]
421 pub fn patience(&self, id: EntityId) -> Option<&Patience> {
422 self.patience.get(id)
423 }
424
425 pub fn patience_mut(&mut self, id: EntityId) -> Option<&mut Patience> {
427 self.patience.get_mut(id)
428 }
429
430 pub fn set_patience(&mut self, id: EntityId, patience: Patience) {
432 self.patience.insert(id, patience);
433 }
434
435 #[must_use]
439 pub fn preferences(&self, id: EntityId) -> Option<&Preferences> {
440 self.preferences.get(id)
441 }
442
443 pub fn set_preferences(&mut self, id: EntityId, prefs: Preferences) {
445 self.preferences.insert(id, prefs);
446 }
447
448 #[must_use]
452 pub fn access_control(&self, id: EntityId) -> Option<&AccessControl> {
453 self.access_controls.get(id)
454 }
455
456 pub fn access_control_mut(&mut self, id: EntityId) -> Option<&mut AccessControl> {
458 self.access_controls.get_mut(id)
459 }
460
461 pub fn set_access_control(&mut self, id: EntityId, ac: AccessControl) {
463 self.access_controls.insert(id, ac);
464 }
465
466 #[cfg(feature = "energy")]
469 #[must_use]
471 pub fn energy_profile(&self, id: EntityId) -> Option<&EnergyProfile> {
472 self.energy_profiles.get(id)
473 }
474
475 #[cfg(feature = "energy")]
476 #[must_use]
478 pub fn energy_metrics(&self, id: EntityId) -> Option<&EnergyMetrics> {
479 self.energy_metrics.get(id)
480 }
481
482 #[cfg(feature = "energy")]
483 pub fn energy_metrics_mut(&mut self, id: EntityId) -> Option<&mut EnergyMetrics> {
485 self.energy_metrics.get_mut(id)
486 }
487
488 #[cfg(feature = "energy")]
489 pub fn set_energy_profile(&mut self, id: EntityId, profile: EnergyProfile) {
491 self.energy_profiles.insert(id, profile);
492 }
493
494 #[cfg(feature = "energy")]
495 pub fn set_energy_metrics(&mut self, id: EntityId, metrics: EnergyMetrics) {
497 self.energy_metrics.insert(id, metrics);
498 }
499
500 #[must_use]
504 pub fn service_mode(&self, id: EntityId) -> Option<&ServiceMode> {
505 self.service_modes.get(id)
506 }
507
508 pub fn set_service_mode(&mut self, id: EntityId, mode: ServiceMode) {
510 self.service_modes.insert(id, mode);
511 }
512
513 #[must_use]
517 pub fn destination_queue(&self, id: EntityId) -> Option<&DestinationQueue> {
518 self.destination_queues.get(id)
519 }
520
521 pub(crate) fn destination_queue_mut(&mut self, id: EntityId) -> Option<&mut DestinationQueue> {
524 self.destination_queues.get_mut(id)
525 }
526
527 pub fn set_destination_queue(&mut self, id: EntityId, queue: DestinationQueue) {
529 self.destination_queues.insert(id, queue);
530 }
531
532 #[must_use]
540 pub fn stop_calls(&self, stop: EntityId) -> Option<&StopCalls> {
541 self.hall_calls.get(stop)
542 }
543
544 #[must_use]
546 pub fn hall_call(&self, stop: EntityId, direction: CallDirection) -> Option<&HallCall> {
547 self.hall_calls.get(stop).and_then(|c| c.get(direction))
548 }
549
550 #[allow(dead_code)]
552 pub(crate) fn hall_call_mut(
553 &mut self,
554 stop: EntityId,
555 direction: CallDirection,
556 ) -> Option<&mut HallCall> {
557 self.hall_calls
558 .get_mut(stop)
559 .and_then(|c| c.get_mut(direction))
560 }
561
562 #[allow(dead_code)]
565 pub(crate) fn set_hall_call(&mut self, call: HallCall) -> bool {
566 let Some(entry) = self.hall_calls.entry(call.stop) else {
567 return false;
568 };
569 let slot = entry.or_default();
570 match call.direction {
571 CallDirection::Up => slot.up = Some(call),
572 CallDirection::Down => slot.down = Some(call),
573 }
574 true
575 }
576
577 #[allow(dead_code)]
579 pub(crate) fn remove_hall_call(
580 &mut self,
581 stop: EntityId,
582 direction: CallDirection,
583 ) -> Option<HallCall> {
584 let entry = self.hall_calls.get_mut(stop)?;
585 match direction {
586 CallDirection::Up => entry.up.take(),
587 CallDirection::Down => entry.down.take(),
588 }
589 }
590
591 pub fn iter_hall_calls(&self) -> impl Iterator<Item = &HallCall> {
593 self.hall_calls.values().flat_map(StopCalls::iter)
594 }
595
596 #[allow(dead_code)]
598 pub(crate) fn iter_hall_calls_mut(&mut self) -> impl Iterator<Item = &mut HallCall> {
599 self.hall_calls.values_mut().flat_map(StopCalls::iter_mut)
600 }
601
602 #[must_use]
604 pub fn car_calls(&self, car: EntityId) -> &[CarCall] {
605 self.car_calls.get(car).map_or(&[], Vec::as_slice)
606 }
607
608 #[allow(dead_code)]
611 pub(crate) fn car_calls_mut(&mut self, car: EntityId) -> Option<&mut Vec<CarCall>> {
612 Some(self.car_calls.entry(car)?.or_default())
613 }
614
615 pub(crate) fn scrub_rider_from_pending_calls(&mut self, rider: EntityId) {
625 for call in self.iter_hall_calls_mut() {
626 call.pending_riders.retain(|r| *r != rider);
627 }
628 for calls in self.car_calls.values_mut() {
629 for c in calls.iter_mut() {
630 c.pending_riders.retain(|r| *r != rider);
631 }
632 calls.retain(|c| !c.pending_riders.is_empty());
633 }
634 }
635
636 pub fn iter_elevators(&self) -> impl Iterator<Item = (EntityId, &Position, &Elevator)> {
640 self.elevators
641 .iter()
642 .filter_map(|(id, car)| self.positions.get(id).map(|pos| (id, pos, car)))
643 }
644
645 #[must_use]
647 pub fn elevator_ids(&self) -> Vec<EntityId> {
648 self.elevators.keys().collect()
649 }
650
651 pub fn elevator_ids_into(&self, buf: &mut Vec<EntityId>) {
653 buf.clear();
654 buf.extend(self.elevators.keys());
655 }
656
657 pub fn iter_riders(&self) -> impl Iterator<Item = (EntityId, &Rider)> {
659 self.riders.iter()
660 }
661
662 pub fn iter_riders_mut(&mut self) -> impl Iterator<Item = (EntityId, &mut Rider)> {
664 self.riders.iter_mut()
665 }
666
667 #[must_use]
669 pub fn rider_ids(&self) -> Vec<EntityId> {
670 self.riders.keys().collect()
671 }
672
673 pub fn iter_stops(&self) -> impl Iterator<Item = (EntityId, &Stop)> {
675 self.stops.iter()
676 }
677
678 #[must_use]
680 pub fn stop_ids(&self) -> Vec<EntityId> {
681 self.stops.keys().collect()
682 }
683
684 pub fn iter_idle_elevators(&self) -> impl Iterator<Item = (EntityId, &Position, &Elevator)> {
686 use crate::components::ElevatorPhase;
687 self.iter_elevators()
688 .filter(|(id, _, car)| car.phase == ElevatorPhase::Idle && !self.is_disabled(*id))
689 }
690
691 pub fn iter_moving_elevators(&self) -> impl Iterator<Item = (EntityId, &Position, &Elevator)> {
695 self.iter_elevators()
696 .filter(|(id, _, car)| car.phase.is_moving() && !self.is_disabled(*id))
697 }
698
699 pub fn iter_waiting_riders(&self) -> impl Iterator<Item = (EntityId, &Rider)> {
701 use crate::components::RiderPhase;
702 self.iter_riders()
703 .filter(|(id, r)| r.phase == RiderPhase::Waiting && !self.is_disabled(*id))
704 }
705
706 #[must_use]
708 pub fn find_stop_at_position(&self, position: f64) -> Option<EntityId> {
709 const EPSILON: f64 = 1e-6;
710 self.stops.iter().find_map(|(id, stop)| {
711 if (stop.position - position).abs() < EPSILON {
712 Some(id)
713 } else {
714 None
715 }
716 })
717 }
718
719 #[must_use]
725 pub fn find_nearest_stop(&self, position: f64) -> Option<EntityId> {
726 self.stops
727 .iter()
728 .min_by(|(_, a), (_, b)| {
729 (a.position - position)
730 .abs()
731 .total_cmp(&(b.position - position).abs())
732 })
733 .map(|(id, _)| id)
734 }
735
736 #[must_use]
738 pub fn stop_position(&self, id: EntityId) -> Option<f64> {
739 self.stops.get(id).map(|s| s.position)
740 }
741
742 pub fn insert_ext<T: 'static + Send + Sync + serde::Serialize + serde::de::DeserializeOwned>(
763 &mut self,
764 id: EntityId,
765 value: T,
766 key: ExtKey<T>,
767 ) {
768 let type_id = TypeId::of::<T>();
769 Self::assert_ext_name_unique(&self.ext_names, type_id, key.name());
770 let map = self
771 .extensions
772 .entry(type_id)
773 .or_insert_with(|| Box::new(SecondaryMap::<EntityId, T>::new()));
774 if let Some(m) = map.as_any_mut().downcast_mut::<SecondaryMap<EntityId, T>>() {
775 m.insert(id, value);
776 }
777 self.ext_names.insert(type_id, key.name().to_owned());
778 }
779
780 #[must_use]
782 pub fn ext<T: 'static + Send + Sync + Clone>(&self, id: EntityId) -> Option<T> {
783 self.ext_map::<T>()?.get(id).cloned()
784 }
785
786 #[must_use]
792 pub fn ext_ref<T: 'static + Send + Sync>(&self, id: EntityId) -> Option<&T> {
793 self.ext_map::<T>()?.get(id)
794 }
795
796 pub fn ext_mut<T: 'static + Send + Sync>(&mut self, id: EntityId) -> Option<&mut T> {
798 self.ext_map_mut::<T>()?.get_mut(id)
799 }
800
801 pub fn remove_ext<T: 'static + Send + Sync>(&mut self, id: EntityId) -> Option<T> {
803 self.ext_map_mut::<T>()?.remove(id)
804 }
805
806 pub(crate) fn ext_map<T: 'static + Send + Sync>(&self) -> Option<&SecondaryMap<EntityId, T>> {
808 self.extensions
809 .get(&TypeId::of::<T>())?
810 .as_any()
811 .downcast_ref::<SecondaryMap<EntityId, T>>()
812 }
813
814 fn ext_map_mut<T: 'static + Send + Sync>(&mut self) -> Option<&mut SecondaryMap<EntityId, T>> {
816 self.extensions
817 .get_mut(&TypeId::of::<T>())?
818 .as_any_mut()
819 .downcast_mut::<SecondaryMap<EntityId, T>>()
820 }
821
822 pub(crate) fn serialize_extensions(&self) -> BTreeMap<String, BTreeMap<EntityId, String>> {
826 let mut result = BTreeMap::new();
827 for (type_id, map) in &self.extensions {
828 if let Some(name) = self.ext_names.get(type_id) {
829 result.insert(name.clone(), map.serialize_entries());
830 }
831 }
832 result
833 }
834
835 pub(crate) fn deserialize_extensions(
838 &mut self,
839 data: &BTreeMap<String, BTreeMap<EntityId, String>>,
840 ) {
841 for (name, entries) in data {
842 if let Some((&type_id, _)) = self.ext_names.iter().find(|(_, n)| *n == name)
844 && let Some(map) = self.extensions.get_mut(&type_id)
845 {
846 map.deserialize_entries(entries);
847 }
848 }
849 }
850
851 pub(crate) fn unregistered_ext_names<'a>(
853 &self,
854 snapshot_names: impl Iterator<Item = &'a String>,
855 ) -> Vec<String> {
856 let registered: std::collections::HashSet<&str> =
857 self.ext_names.values().map(String::as_str).collect();
858 snapshot_names
859 .filter(|name| !registered.contains(name.as_str()))
860 .cloned()
861 .collect()
862 }
863
864 pub fn register_ext<
869 T: 'static + Send + Sync + serde::Serialize + serde::de::DeserializeOwned,
870 >(
871 &mut self,
872 key: ExtKey<T>,
873 ) -> ExtKey<T> {
874 let type_id = TypeId::of::<T>();
875 Self::assert_ext_name_unique(&self.ext_names, type_id, key.name());
876 self.extensions
877 .entry(type_id)
878 .or_insert_with(|| Box::new(SecondaryMap::<EntityId, T>::new()));
879 self.ext_names.insert(type_id, key.name().to_owned());
880 key
881 }
882
883 #[allow(clippy::panic)]
898 fn assert_ext_name_unique(ext_names: &HashMap<TypeId, String>, type_id: TypeId, name: &str) {
899 if let Some((existing_tid, _)) = ext_names
900 .iter()
901 .find(|(tid, n)| **tid != type_id && n.as_str() == name)
902 {
903 panic!(
904 "ExtKey name {name:?} is already registered to a different type \
905 ({existing_tid:?}); each extension type needs a unique key name. \
906 If renaming is impractical, use ExtKey::from_type_name() so the \
907 name embeds the fully-qualified Rust type name."
908 );
909 }
910 }
911
912 pub fn disable(&mut self, id: EntityId) {
916 self.disabled.insert(id, ());
917 }
918
919 pub fn enable(&mut self, id: EntityId) {
921 self.disabled.remove(id);
922 }
923
924 #[must_use]
926 pub fn is_disabled(&self, id: EntityId) -> bool {
927 self.disabled.contains_key(id)
928 }
929
930 pub fn insert_resource<T: 'static + Send + Sync>(&mut self, value: T) {
948 self.resources.insert(TypeId::of::<T>(), Box::new(value));
949 }
950
951 #[must_use]
953 pub fn resource<T: 'static + Send + Sync>(&self) -> Option<&T> {
954 self.resources.get(&TypeId::of::<T>())?.downcast_ref()
955 }
956
957 pub fn resource_mut<T: 'static + Send + Sync>(&mut self) -> Option<&mut T> {
959 self.resources.get_mut(&TypeId::of::<T>())?.downcast_mut()
960 }
961
962 pub fn remove_resource<T: 'static + Send + Sync>(&mut self) -> Option<T> {
964 self.resources
965 .remove(&TypeId::of::<T>())
966 .and_then(|b| b.downcast().ok())
967 .map(|b| *b)
968 }
969
970 #[must_use]
986 pub const fn query<Q: crate::query::WorldQuery>(&self) -> crate::query::QueryBuilder<'_, Q> {
987 crate::query::QueryBuilder::new(self)
988 }
989
990 pub fn query_ext_mut<T: 'static + Send + Sync>(&mut self) -> crate::query::ExtQueryMut<'_, T> {
1009 crate::query::ExtQueryMut::new(self)
1010 }
1011}
1012
1013impl Default for World {
1014 fn default() -> Self {
1015 Self::new()
1016 }
1017}
1018
1019pub(crate) struct SortedStops(pub(crate) Vec<(f64, EntityId)>);
1024
1025#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)]
1031pub struct StopCalls {
1032 pub up: Option<HallCall>,
1034 pub down: Option<HallCall>,
1036}
1037
1038impl StopCalls {
1039 #[must_use]
1041 pub const fn get(&self, direction: CallDirection) -> Option<&HallCall> {
1042 match direction {
1043 CallDirection::Up => self.up.as_ref(),
1044 CallDirection::Down => self.down.as_ref(),
1045 }
1046 }
1047
1048 pub const fn get_mut(&mut self, direction: CallDirection) -> Option<&mut HallCall> {
1050 match direction {
1051 CallDirection::Up => self.up.as_mut(),
1052 CallDirection::Down => self.down.as_mut(),
1053 }
1054 }
1055
1056 pub fn iter(&self) -> impl Iterator<Item = &HallCall> {
1058 self.up.iter().chain(self.down.iter())
1059 }
1060
1061 pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut HallCall> {
1063 self.up.iter_mut().chain(self.down.iter_mut())
1064 }
1065}