Skip to content

Commit 155068a

Browse files
committed
Add 's (state) lifetime to Fetch (#2515)
Allows iterators to return things that borrow data from `QueryState`, needed this in my relations PR figure might be worth landing separately maybe
1 parent 5ffff03 commit 155068a

File tree

5 files changed

+59
-59
lines changed

5 files changed

+59
-59
lines changed

crates/bevy_ecs/src/query/fetch.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,11 @@ use std::{
4141
///
4242
/// [`Or`]: crate::query::Or
4343
pub trait WorldQuery {
44-
type Fetch: for<'a> Fetch<'a, State = Self::State>;
44+
type Fetch: for<'world, 'state> Fetch<'world, 'state, State = Self::State>;
4545
type State: FetchState;
4646
}
4747

48-
pub trait Fetch<'w>: Sized {
48+
pub trait Fetch<'world, 'state>: Sized {
4949
type Item;
5050
type State: FetchState;
5151

@@ -173,7 +173,7 @@ unsafe impl FetchState for EntityState {
173173
}
174174
}
175175

176-
impl<'w> Fetch<'w> for EntityFetch {
176+
impl<'w, 's> Fetch<'w, 's> for EntityFetch {
177177
type Item = Entity;
178178
type State = EntityState;
179179

@@ -296,7 +296,7 @@ impl<T> Clone for ReadFetch<T> {
296296
/// SAFETY: access is read only
297297
unsafe impl<T> ReadOnlyFetch for ReadFetch<T> {}
298298

299-
impl<'w, T: Component> Fetch<'w> for ReadFetch<T> {
299+
impl<'w, 's, T: Component> Fetch<'w, 's> for ReadFetch<T> {
300300
type Item = &'w T;
301301
type State = ReadState<T>;
302302

@@ -459,7 +459,7 @@ unsafe impl<T: Component> FetchState for WriteState<T> {
459459
}
460460
}
461461

462-
impl<'w, T: Component> Fetch<'w> for WriteFetch<T> {
462+
impl<'w, 's, T: Component> Fetch<'w, 's> for WriteFetch<T> {
463463
type Item = Mut<'w, T>;
464464
type State = WriteState<T>;
465465

@@ -619,7 +619,7 @@ unsafe impl<T: FetchState> FetchState for OptionState<T> {
619619
}
620620
}
621621

622-
impl<'w, T: Fetch<'w>> Fetch<'w> for OptionFetch<T> {
622+
impl<'w, 's, T: Fetch<'w, 's>> Fetch<'w, 's> for OptionFetch<T> {
623623
type Item = Option<T::Item>;
624624
type State = OptionState<T::State>;
625625

@@ -810,7 +810,7 @@ pub struct ChangeTrackersFetch<T> {
810810
/// SAFETY: access is read only
811811
unsafe impl<T> ReadOnlyFetch for ChangeTrackersFetch<T> {}
812812

813-
impl<'w, T: Component> Fetch<'w> for ChangeTrackersFetch<T> {
813+
impl<'w, 's, T: Component> Fetch<'w, 's> for ChangeTrackersFetch<T> {
814814
type Item = ChangeTrackers<T>;
815815
type State = ChangeTrackersState<T>;
816816

@@ -913,7 +913,7 @@ impl<'w, T: Component> Fetch<'w> for ChangeTrackersFetch<T> {
913913
macro_rules! impl_tuple_fetch {
914914
($(($name: ident, $state: ident)),*) => {
915915
#[allow(non_snake_case)]
916-
impl<'a, $($name: Fetch<'a>),*> Fetch<'a> for ($($name,)*) {
916+
impl<'w, 's, $($name: Fetch<'w, 's>),*> Fetch<'w, 's> for ($($name,)*) {
917917
type Item = ($($name::Item,)*);
918918
type State = ($($name::State,)*);
919919

crates/bevy_ecs/src/query/filter.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use std::{cell::UnsafeCell, marker::PhantomData, ptr};
1212

1313
/// Extension trait for [`Fetch`] containing methods used by query filters.
1414
/// This trait exists to allow "short circuit" behaviors for relevant query filter fetches.
15-
pub trait FilterFetch: for<'a> Fetch<'a> {
15+
pub trait FilterFetch: for<'w, 's> Fetch<'w, 's> {
1616
/// # Safety
1717
///
1818
/// Must always be called _after_ [`Fetch::set_archetype`]. `archetype_index` must be in the range
@@ -28,7 +28,7 @@ pub trait FilterFetch: for<'a> Fetch<'a> {
2828

2929
impl<T> FilterFetch for T
3030
where
31-
T: for<'a> Fetch<'a, Item = bool>,
31+
T: for<'w, 's> Fetch<'w, 's, Item = bool>,
3232
{
3333
#[inline]
3434
unsafe fn archetype_filter_fetch(&mut self, archetype_index: usize) -> bool {
@@ -119,7 +119,7 @@ unsafe impl<T: Component> FetchState for WithState<T> {
119119
}
120120
}
121121

122-
impl<'a, T: Component> Fetch<'a> for WithFetch<T> {
122+
impl<'w, 's, T: Component> Fetch<'w, 's> for WithFetch<T> {
123123
type Item = bool;
124124
type State = WithState<T>;
125125

@@ -238,7 +238,7 @@ unsafe impl<T: Component> FetchState for WithoutState<T> {
238238
}
239239
}
240240

241-
impl<'a, T: Component> Fetch<'a> for WithoutFetch<T> {
241+
impl<'w, 's, T: Component> Fetch<'w, 's> for WithoutFetch<T> {
242242
type Item = bool;
243243
type State = WithoutState<T>;
244244

@@ -338,7 +338,7 @@ unsafe impl<T: Bundle> FetchState for WithBundleState<T> {
338338
}
339339
}
340340

341-
impl<'a, T: Bundle> Fetch<'a> for WithBundleFetch<T> {
341+
impl<'w, 's, T: Bundle> Fetch<'w, 's> for WithBundleFetch<T> {
342342
type Item = bool;
343343
type State = WithBundleState<T>;
344344

@@ -446,8 +446,8 @@ macro_rules! impl_query_filter_tuple {
446446

447447
#[allow(unused_variables)]
448448
#[allow(non_snake_case)]
449-
impl<'a, $($filter: FilterFetch),*> Fetch<'a> for Or<($(OrFetch<$filter>,)*)> {
450-
type State = Or<($(<$filter as Fetch<'a>>::State,)*)>;
449+
impl<'w, 's, $($filter: FilterFetch),*> Fetch<'w, 's> for Or<($(OrFetch<$filter>,)*)> {
450+
type State = Or<($(<$filter as Fetch<'w, 's>>::State,)*)>;
451451
type Item = bool;
452452

453453
unsafe fn init(world: &World, state: &Self::State, last_change_tick: u32, change_tick: u32) -> Self {
@@ -612,7 +612,7 @@ macro_rules! impl_tick_filter {
612612
}
613613
}
614614

615-
impl<'a, T: Component> Fetch<'a> for $fetch_name<T> {
615+
impl<'w, 's, T: Component> Fetch<'w, 's> for $fetch_name<T> {
616616
type State = $state_name<T>;
617617
type Item = bool;
618618

crates/bevy_ecs/src/query/iter.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ impl<'w, 's, Q: WorldQuery, F: WorldQuery> Iterator for QueryIter<'w, 's, Q, F>
131131
where
132132
F::Fetch: FilterFetch,
133133
{
134-
type Item = <Q::Fetch as Fetch<'w>>::Item;
134+
type Item = <Q::Fetch as Fetch<'w, 's>>::Item;
135135

136136
// NOTE: If you are changing query iteration code, remember to update the following places, where relevant:
137137
// QueryIter, QueryIterationCursor, QueryState::for_each_unchecked_manual, QueryState::par_for_each_unchecked_manual
@@ -279,7 +279,7 @@ where
279279
/// It is always safe for shared access.
280280
unsafe fn fetch_next_aliased_unchecked<'a>(
281281
&mut self,
282-
) -> Option<[<Q::Fetch as Fetch<'a>>::Item; K]>
282+
) -> Option<[<Q::Fetch as Fetch<'a, 's>>::Item; K]>
283283
where
284284
Q::Fetch: Clone,
285285
F::Fetch: Clone,
@@ -309,23 +309,23 @@ where
309309
}
310310

311311
// TODO: use MaybeUninit::uninit_array if it stabilizes
312-
let mut values: [MaybeUninit<<Q::Fetch as Fetch<'a>>::Item>; K] =
312+
let mut values: [MaybeUninit<<Q::Fetch as Fetch<'a, 's>>::Item>; K] =
313313
MaybeUninit::uninit().assume_init();
314314

315315
for (value, cursor) in values.iter_mut().zip(&mut self.cursors) {
316316
value.as_mut_ptr().write(cursor.peek_last().unwrap());
317317
}
318318

319319
// TODO: use MaybeUninit::array_assume_init if it stabilizes
320-
let values: [<Q::Fetch as Fetch<'a>>::Item; K] =
321-
(&values as *const _ as *const [<Q::Fetch as Fetch<'a>>::Item; K]).read();
320+
let values: [<Q::Fetch as Fetch<'a, 's>>::Item; K] =
321+
(&values as *const _ as *const [<Q::Fetch as Fetch<'a, 's>>::Item; K]).read();
322322

323323
Some(values)
324324
}
325325

326326
/// Get next combination of queried components
327327
#[inline]
328-
pub fn fetch_next(&mut self) -> Option<[<Q::Fetch as Fetch<'_>>::Item; K]>
328+
pub fn fetch_next(&mut self) -> Option<[<Q::Fetch as Fetch<'_, 's>>::Item; K]>
329329
where
330330
Q::Fetch: Clone,
331331
F::Fetch: Clone,
@@ -346,7 +346,7 @@ where
346346
Q::Fetch: Clone + ReadOnlyFetch,
347347
F::Fetch: Clone + FilterFetch + ReadOnlyFetch,
348348
{
349-
type Item = [<Q::Fetch as Fetch<'w>>::Item; K];
349+
type Item = [<Q::Fetch as Fetch<'w, 's>>::Item; K];
350350

351351
#[inline]
352352
fn next(&mut self) -> Option<Self::Item> {
@@ -476,7 +476,7 @@ where
476476

477477
/// retrieve item returned from most recent `next` call again.
478478
#[inline]
479-
unsafe fn peek_last<'w>(&mut self) -> Option<<Q::Fetch as Fetch<'w>>::Item> {
479+
unsafe fn peek_last<'w>(&mut self) -> Option<<Q::Fetch as Fetch<'w, 's>>::Item> {
480480
if self.current_index > 0 {
481481
if self.is_dense {
482482
Some(self.fetch.table_fetch(self.current_index - 1))
@@ -497,7 +497,7 @@ where
497497
tables: &'w Tables,
498498
archetypes: &'w Archetypes,
499499
query_state: &'s QueryState<Q, F>,
500-
) -> Option<<Q::Fetch as Fetch<'w>>::Item> {
500+
) -> Option<<Q::Fetch as Fetch<'w, 's>>::Item> {
501501
if self.is_dense {
502502
loop {
503503
if self.current_index == self.current_len {

crates/bevy_ecs/src/query/state.rs

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ where
121121
&mut self,
122122
world: &'w World,
123123
entity: Entity,
124-
) -> Result<<Q::Fetch as Fetch<'w>>::Item, QueryEntityError>
124+
) -> Result<<Q::Fetch as Fetch<'w, '_>>::Item, QueryEntityError>
125125
where
126126
Q::Fetch: ReadOnlyFetch,
127127
{
@@ -134,7 +134,7 @@ where
134134
&mut self,
135135
world: &'w mut World,
136136
entity: Entity,
137-
) -> Result<<Q::Fetch as Fetch<'w>>::Item, QueryEntityError> {
137+
) -> Result<<Q::Fetch as Fetch<'w, '_>>::Item, QueryEntityError> {
138138
// SAFETY: query has unique world access
139139
unsafe { self.get_unchecked(world, entity) }
140140
}
@@ -148,7 +148,7 @@ where
148148
&mut self,
149149
world: &'w World,
150150
entity: Entity,
151-
) -> Result<<Q::Fetch as Fetch<'w>>::Item, QueryEntityError> {
151+
) -> Result<<Q::Fetch as Fetch<'w, '_>>::Item, QueryEntityError> {
152152
self.validate_world_and_update_archetypes(world);
153153
self.get_unchecked_manual(
154154
world,
@@ -167,7 +167,7 @@ where
167167
entity: Entity,
168168
last_change_tick: u32,
169169
change_tick: u32,
170-
) -> Result<<Q::Fetch as Fetch<'w>>::Item, QueryEntityError> {
170+
) -> Result<<Q::Fetch as Fetch<'w, '_>>::Item, QueryEntityError> {
171171
let location = world
172172
.entities
173173
.get(entity)
@@ -290,10 +290,10 @@ where
290290
}
291291

292292
#[inline]
293-
pub fn for_each<'w>(
294-
&mut self,
293+
pub fn for_each<'w, 's>(
294+
&'s mut self,
295295
world: &'w World,
296-
func: impl FnMut(<Q::Fetch as Fetch<'w>>::Item),
296+
func: impl FnMut(<Q::Fetch as Fetch<'w, 's>>::Item),
297297
) where
298298
Q::Fetch: ReadOnlyFetch,
299299
{
@@ -304,10 +304,10 @@ where
304304
}
305305

306306
#[inline]
307-
pub fn for_each_mut<'w>(
308-
&mut self,
307+
pub fn for_each_mut<'w, 's>(
308+
&'s mut self,
309309
world: &'w mut World,
310-
func: impl FnMut(<Q::Fetch as Fetch<'w>>::Item),
310+
func: impl FnMut(<Q::Fetch as Fetch<'w, 's>>::Item),
311311
) {
312312
// SAFETY: query has unique world access
313313
unsafe {
@@ -320,10 +320,10 @@ where
320320
/// This does not check for mutable query correctness. To be safe, make sure mutable queries
321321
/// have unique access to the components they query.
322322
#[inline]
323-
pub unsafe fn for_each_unchecked<'w>(
324-
&mut self,
323+
pub unsafe fn for_each_unchecked<'w, 's>(
324+
&'s mut self,
325325
world: &'w World,
326-
func: impl FnMut(<Q::Fetch as Fetch<'w>>::Item),
326+
func: impl FnMut(<Q::Fetch as Fetch<'w, 's>>::Item),
327327
) {
328328
self.validate_world_and_update_archetypes(world);
329329
self.for_each_unchecked_manual(
@@ -335,12 +335,12 @@ where
335335
}
336336

337337
#[inline]
338-
pub fn par_for_each<'w>(
339-
&mut self,
338+
pub fn par_for_each<'w, 's>(
339+
&'s mut self,
340340
world: &'w World,
341341
task_pool: &TaskPool,
342342
batch_size: usize,
343-
func: impl Fn(<Q::Fetch as Fetch<'w>>::Item) + Send + Sync + Clone,
343+
func: impl Fn(<Q::Fetch as Fetch<'w, 's>>::Item) + Send + Sync + Clone,
344344
) where
345345
Q::Fetch: ReadOnlyFetch,
346346
{
@@ -351,12 +351,12 @@ where
351351
}
352352

353353
#[inline]
354-
pub fn par_for_each_mut<'w>(
355-
&mut self,
354+
pub fn par_for_each_mut<'w, 's>(
355+
&'s mut self,
356356
world: &'w mut World,
357357
task_pool: &TaskPool,
358358
batch_size: usize,
359-
func: impl Fn(<Q::Fetch as Fetch<'w>>::Item) + Send + Sync + Clone,
359+
func: impl Fn(<Q::Fetch as Fetch<'w, 's>>::Item) + Send + Sync + Clone,
360360
) {
361361
// SAFETY: query has unique world access
362362
unsafe {
@@ -369,12 +369,12 @@ where
369369
/// This does not check for mutable query correctness. To be safe, make sure mutable queries
370370
/// have unique access to the components they query.
371371
#[inline]
372-
pub unsafe fn par_for_each_unchecked<'w>(
373-
&mut self,
372+
pub unsafe fn par_for_each_unchecked<'w, 's>(
373+
&'s mut self,
374374
world: &'w World,
375375
task_pool: &TaskPool,
376376
batch_size: usize,
377-
func: impl Fn(<Q::Fetch as Fetch<'w>>::Item) + Send + Sync + Clone,
377+
func: impl Fn(<Q::Fetch as Fetch<'w, 's>>::Item) + Send + Sync + Clone,
378378
) {
379379
self.validate_world_and_update_archetypes(world);
380380
self.par_for_each_unchecked_manual(
@@ -396,7 +396,7 @@ where
396396
pub(crate) unsafe fn for_each_unchecked_manual<'w, 's>(
397397
&'s self,
398398
world: &'w World,
399-
mut func: impl FnMut(<Q::Fetch as Fetch<'w>>::Item),
399+
mut func: impl FnMut(<Q::Fetch as Fetch<'w, 's>>::Item),
400400
last_change_tick: u32,
401401
change_tick: u32,
402402
) {
@@ -450,7 +450,7 @@ where
450450
world: &'w World,
451451
task_pool: &TaskPool,
452452
batch_size: usize,
453-
func: impl Fn(<Q::Fetch as Fetch<'w>>::Item) + Send + Sync + Clone,
453+
func: impl Fn(<Q::Fetch as Fetch<'w, 's>>::Item) + Send + Sync + Clone,
454454
last_change_tick: u32,
455455
change_tick: u32,
456456
) {

0 commit comments

Comments
 (0)