elevator_core/query/
fetch.rs1use std::marker::PhantomData;
4
5use crate::entity::EntityId;
6use crate::world::World;
7
8pub trait WorldQuery {
17 type Item<'w>;
19
20 fn fetch(world: &World, id: EntityId) -> Option<Self::Item<'_>>;
22
23 fn contains(world: &World, id: EntityId) -> bool;
25}
26
27pub struct Ext<T>(PhantomData<T>);
31
32pub struct ExtMut<T>(PhantomData<T>);
34
35impl WorldQuery for EntityId {
36 type Item<'w> = Self;
37
38 fn fetch(_world: &World, id: EntityId) -> Option<Self::Item<'_>> {
39 Some(id)
40 }
41
42 fn contains(_world: &World, _id: EntityId) -> bool {
43 true
44 }
45}
46
47macro_rules! impl_builtin_query {
49 ($comp:ty, $field:ident) => {
50 impl WorldQuery for &$comp {
51 type Item<'w> = &'w $comp;
52
53 fn fetch(world: &World, id: EntityId) -> Option<Self::Item<'_>> {
54 world.$field.get(id)
55 }
56
57 fn contains(world: &World, id: EntityId) -> bool {
58 world.$field.contains_key(id)
59 }
60 }
61
62 impl WorldQuery for Option<&$comp> {
63 type Item<'w> = Option<&'w $comp>;
64
65 fn fetch(world: &World, id: EntityId) -> Option<Self::Item<'_>> {
66 Some(world.$field.get(id))
67 }
68
69 fn contains(_world: &World, _id: EntityId) -> bool {
70 true
71 }
72 }
73 };
74}
75
76impl_builtin_query!(crate::components::Position, positions);
77impl_builtin_query!(crate::components::Velocity, velocities);
78impl_builtin_query!(crate::components::Elevator, elevators);
79impl_builtin_query!(crate::components::Stop, stops);
80impl_builtin_query!(crate::components::Rider, riders);
81impl_builtin_query!(crate::components::Route, routes);
82impl_builtin_query!(crate::components::Line, lines);
83impl_builtin_query!(crate::components::Patience, patience);
84impl_builtin_query!(crate::components::Preferences, preferences);
85
86impl<T: 'static + Send + Sync> WorldQuery for &Ext<T> {
87 type Item<'w> = &'w T;
88
89 fn fetch(world: &World, id: EntityId) -> Option<Self::Item<'_>> {
90 world.ext_map::<T>()?.get(id)
91 }
92
93 fn contains(world: &World, id: EntityId) -> bool {
94 world.ext_map::<T>().is_some_and(|m| m.contains_key(id))
95 }
96}
97
98macro_rules! impl_tuple_query {
100 ($($name:ident),+) => {
101 #[allow(non_snake_case)]
102 impl<$($name: WorldQuery),+> WorldQuery for ($($name,)+) {
103 type Item<'w> = ($($name::Item<'w>,)+);
104
105 fn fetch(world: &World, id: EntityId) -> Option<Self::Item<'_>> {
106 Some(($($name::fetch(world, id)?,)+))
107 }
108
109 fn contains(world: &World, id: EntityId) -> bool {
110 $($name::contains(world, id) &&)+ true
111 }
112 }
113 };
114}
115
116impl_tuple_query!(A);
117impl_tuple_query!(A, B);
118impl_tuple_query!(A, B, C);
119impl_tuple_query!(A, B, C, D);
120impl_tuple_query!(A, B, C, D, E);
121impl_tuple_query!(A, B, C, D, E, F);
122impl_tuple_query!(A, B, C, D, E, F, G);
123impl_tuple_query!(A, B, C, D, E, F, G, H);