1use core::{any::TypeId, marker::PhantomData, ptr::NonNull};
2
3use crate::{Access, Archetype, Component, Fetch, Query};
4
5pub struct Mutated<T>(PhantomData<fn(T)>);
33
34impl<T: Component> Query for Mutated<T> {
35 type Item<'a> = bool;
36
37 type Fetch = FetchMutated<T>;
38
39 unsafe fn get<'a>(fetch: &FetchMutated<T>, n: usize) -> Self::Item<'a> {
40 *fetch.0.as_ptr().add(n)
41 }
42}
43
44#[doc(hidden)]
45pub struct FetchMutated<T>(NonNull<bool>, PhantomData<fn(T)>);
46
47unsafe impl<T: Component> Fetch for FetchMutated<T> {
48 type State = usize;
49
50 fn dangling() -> Self {
51 Self(NonNull::dangling(), PhantomData)
52 }
53
54 fn access(archetype: &Archetype) -> Option<Access> {
55 if archetype.has::<T>() {
56 Some(Access::Read)
57 } else {
58 None
59 }
60 }
61
62 fn borrow(_archetype: &Archetype, _state: Self::State) {}
63 fn prepare(archetype: &Archetype) -> Option<Self::State> {
64 archetype.get_state::<T>()
65 }
66 fn execute(archetype: &Archetype, state: Self::State) -> Self {
67 Self(archetype.get_mutated(state), PhantomData)
68 }
69 fn release(_archetype: &Archetype, _state: Self::State) {}
70
71 fn for_each_borrow(mut f: impl FnMut(TypeId, bool)) {
72 f(TypeId::of::<T>(), false);
73 }
74}
75
76pub struct Added<T>(PhantomData<fn(T)>);
96
97impl<T: Component> Query for Added<T> {
98 type Item<'a> = bool;
99
100 type Fetch = FetchAdded<T>;
101
102 unsafe fn get<'a>(fetch: &FetchAdded<T>, n: usize) -> Self::Item<'a> {
103 *fetch.0.as_ptr().add(n)
104 }
105}
106
107#[doc(hidden)]
108pub struct FetchAdded<T>(NonNull<bool>, PhantomData<fn(T)>);
109
110unsafe impl<T: Component> Fetch for FetchAdded<T> {
111 type State = usize;
112
113 fn dangling() -> Self {
114 Self(NonNull::dangling(), PhantomData)
115 }
116
117 fn access(archetype: &Archetype) -> Option<Access> {
118 if archetype.has::<T>() {
119 Some(Access::Read)
120 } else {
121 None
122 }
123 }
124
125 fn borrow(_archetype: &Archetype, _state: Self::State) {}
126 fn prepare(archetype: &Archetype) -> Option<Self::State> {
127 archetype.get_state::<T>()
128 }
129 fn execute(archetype: &Archetype, state: Self::State) -> Self {
130 Self(archetype.get_added(state), PhantomData)
131 }
132 fn release(_archetype: &Archetype, _state: Self::State) {}
133
134 fn for_each_borrow(mut f: impl FnMut(TypeId, bool)) {
135 f(TypeId::of::<T>(), false);
136 }
137}
138
139pub struct Changed<T>(PhantomData<fn(T)>);
171
172impl<T: Component> Query for Changed<T> {
173 type Item<'a> = bool;
174
175 type Fetch = FetchChanged<T>;
176
177 unsafe fn get<'a>(fetch: &FetchChanged<T>, n: usize) -> Self::Item<'a> {
178 *fetch.0.as_ptr().add(n) || *fetch.1.as_ptr().add(n)
179 }
180}
181
182#[doc(hidden)]
183pub struct FetchChanged<T>(NonNull<bool>, NonNull<bool>, PhantomData<fn(T)>);
184
185unsafe impl<T: Component> Fetch for FetchChanged<T> {
186 type State = usize;
187
188 fn dangling() -> Self {
189 Self(NonNull::dangling(), NonNull::dangling(), PhantomData)
190 }
191
192 fn access(archetype: &Archetype) -> Option<Access> {
193 if archetype.has::<T>() {
194 Some(Access::Read)
195 } else {
196 None
197 }
198 }
199
200 fn borrow(_archetype: &Archetype, _state: Self::State) {}
201 fn prepare(archetype: &Archetype) -> Option<Self::State> {
202 archetype.get_state::<T>()
203 }
204 fn execute(archetype: &Archetype, state: Self::State) -> Self {
205 Self(
206 archetype.get_mutated(state),
207 archetype.get_added(state),
208 PhantomData,
209 )
210 }
211 fn release(_archetype: &Archetype, _state: Self::State) {}
212
213 fn for_each_borrow(mut f: impl FnMut(TypeId, bool)) {
214 f(TypeId::of::<T>(), false);
215 }
216}