1use crate::ecs::{Entity, resources::Resources, system_param::SystemParam};
2
3pub struct Query<'a, Q: hecs::Query> {
6 world: &'a hecs::World,
7 borrow: hecs::QueryBorrow<'a, Q>,
8 scratch: Option<hecs::QueryOne<'a, Q>>,
9}
10
11impl<'a, Q: hecs::Query> IntoIterator for &'a mut Query<'a, Q> {
12 type Item = Q::Item<'a>;
13 type IntoIter = hecs::QueryIter<'a, Q>;
14
15 fn into_iter(self) -> Self::IntoIter {
16 (&mut self.borrow).into_iter()
17 }
18}
19
20impl<'a, Q: hecs::Query> Query<'a, Q> {
21 pub fn iter(&mut self) -> impl Iterator<Item = Q::Item<'_>> {
23 self.borrow.iter()
24 }
25
26 pub fn get(&mut self, entity: Entity) -> Option<Q::Item<'_>> {
29 self.scratch = Some(self.world.query_one::<Q>(entity));
30 self.scratch.as_mut().unwrap().get().ok()
31 }
32
33 pub fn with<R: hecs::Query>(self) -> Query<'a, hecs::With<Q, R>> {
36 Query {
37 world: self.world,
38 borrow: self.borrow.with::<R>(),
39 scratch: None,
40 }
41 }
42
43 pub fn without<R: hecs::Query>(self) -> Query<'a, hecs::Without<Q, R>> {
45 Query {
46 world: self.world,
47 borrow: self.borrow.without::<R>(),
48 scratch: None,
49 }
50 }
51
52 pub fn single(&mut self) -> Q::Item<'_> {
56 self.get_single()
57 .expect("Query::single: expected exactly one matching entity")
58 }
59
60 pub fn get_single(&mut self) -> Option<Q::Item<'_>> {
63 let mut iter = self.borrow.iter();
64 let first = iter.next()?;
65 if iter.next().is_some() {
66 return None;
67 }
68 Some(first)
69 }
70}
71
72impl<Q> SystemParam for Query<'static, Q>
73where
74 Q: hecs::Query + 'static,
75{
76 type Item<'a> = Query<'a, Q>;
77 type State = ();
78
79 fn fetch<'a>(
80 world: &'a hecs::World,
81 _resources: &'a Resources,
82 _state: &'a mut Self::State,
83 ) -> Self::Item<'a> {
84 Query {
85 world,
86 borrow: world.query::<Q>(),
87 scratch: None,
88 }
89 }
90}