mirror of
https://github.com/bevyengine/bevy
synced 2024-11-25 14:10:19 +00:00
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
This commit is contained in:
parent
5ffff03b33
commit
155068a090
5 changed files with 59 additions and 59 deletions
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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>;
|
||||
|
||||
|
@ -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>;
|
||||
|
||||
|
@ -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>;
|
||||
|
||||
|
@ -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>;
|
||||
|
||||
|
@ -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,)*);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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>;
|
||||
|
||||
|
@ -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>;
|
||||
|
||||
|
@ -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>;
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -309,7 +309,7 @@ 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) {
|
||||
|
@ -317,15 +317,15 @@ where
|
|||
}
|
||||
|
||||
// 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,
|
||||
|
@ -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> {
|
||||
|
@ -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))
|
||||
|
@ -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 {
|
||||
|
|
|
@ -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,
|
||||
{
|
||||
|
@ -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) }
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
{
|
||||
|
@ -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 {
|
||||
|
@ -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(
|
||||
|
@ -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,
|
||||
{
|
||||
|
@ -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 {
|
||||
|
@ -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(
|
||||
|
@ -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,
|
||||
) {
|
||||
|
@ -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,
|
||||
) {
|
||||
|
|
|
@ -266,7 +266,7 @@ where
|
|||
///
|
||||
/// This can only be called for read-only queries, see [`Self::for_each_mut`] for write-queries.
|
||||
#[inline]
|
||||
pub fn for_each(&self, f: impl FnMut(<Q::Fetch as Fetch<'w>>::Item))
|
||||
pub fn for_each<'s>(&'s self, f: impl FnMut(<Q::Fetch as Fetch<'w, 's>>::Item))
|
||||
where
|
||||
Q::Fetch: ReadOnlyFetch,
|
||||
{
|
||||
|
@ -285,7 +285,7 @@ where
|
|||
/// Runs `f` on each query result. This is faster than the equivalent iter() method, but cannot
|
||||
/// be chained like a normal [`Iterator`].
|
||||
#[inline]
|
||||
pub fn for_each_mut(&mut self, f: impl FnMut(<Q::Fetch as Fetch<'w>>::Item)) {
|
||||
pub fn for_each_mut<'s>(&'s mut self, f: impl FnMut(<Q::Fetch as Fetch<'w, 's>>::Item)) {
|
||||
// SAFE: system runs without conflicts with other systems. same-system queries have runtime
|
||||
// borrow checks when they conflict
|
||||
unsafe {
|
||||
|
@ -303,11 +303,11 @@ where
|
|||
/// This can only be called for read-only queries, see [`Self::par_for_each_mut`] for
|
||||
/// write-queries.
|
||||
#[inline]
|
||||
pub fn par_for_each(
|
||||
&self,
|
||||
pub fn par_for_each<'s>(
|
||||
&'s self,
|
||||
task_pool: &TaskPool,
|
||||
batch_size: usize,
|
||||
f: impl Fn(<Q::Fetch as Fetch<'w>>::Item) + Send + Sync + Clone,
|
||||
f: impl Fn(<Q::Fetch as Fetch<'w, 's>>::Item) + Send + Sync + Clone,
|
||||
) where
|
||||
Q::Fetch: ReadOnlyFetch,
|
||||
{
|
||||
|
@ -327,11 +327,11 @@ where
|
|||
|
||||
/// Runs `f` on each query result in parallel using the given task pool.
|
||||
#[inline]
|
||||
pub fn par_for_each_mut(
|
||||
&mut self,
|
||||
pub fn par_for_each_mut<'s>(
|
||||
&'s mut self,
|
||||
task_pool: &TaskPool,
|
||||
batch_size: usize,
|
||||
f: impl Fn(<Q::Fetch as Fetch<'w>>::Item) + Send + Sync + Clone,
|
||||
f: impl Fn(<Q::Fetch as Fetch<'w, 's>>::Item) + Send + Sync + Clone,
|
||||
) {
|
||||
// SAFE: system runs without conflicts with other systems. same-system queries have runtime
|
||||
// borrow checks when they conflict
|
||||
|
@ -511,7 +511,7 @@ where
|
|||
/// ```
|
||||
///
|
||||
/// This can only be called for read-only queries, see [`Self::single_mut`] for write-queries.
|
||||
pub fn single(&self) -> Result<<Q::Fetch as Fetch<'_>>::Item, QuerySingleError>
|
||||
pub fn single(&self) -> Result<<Q::Fetch as Fetch<'_, '_>>::Item, QuerySingleError>
|
||||
where
|
||||
Q::Fetch: ReadOnlyFetch,
|
||||
{
|
||||
|
@ -530,7 +530,7 @@ where
|
|||
|
||||
/// Gets the query result if it is only a single result, otherwise returns a
|
||||
/// [`QuerySingleError`].
|
||||
pub fn single_mut(&mut self) -> Result<<Q::Fetch as Fetch<'_>>::Item, QuerySingleError> {
|
||||
pub fn single_mut(&mut self) -> Result<<Q::Fetch as Fetch<'_, '_>>::Item, QuerySingleError> {
|
||||
let mut query = self.iter_mut();
|
||||
let first = query.next();
|
||||
let extra = query.next().is_some();
|
||||
|
|
Loading…
Reference in a new issue