Skip to content

Commit

Permalink
Add 's (state) lifetime to Fetch (bevyengine#2515)
Browse files Browse the repository at this point in the history
Allows iterators to return things that borrow data from `QueryState`, needed this in my relations PR figure might be worth landing separately maybe
  • Loading branch information
BoxyUwU committed Jul 29, 2021
1 parent 5ffff03 commit 155068a
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 59 deletions.
16 changes: 8 additions & 8 deletions crates/bevy_ecs/src/query/fetch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,11 @@ use std::{
///
/// [`Or`]: crate::query::Or
pub trait WorldQuery {
type Fetch: for<'a> Fetch<'a, State = Self::State>;
type Fetch: for<'world, 'state> Fetch<'world, 'state, State = Self::State>;
type State: FetchState;
}

pub trait Fetch<'w>: Sized {
pub trait Fetch<'world, 'state>: Sized {
type Item;
type State: FetchState;

Expand Down Expand Up @@ -173,7 +173,7 @@ unsafe impl FetchState for EntityState {
}
}

impl<'w> Fetch<'w> for EntityFetch {
impl<'w, 's> Fetch<'w, 's> for EntityFetch {
type Item = Entity;
type State = EntityState;

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

impl<'w, T: Component> Fetch<'w> for ReadFetch<T> {
impl<'w, 's, T: Component> Fetch<'w, 's> for ReadFetch<T> {
type Item = &'w T;
type State = ReadState<T>;

Expand Down Expand Up @@ -459,7 +459,7 @@ unsafe impl<T: Component> FetchState for WriteState<T> {
}
}

impl<'w, T: Component> Fetch<'w> for WriteFetch<T> {
impl<'w, 's, T: Component> Fetch<'w, 's> for WriteFetch<T> {
type Item = Mut<'w, T>;
type State = WriteState<T>;

Expand Down Expand Up @@ -619,7 +619,7 @@ unsafe impl<T: FetchState> FetchState for OptionState<T> {
}
}

impl<'w, T: Fetch<'w>> Fetch<'w> for OptionFetch<T> {
impl<'w, 's, T: Fetch<'w, 's>> Fetch<'w, 's> for OptionFetch<T> {
type Item = Option<T::Item>;
type State = OptionState<T::State>;

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

impl<'w, T: Component> Fetch<'w> for ChangeTrackersFetch<T> {
impl<'w, 's, T: Component> Fetch<'w, 's> for ChangeTrackersFetch<T> {
type Item = ChangeTrackers<T>;
type State = ChangeTrackersState<T>;

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

Expand Down
16 changes: 8 additions & 8 deletions crates/bevy_ecs/src/query/filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use std::{cell::UnsafeCell, marker::PhantomData, ptr};

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

impl<T> FilterFetch for T
where
T: for<'a> Fetch<'a, Item = bool>,
T: for<'w, 's> Fetch<'w, 's, Item = bool>,
{
#[inline]
unsafe fn archetype_filter_fetch(&mut self, archetype_index: usize) -> bool {
Expand Down Expand Up @@ -119,7 +119,7 @@ unsafe impl<T: Component> FetchState for WithState<T> {
}
}

impl<'a, T: Component> Fetch<'a> for WithFetch<T> {
impl<'w, 's, T: Component> Fetch<'w, 's> for WithFetch<T> {
type Item = bool;
type State = WithState<T>;

Expand Down Expand Up @@ -238,7 +238,7 @@ unsafe impl<T: Component> FetchState for WithoutState<T> {
}
}

impl<'a, T: Component> Fetch<'a> for WithoutFetch<T> {
impl<'w, 's, T: Component> Fetch<'w, 's> for WithoutFetch<T> {
type Item = bool;
type State = WithoutState<T>;

Expand Down Expand Up @@ -338,7 +338,7 @@ unsafe impl<T: Bundle> FetchState for WithBundleState<T> {
}
}

impl<'a, T: Bundle> Fetch<'a> for WithBundleFetch<T> {
impl<'w, 's, T: Bundle> Fetch<'w, 's> for WithBundleFetch<T> {
type Item = bool;
type State = WithBundleState<T>;

Expand Down Expand Up @@ -446,8 +446,8 @@ macro_rules! impl_query_filter_tuple {

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

unsafe fn init(world: &World, state: &Self::State, last_change_tick: u32, change_tick: u32) -> Self {
Expand Down Expand Up @@ -612,7 +612,7 @@ macro_rules! impl_tick_filter {
}
}

impl<'a, T: Component> Fetch<'a> for $fetch_name<T> {
impl<'w, 's, T: Component> Fetch<'w, 's> for $fetch_name<T> {
type State = $state_name<T>;
type Item = bool;

Expand Down
18 changes: 9 additions & 9 deletions crates/bevy_ecs/src/query/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ impl<'w, 's, Q: WorldQuery, F: WorldQuery> Iterator for QueryIter<'w, 's, Q, F>
where
F::Fetch: FilterFetch,
{
type Item = <Q::Fetch as Fetch<'w>>::Item;
type Item = <Q::Fetch as Fetch<'w, 's>>::Item;

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

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

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

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

Some(values)
}

/// Get next combination of queried components
#[inline]
pub fn fetch_next(&mut self) -> Option<[<Q::Fetch as Fetch<'_>>::Item; K]>
pub fn fetch_next(&mut self) -> Option<[<Q::Fetch as Fetch<'_, 's>>::Item; K]>
where
Q::Fetch: Clone,
F::Fetch: Clone,
Expand All @@ -346,7 +346,7 @@ where
Q::Fetch: Clone + ReadOnlyFetch,
F::Fetch: Clone + FilterFetch + ReadOnlyFetch,
{
type Item = [<Q::Fetch as Fetch<'w>>::Item; K];
type Item = [<Q::Fetch as Fetch<'w, 's>>::Item; K];

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

/// retrieve item returned from most recent `next` call again.
#[inline]
unsafe fn peek_last<'w>(&mut self) -> Option<<Q::Fetch as Fetch<'w>>::Item> {
unsafe fn peek_last<'w>(&mut self) -> Option<<Q::Fetch as Fetch<'w, 's>>::Item> {
if self.current_index > 0 {
if self.is_dense {
Some(self.fetch.table_fetch(self.current_index - 1))
Expand All @@ -497,7 +497,7 @@ where
tables: &'w Tables,
archetypes: &'w Archetypes,
query_state: &'s QueryState<Q, F>,
) -> Option<<Q::Fetch as Fetch<'w>>::Item> {
) -> Option<<Q::Fetch as Fetch<'w, 's>>::Item> {
if self.is_dense {
loop {
if self.current_index == self.current_len {
Expand Down
48 changes: 24 additions & 24 deletions crates/bevy_ecs/src/query/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ where
&mut self,
world: &'w World,
entity: Entity,
) -> Result<<Q::Fetch as Fetch<'w>>::Item, QueryEntityError>
) -> Result<<Q::Fetch as Fetch<'w, '_>>::Item, QueryEntityError>
where
Q::Fetch: ReadOnlyFetch,
{
Expand All @@ -134,7 +134,7 @@ where
&mut self,
world: &'w mut World,
entity: Entity,
) -> Result<<Q::Fetch as Fetch<'w>>::Item, QueryEntityError> {
) -> Result<<Q::Fetch as Fetch<'w, '_>>::Item, QueryEntityError> {
// SAFETY: query has unique world access
unsafe { self.get_unchecked(world, entity) }
}
Expand All @@ -148,7 +148,7 @@ where
&mut self,
world: &'w World,
entity: Entity,
) -> Result<<Q::Fetch as Fetch<'w>>::Item, QueryEntityError> {
) -> Result<<Q::Fetch as Fetch<'w, '_>>::Item, QueryEntityError> {
self.validate_world_and_update_archetypes(world);
self.get_unchecked_manual(
world,
Expand All @@ -167,7 +167,7 @@ where
entity: Entity,
last_change_tick: u32,
change_tick: u32,
) -> Result<<Q::Fetch as Fetch<'w>>::Item, QueryEntityError> {
) -> Result<<Q::Fetch as Fetch<'w, '_>>::Item, QueryEntityError> {
let location = world
.entities
.get(entity)
Expand Down Expand Up @@ -290,10 +290,10 @@ where
}

#[inline]
pub fn for_each<'w>(
&mut self,
pub fn for_each<'w, 's>(
&'s mut self,
world: &'w World,
func: impl FnMut(<Q::Fetch as Fetch<'w>>::Item),
func: impl FnMut(<Q::Fetch as Fetch<'w, 's>>::Item),
) where
Q::Fetch: ReadOnlyFetch,
{
Expand All @@ -304,10 +304,10 @@ where
}

#[inline]
pub fn for_each_mut<'w>(
&mut self,
pub fn for_each_mut<'w, 's>(
&'s mut self,
world: &'w mut World,
func: impl FnMut(<Q::Fetch as Fetch<'w>>::Item),
func: impl FnMut(<Q::Fetch as Fetch<'w, 's>>::Item),
) {
// SAFETY: query has unique world access
unsafe {
Expand All @@ -320,10 +320,10 @@ where
/// This does not check for mutable query correctness. To be safe, make sure mutable queries
/// have unique access to the components they query.
#[inline]
pub unsafe fn for_each_unchecked<'w>(
&mut self,
pub unsafe fn for_each_unchecked<'w, 's>(
&'s mut self,
world: &'w World,
func: impl FnMut(<Q::Fetch as Fetch<'w>>::Item),
func: impl FnMut(<Q::Fetch as Fetch<'w, 's>>::Item),
) {
self.validate_world_and_update_archetypes(world);
self.for_each_unchecked_manual(
Expand All @@ -335,12 +335,12 @@ where
}

#[inline]
pub fn par_for_each<'w>(
&mut self,
pub fn par_for_each<'w, 's>(
&'s mut self,
world: &'w World,
task_pool: &TaskPool,
batch_size: usize,
func: impl Fn(<Q::Fetch as Fetch<'w>>::Item) + Send + Sync + Clone,
func: impl Fn(<Q::Fetch as Fetch<'w, 's>>::Item) + Send + Sync + Clone,
) where
Q::Fetch: ReadOnlyFetch,
{
Expand All @@ -351,12 +351,12 @@ where
}

#[inline]
pub fn par_for_each_mut<'w>(
&mut self,
pub fn par_for_each_mut<'w, 's>(
&'s mut self,
world: &'w mut World,
task_pool: &TaskPool,
batch_size: usize,
func: impl Fn(<Q::Fetch as Fetch<'w>>::Item) + Send + Sync + Clone,
func: impl Fn(<Q::Fetch as Fetch<'w, 's>>::Item) + Send + Sync + Clone,
) {
// SAFETY: query has unique world access
unsafe {
Expand All @@ -369,12 +369,12 @@ where
/// This does not check for mutable query correctness. To be safe, make sure mutable queries
/// have unique access to the components they query.
#[inline]
pub unsafe fn par_for_each_unchecked<'w>(
&mut self,
pub unsafe fn par_for_each_unchecked<'w, 's>(
&'s mut self,
world: &'w World,
task_pool: &TaskPool,
batch_size: usize,
func: impl Fn(<Q::Fetch as Fetch<'w>>::Item) + Send + Sync + Clone,
func: impl Fn(<Q::Fetch as Fetch<'w, 's>>::Item) + Send + Sync + Clone,
) {
self.validate_world_and_update_archetypes(world);
self.par_for_each_unchecked_manual(
Expand All @@ -396,7 +396,7 @@ where
pub(crate) unsafe fn for_each_unchecked_manual<'w, 's>(
&'s self,
world: &'w World,
mut func: impl FnMut(<Q::Fetch as Fetch<'w>>::Item),
mut func: impl FnMut(<Q::Fetch as Fetch<'w, 's>>::Item),
last_change_tick: u32,
change_tick: u32,
) {
Expand Down Expand Up @@ -450,7 +450,7 @@ where
world: &'w World,
task_pool: &TaskPool,
batch_size: usize,
func: impl Fn(<Q::Fetch as Fetch<'w>>::Item) + Send + Sync + Clone,
func: impl Fn(<Q::Fetch as Fetch<'w, 's>>::Item) + Send + Sync + Clone,
last_change_tick: u32,
change_tick: u32,
) {
Expand Down
Loading

0 comments on commit 155068a

Please sign in to comment.