wecs_core/query/
query.rs

1use std::marker::PhantomData;
2
3use crate::{entity::EntityId, system::SystemParam, world::UnsafeWorldCell};
4
5use super::QueryComponent;
6
7pub struct Query<'world, Q>
8where
9    Q: QueryComponent,
10{
11    unsafe_world_cell: UnsafeWorldCell<'world>,
12    entity_ids: Vec<EntityId>,
13    _phantom_data: PhantomData<Q>,
14}
15
16impl<'world, Q> Iterator for Query<'world, Q>
17where
18    Q: QueryComponent,
19{
20    type Item = Q::Item<'world>;
21
22    fn next(&mut self) -> Option<Self::Item> {
23        if let Some(entity_id) = self.entity_ids.pop() {
24            let item = Q::get_component(self.unsafe_world_cell, entity_id);
25            return Some(item);
26        }
27
28        None
29    }
30}
31
32impl<'w, Q> SystemParam for Query<'w, Q>
33where
34    Q: QueryComponent,
35{
36    type Item<'world> = Query<'world, Q>;
37
38    fn get_param<'world>(unsafe_world_cell: UnsafeWorldCell<'world>) -> Self::Item<'world> {
39        let entity_ids = {
40            let world = unsafe_world_cell.world();
41            let entities = world.entities();
42            let archetypes = world.archetypes();
43            entities
44                .data
45                .iter()
46                .enumerate()
47                .filter(|(index, data)| {
48                    !entities.free_ids.contains(index) && data.archetype_id.is_init() && {
49                        let component_ids = &archetypes.get_data(&data.archetype_id).components_ids;
50
51                        Q::get_component_ids()
52                            .iter()
53                            .all(|id| component_ids.contains(id))
54                    }
55                })
56                .map(|(index, data)| EntityId {
57                    index,
58                    gen: data.gen,
59                })
60                .collect::<Vec<_>>()
61        };
62        Query {
63            unsafe_world_cell,
64            entity_ids,
65            _phantom_data: PhantomData,
66        }
67    }
68}