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