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