1use core::marker::PhantomData;
2
3use crate::{
4 query::{assert_borrow, Fetch, With, Without},
5 Archetype, Query, QueryItem,
6};
7
8pub struct QueryOne<'a, Q: Query> {
11 archetype: &'a Archetype,
12 index: u32,
13 borrowed: bool,
14 _marker: PhantomData<Q>,
15}
16
17impl<'a, Q: Query> QueryOne<'a, Q> {
18 pub(crate) unsafe fn new(archetype: &'a Archetype, index: u32) -> Self {
24 assert_borrow::<Q>();
25
26 Self {
27 archetype,
28 index,
29 borrowed: false,
30 _marker: PhantomData,
31 }
32 }
33
34 pub fn get(&mut self) -> Option<QueryItem<'_, Q>> {
42 assert!(!self.borrowed, "called QueryOnce::get twice; construct a new query instead");
46 let state = Q::Fetch::prepare(self.archetype)?;
47 Q::Fetch::borrow(self.archetype, state);
48 let fetch = Q::Fetch::execute(self.archetype, state);
49 self.borrowed = true;
50 unsafe { Some(fetch.get(self.index as usize)) }
51 }
52
53 pub fn with<R: Query>(self) -> QueryOne<'a, With<Q, R>> {
57 self.transform()
58 }
59
60 pub fn without<R: Query>(self) -> QueryOne<'a, Without<Q, R>> {
64 self.transform()
65 }
66
67 fn transform<R: Query>(mut self) -> QueryOne<'a, R> {
69 let x = QueryOne {
70 archetype: self.archetype,
71 index: self.index,
72 borrowed: self.borrowed,
73 _marker: PhantomData,
74 };
75 self.borrowed = false;
77 x
78 }
79}
80
81impl<Q: Query> Drop for QueryOne<'_, Q> {
82 fn drop(&mut self) {
83 if self.borrowed {
84 let state = Q::Fetch::prepare(self.archetype).unwrap();
85 Q::Fetch::release(self.archetype, state);
86 }
87 }
88}
89
90unsafe impl<Q: Query> Send for QueryOne<'_, Q> {}
91unsafe impl<Q: Query> Sync for QueryOne<'_, Q> {}