flax/query/
data.rs

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
23/// Combined reference to a query and a world.
24///
25/// Allow for executing a query inside a system without violating access rules.
26pub 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    /// Prepare the query.
65    ///
66    /// This will borrow all required archetypes for the duration of the
67    /// `PreparedQuery`.
68    ///
69    /// The same query can be prepared multiple times, though not
70    /// simultaneously.
71    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}