1use alloc::vec::Vec;
2use atomic_refcell::AtomicRef;
3
4use crate::{
5 filter::All,
6 system::{Access, AsBorrowed, SystemAccess, SystemContext, SystemData},
7 Fetch, Planar, Query, World,
8};
9
10use super::QueryStrategy;
11
12impl<Q, F, S> SystemAccess for Query<Q, F, S>
13where
14 Q: 'static + for<'x> Fetch<'x>,
15 F: 'static + for<'x> Fetch<'x>,
16 S: for<'x> QueryStrategy<'x, Q, F>,
17{
18 fn access(&self, world: &World, dst: &mut Vec<Access>) {
19 self.strategy.access(world, &self.fetch, dst);
20 }
21}
22
23pub struct QueryData<'a, Q, F = All, S = Planar>
27where
28 Q: for<'x> Fetch<'x> + 'static,
29 F: for<'x> Fetch<'x> + 'static,
30{
31 world: AtomicRef<'a, World>,
32 query: &'a mut Query<Q, F, S>,
33}
34
35impl<'a, Q, F, S> SystemData<'a> for Query<Q, F, S>
36where
37 Q: 'static + for<'x> Fetch<'x>,
38 F: 'static + for<'x> Fetch<'x>,
39 S: 'static + for<'x> QueryStrategy<'x, Q, F>,
40{
41 type Value = QueryData<'a, Q, F, S>;
42
43 fn acquire(&'a mut self, ctx: &'a SystemContext<'_, '_, '_>) -> Self::Value {
44 let world = ctx.world();
45
46 QueryData { world, query: self }
47 }
48
49 fn describe(&self, f: &mut alloc::fmt::Formatter<'_>) -> alloc::fmt::Result {
50 f.write_str("Query<")?;
51 self.fetch.describe(f)?;
52 f.write_str(", ")?;
53 f.write_str(&tynm::type_name::<S>())?;
54 f.write_str(">")
55 }
56}
57
58impl<'a, Q, F, S> QueryData<'a, Q, F, S>
59where
60 Q: for<'x> Fetch<'x>,
61 F: for<'x> Fetch<'x>,
62 S: for<'x> QueryStrategy<'x, Q, F>,
63{
64 pub fn borrow(&mut self) -> <S as QueryStrategy<Q, F>>::Borrow {
72 self.query.borrow(&self.world)
73 }
74}
75
76impl<'a, 'w, Q, F, S> AsBorrowed<'a> for QueryData<'w, Q, F, S>
77where
78 Q: for<'x> Fetch<'x> + 'static,
79 F: for<'x> Fetch<'x> + 'static,
80 S: for<'x> QueryStrategy<'x, Q, F>,
81 <S as QueryStrategy<'a, Q, F>>::Borrow: 'a,
82{
83 type Borrowed = <S as QueryStrategy<'a, Q, F>>::Borrow;
84
85 fn as_borrowed(&'a mut self) -> Self::Borrowed {
86 self.borrow()
87 }
88}