mirror of
https://github.com/bevyengine/bevy
synced 2024-11-10 07:04:33 +00:00
Rename Q
type parameter to D
when referring to WorldQueryData
(#10782)
# Objective Since #10776 split `WorldQuery` to `WorldQueryData` and `WorldQueryFilter`, it should be clear that the query is actually composed of two parts. It is not factually correct to call "query" only the data part. Therefore I suggest to rename the `Q` parameter to `D` in `Query` and related items. As far as I know, there shouldn't be breaking changes from renaming generic type parameters. ## Solution I used a combination of rust-analyzer go to reference and `Ctrl-F`ing various patterns to catch as many cases as possible. Hopefully I got them all. Feel free to check if you're concerned of me having missed some. ## Notes This and #10779 have many lines in common, so merging one will cause a lot of merge conflicts to the other. --------- Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
This commit is contained in:
parent
7538e27f6a
commit
9c78128e8f
10 changed files with 271 additions and 271 deletions
|
@ -272,7 +272,7 @@ pub unsafe trait ReadOnlyQueryData: QueryData<ReadOnly = Self> {}
|
|||
/// The item type returned when a [`WorldQuery`] is iterated over
|
||||
pub type QueryItem<'w, Q> = <Q as WorldQuery>::Item<'w>;
|
||||
/// The read-only variant of the item type returned when a [`QueryData`] is iterated over immutably
|
||||
pub type ROQueryItem<'w, Q> = QueryItem<'w, <Q as QueryData>::ReadOnly>;
|
||||
pub type ROQueryItem<'w, D> = QueryItem<'w, <D as QueryData>::ReadOnly>;
|
||||
|
||||
/// SAFETY:
|
||||
/// `update_component_access` and `update_archetype_component_access` do nothing.
|
||||
|
@ -1399,27 +1399,27 @@ macro_rules! impl_anytuple_fetch {
|
|||
all_tuples!(impl_tuple_query_data, 0, 15, F, S);
|
||||
all_tuples!(impl_anytuple_fetch, 0, 15, F, S);
|
||||
|
||||
/// [`WorldQuery`] used to nullify queries by turning `Query<Q>` into `Query<NopWorldQuery<Q>>`
|
||||
/// [`WorldQuery`] used to nullify queries by turning `Query<D>` into `Query<NopWorldQuery<D>>`
|
||||
///
|
||||
/// This will rarely be useful to consumers of `bevy_ecs`.
|
||||
pub struct NopWorldQuery<Q: QueryData>(PhantomData<Q>);
|
||||
pub struct NopWorldQuery<D: QueryData>(PhantomData<D>);
|
||||
|
||||
/// SAFETY:
|
||||
/// `update_component_access` and `update_archetype_component_access` do nothing.
|
||||
/// This is sound because `fetch` does not access components.
|
||||
unsafe impl<Q: QueryData> WorldQuery for NopWorldQuery<Q> {
|
||||
unsafe impl<D: QueryData> WorldQuery for NopWorldQuery<D> {
|
||||
type Fetch<'w> = ();
|
||||
type Item<'w> = ();
|
||||
type State = Q::State;
|
||||
type State = D::State;
|
||||
|
||||
fn shrink<'wlong: 'wshort, 'wshort>(_: ()) {}
|
||||
|
||||
const IS_DENSE: bool = Q::IS_DENSE;
|
||||
const IS_DENSE: bool = D::IS_DENSE;
|
||||
|
||||
#[inline(always)]
|
||||
unsafe fn init_fetch(
|
||||
_world: UnsafeWorldCell,
|
||||
_state: &Q::State,
|
||||
_state: &D::State,
|
||||
_last_run: Tick,
|
||||
_this_run: Tick,
|
||||
) {
|
||||
|
@ -1428,14 +1428,14 @@ unsafe impl<Q: QueryData> WorldQuery for NopWorldQuery<Q> {
|
|||
#[inline(always)]
|
||||
unsafe fn set_archetype(
|
||||
_fetch: &mut (),
|
||||
_state: &Q::State,
|
||||
_state: &D::State,
|
||||
_archetype: &Archetype,
|
||||
_tables: &Table,
|
||||
) {
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
unsafe fn set_table<'w>(_fetch: &mut (), _state: &Q::State, _table: &Table) {}
|
||||
unsafe fn set_table<'w>(_fetch: &mut (), _state: &D::State, _table: &Table) {}
|
||||
|
||||
#[inline(always)]
|
||||
unsafe fn fetch<'w>(
|
||||
|
@ -1445,34 +1445,34 @@ unsafe impl<Q: QueryData> WorldQuery for NopWorldQuery<Q> {
|
|||
) -> Self::Item<'w> {
|
||||
}
|
||||
|
||||
fn update_component_access(_state: &Q::State, _access: &mut FilteredAccess<ComponentId>) {}
|
||||
fn update_component_access(_state: &D::State, _access: &mut FilteredAccess<ComponentId>) {}
|
||||
|
||||
fn update_archetype_component_access(
|
||||
_state: &Q::State,
|
||||
_state: &D::State,
|
||||
_archetype: &Archetype,
|
||||
_access: &mut Access<ArchetypeComponentId>,
|
||||
) {
|
||||
}
|
||||
|
||||
fn init_state(world: &mut World) -> Self::State {
|
||||
Q::init_state(world)
|
||||
D::init_state(world)
|
||||
}
|
||||
|
||||
fn matches_component_set(
|
||||
state: &Self::State,
|
||||
set_contains_id: &impl Fn(ComponentId) -> bool,
|
||||
) -> bool {
|
||||
Q::matches_component_set(state, set_contains_id)
|
||||
D::matches_component_set(state, set_contains_id)
|
||||
}
|
||||
}
|
||||
|
||||
/// SAFETY: `Self::ReadOnly` is `Self`
|
||||
unsafe impl<Q: QueryData> QueryData for NopWorldQuery<Q> {
|
||||
unsafe impl<D: QueryData> QueryData for NopWorldQuery<D> {
|
||||
type ReadOnly = Self;
|
||||
}
|
||||
|
||||
/// SAFETY: `NopFetch` never accesses any data
|
||||
unsafe impl<Q: QueryData> ReadOnlyQueryData for NopWorldQuery<Q> {}
|
||||
unsafe impl<D: QueryData> ReadOnlyQueryData for NopWorldQuery<D> {}
|
||||
|
||||
/// SAFETY:
|
||||
/// `update_component_access` and `update_archetype_component_access` do nothing.
|
||||
|
@ -1601,14 +1601,14 @@ mod tests {
|
|||
|
||||
#[derive(QueryData)]
|
||||
#[query_data(mutable)]
|
||||
pub struct Q {
|
||||
pub struct D {
|
||||
pub a: &'static mut A,
|
||||
}
|
||||
}
|
||||
|
||||
let _ = private::QReadOnly { a: &A };
|
||||
let _ = private::DReadOnly { a: &A };
|
||||
|
||||
fn my_system(query: Query<private::Q>) {
|
||||
fn my_system(query: Query<private::D>) {
|
||||
for q in &query {
|
||||
let _ = &q.a;
|
||||
}
|
||||
|
|
|
@ -14,20 +14,20 @@ use super::{QueryData, QueryFilter, ReadOnlyQueryData};
|
|||
///
|
||||
/// This struct is created by the [`Query::iter`](crate::system::Query::iter) and
|
||||
/// [`Query::iter_mut`](crate::system::Query::iter_mut) methods.
|
||||
pub struct QueryIter<'w, 's, Q: QueryData, F: QueryFilter> {
|
||||
pub struct QueryIter<'w, 's, D: QueryData, F: QueryFilter> {
|
||||
tables: &'w Tables,
|
||||
archetypes: &'w Archetypes,
|
||||
query_state: &'s QueryState<Q, F>,
|
||||
cursor: QueryIterationCursor<'w, 's, Q, F>,
|
||||
query_state: &'s QueryState<D, F>,
|
||||
cursor: QueryIterationCursor<'w, 's, D, F>,
|
||||
}
|
||||
|
||||
impl<'w, 's, Q: QueryData, F: QueryFilter> QueryIter<'w, 's, Q, F> {
|
||||
impl<'w, 's, D: QueryData, F: QueryFilter> QueryIter<'w, 's, D, F> {
|
||||
/// # Safety
|
||||
/// - `world` must have permission to access any of the components registered in `query_state`.
|
||||
/// - `world` must be the same one used to initialize `query_state`.
|
||||
pub(crate) unsafe fn new(
|
||||
world: UnsafeWorldCell<'w>,
|
||||
query_state: &'s QueryState<Q, F>,
|
||||
query_state: &'s QueryState<D, F>,
|
||||
last_run: Tick,
|
||||
this_run: Tick,
|
||||
) -> Self {
|
||||
|
@ -45,8 +45,8 @@ impl<'w, 's, Q: QueryData, F: QueryFilter> QueryIter<'w, 's, Q, F> {
|
|||
///
|
||||
/// # Safety
|
||||
/// - all `rows` must be in `[0, table.entity_count)`.
|
||||
/// - `table` must match Q and F
|
||||
/// - Both `Q::IS_DENSE` and `F::IS_DENSE` must be true.
|
||||
/// - `table` must match D and F
|
||||
/// - Both `D::IS_DENSE` and `F::IS_DENSE` must be true.
|
||||
#[inline]
|
||||
#[cfg(all(not(target = "wasm32"), feature = "multi-threaded"))]
|
||||
pub(super) unsafe fn for_each_in_table_range<Func>(
|
||||
|
@ -55,9 +55,9 @@ impl<'w, 's, Q: QueryData, F: QueryFilter> QueryIter<'w, 's, Q, F> {
|
|||
table: &'w Table,
|
||||
rows: Range<usize>,
|
||||
) where
|
||||
Func: FnMut(Q::Item<'w>),
|
||||
Func: FnMut(D::Item<'w>),
|
||||
{
|
||||
// SAFETY: Caller assures that Q::IS_DENSE and F::IS_DENSE are true, that table matches Q and F
|
||||
// SAFETY: Caller assures that D::IS_DENSE and F::IS_DENSE are true, that table matches D and F
|
||||
// and all indicies in rows are in range.
|
||||
unsafe {
|
||||
self.fold_over_table_range((), &mut |_, item| func(item), table, rows);
|
||||
|
@ -69,8 +69,8 @@ impl<'w, 's, Q: QueryData, F: QueryFilter> QueryIter<'w, 's, Q, F> {
|
|||
///
|
||||
/// # Safety
|
||||
/// - all `indices` must be in `[0, archetype.len())`.
|
||||
/// - `archetype` must match Q and F
|
||||
/// - Either `Q::IS_DENSE` or `F::IS_DENSE` must be false.
|
||||
/// - `archetype` must match D and F
|
||||
/// - Either `D::IS_DENSE` or `F::IS_DENSE` must be false.
|
||||
#[inline]
|
||||
#[cfg(all(not(target = "wasm32"), feature = "multi-threaded"))]
|
||||
pub(super) unsafe fn for_each_in_archetype_range<Func>(
|
||||
|
@ -79,9 +79,9 @@ impl<'w, 's, Q: QueryData, F: QueryFilter> QueryIter<'w, 's, Q, F> {
|
|||
archetype: &'w Archetype,
|
||||
rows: Range<usize>,
|
||||
) where
|
||||
Func: FnMut(Q::Item<'w>),
|
||||
Func: FnMut(D::Item<'w>),
|
||||
{
|
||||
// SAFETY: Caller assures that either Q::IS_DENSE or F::IS_DENSE are false, that archetype matches Q and F
|
||||
// SAFETY: Caller assures that either D::IS_DENSE or F::IS_DENSE are false, that archetype matches D and F
|
||||
// and all indices in rows are in range.
|
||||
unsafe {
|
||||
self.fold_over_archetype_range((), &mut |_, item| func(item), archetype, rows);
|
||||
|
@ -93,8 +93,8 @@ impl<'w, 's, Q: QueryData, F: QueryFilter> QueryIter<'w, 's, Q, F> {
|
|||
///
|
||||
/// # Safety
|
||||
/// - all `rows` must be in `[0, table.entity_count)`.
|
||||
/// - `table` must match Q and F
|
||||
/// - Both `Q::IS_DENSE` and `F::IS_DENSE` must be true.
|
||||
/// - `table` must match D and F
|
||||
/// - Both `D::IS_DENSE` and `F::IS_DENSE` must be true.
|
||||
#[inline]
|
||||
pub(super) unsafe fn fold_over_table_range<B, Func>(
|
||||
&mut self,
|
||||
|
@ -104,14 +104,14 @@ impl<'w, 's, Q: QueryData, F: QueryFilter> QueryIter<'w, 's, Q, F> {
|
|||
rows: Range<usize>,
|
||||
) -> B
|
||||
where
|
||||
Func: FnMut(B, Q::Item<'w>) -> B,
|
||||
Func: FnMut(B, D::Item<'w>) -> B,
|
||||
{
|
||||
assert!(
|
||||
rows.end <= u32::MAX as usize,
|
||||
"TableRow is only valid up to u32::MAX"
|
||||
);
|
||||
|
||||
Q::set_table(&mut self.cursor.fetch, &self.query_state.fetch_state, table);
|
||||
D::set_table(&mut self.cursor.fetch, &self.query_state.fetch_state, table);
|
||||
F::set_table(
|
||||
&mut self.cursor.filter,
|
||||
&self.query_state.filter_state,
|
||||
|
@ -131,7 +131,7 @@ impl<'w, 's, Q: QueryData, F: QueryFilter> QueryIter<'w, 's, Q, F> {
|
|||
|
||||
// SAFETY: set_table was called prior.
|
||||
// Caller assures `row` in range of the current archetype.
|
||||
let item = Q::fetch(&mut self.cursor.fetch, *entity, row);
|
||||
let item = D::fetch(&mut self.cursor.fetch, *entity, row);
|
||||
|
||||
accum = func(accum, item);
|
||||
}
|
||||
|
@ -143,8 +143,8 @@ impl<'w, 's, Q: QueryData, F: QueryFilter> QueryIter<'w, 's, Q, F> {
|
|||
///
|
||||
/// # Safety
|
||||
/// - all `indices` must be in `[0, archetype.len())`.
|
||||
/// - `archetype` must match Q and F
|
||||
/// - Either `Q::IS_DENSE` or `F::IS_DENSE` must be false.
|
||||
/// - `archetype` must match D and F
|
||||
/// - Either `D::IS_DENSE` or `F::IS_DENSE` must be false.
|
||||
#[inline]
|
||||
pub(super) unsafe fn fold_over_archetype_range<B, Func>(
|
||||
&mut self,
|
||||
|
@ -154,10 +154,10 @@ impl<'w, 's, Q: QueryData, F: QueryFilter> QueryIter<'w, 's, Q, F> {
|
|||
indices: Range<usize>,
|
||||
) -> B
|
||||
where
|
||||
Func: FnMut(B, Q::Item<'w>) -> B,
|
||||
Func: FnMut(B, D::Item<'w>) -> B,
|
||||
{
|
||||
let table = self.tables.get(archetype.table_id()).debug_checked_unwrap();
|
||||
Q::set_archetype(
|
||||
D::set_archetype(
|
||||
&mut self.cursor.fetch,
|
||||
&self.query_state.fetch_state,
|
||||
archetype,
|
||||
|
@ -186,7 +186,7 @@ impl<'w, 's, Q: QueryData, F: QueryFilter> QueryIter<'w, 's, Q, F> {
|
|||
|
||||
// SAFETY: set_archetype was called prior, `index` is an archetype index in range of the current archetype
|
||||
// Caller assures `index` in range of the current archetype.
|
||||
let item = Q::fetch(
|
||||
let item = D::fetch(
|
||||
&mut self.cursor.fetch,
|
||||
archetype_entity.entity(),
|
||||
archetype_entity.table_row(),
|
||||
|
@ -198,8 +198,8 @@ impl<'w, 's, Q: QueryData, F: QueryFilter> QueryIter<'w, 's, Q, F> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'w, 's, Q: QueryData, F: QueryFilter> Iterator for QueryIter<'w, 's, Q, F> {
|
||||
type Item = Q::Item<'w>;
|
||||
impl<'w, 's, D: QueryData, F: QueryFilter> Iterator for QueryIter<'w, 's, D, F> {
|
||||
type Item = D::Item<'w>;
|
||||
|
||||
#[inline(always)]
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
|
@ -230,15 +230,15 @@ impl<'w, 's, Q: QueryData, F: QueryFilter> Iterator for QueryIter<'w, 's, Q, F>
|
|||
let Some(item) = self.next() else { break };
|
||||
accum = func(accum, item);
|
||||
}
|
||||
if Q::IS_DENSE && F::IS_DENSE {
|
||||
if D::IS_DENSE && F::IS_DENSE {
|
||||
for table_id in self.cursor.table_id_iter.clone() {
|
||||
// SAFETY: Matched table IDs are guaranteed to still exist.
|
||||
let table = unsafe { self.tables.get(*table_id).debug_checked_unwrap() };
|
||||
accum =
|
||||
// SAFETY:
|
||||
// - The fetched table matches both Q and F
|
||||
// - The fetched table matches both D and F
|
||||
// - The provided range is equivalent to [0, table.entity_count)
|
||||
// - The if block ensures that Q::IS_DENSE and F::IS_DENSE are both true
|
||||
// - The if block ensures that D::IS_DENSE and F::IS_DENSE are both true
|
||||
unsafe { self.fold_over_table_range(accum, &mut func, table, 0..table.entity_count()) };
|
||||
}
|
||||
} else {
|
||||
|
@ -248,9 +248,9 @@ impl<'w, 's, Q: QueryData, F: QueryFilter> Iterator for QueryIter<'w, 's, Q, F>
|
|||
unsafe { self.archetypes.get(*archetype_id).debug_checked_unwrap() };
|
||||
accum =
|
||||
// SAFETY:
|
||||
// - The fetched archetype matches both Q and F
|
||||
// - The fetched archetype matches both D and F
|
||||
// - The provided range is equivalent to [0, archetype.len)
|
||||
// - The if block ensures that ether Q::IS_DENSE or F::IS_DENSE are false
|
||||
// - The if block ensures that ether D::IS_DENSE or F::IS_DENSE are false
|
||||
unsafe { self.fold_over_archetype_range(accum, &mut func, archetype, 0..archetype.len()) };
|
||||
}
|
||||
}
|
||||
|
@ -259,7 +259,7 @@ impl<'w, 's, Q: QueryData, F: QueryFilter> Iterator for QueryIter<'w, 's, Q, F>
|
|||
}
|
||||
|
||||
// This is correct as [`QueryIter`] always returns `None` once exhausted.
|
||||
impl<'w, 's, Q: QueryData, F: QueryFilter> FusedIterator for QueryIter<'w, 's, Q, F> {}
|
||||
impl<'w, 's, D: QueryData, F: QueryFilter> FusedIterator for QueryIter<'w, 's, D, F> {}
|
||||
|
||||
/// An [`Iterator`] over the query items generated from an iterator of [`Entity`]s.
|
||||
///
|
||||
|
@ -267,7 +267,7 @@ impl<'w, 's, Q: QueryData, F: QueryFilter> FusedIterator for QueryIter<'w, 's, Q
|
|||
/// Entities that don't match the query are skipped.
|
||||
///
|
||||
/// This struct is created by the [`Query::iter_many`](crate::system::Query::iter_many) and [`Query::iter_many_mut`](crate::system::Query::iter_many_mut) methods.
|
||||
pub struct QueryManyIter<'w, 's, Q: QueryData, F: QueryFilter, I: Iterator>
|
||||
pub struct QueryManyIter<'w, 's, D: QueryData, F: QueryFilter, I: Iterator>
|
||||
where
|
||||
I::Item: Borrow<Entity>,
|
||||
{
|
||||
|
@ -275,12 +275,12 @@ where
|
|||
entities: &'w Entities,
|
||||
tables: &'w Tables,
|
||||
archetypes: &'w Archetypes,
|
||||
fetch: Q::Fetch<'w>,
|
||||
fetch: D::Fetch<'w>,
|
||||
filter: F::Fetch<'w>,
|
||||
query_state: &'s QueryState<Q, F>,
|
||||
query_state: &'s QueryState<D, F>,
|
||||
}
|
||||
|
||||
impl<'w, 's, Q: QueryData, F: QueryFilter, I: Iterator> QueryManyIter<'w, 's, Q, F, I>
|
||||
impl<'w, 's, D: QueryData, F: QueryFilter, I: Iterator> QueryManyIter<'w, 's, D, F, I>
|
||||
where
|
||||
I::Item: Borrow<Entity>,
|
||||
{
|
||||
|
@ -289,12 +289,12 @@ where
|
|||
/// - `world` must be the same one used to initialize `query_state`.
|
||||
pub(crate) unsafe fn new<EntityList: IntoIterator<IntoIter = I>>(
|
||||
world: UnsafeWorldCell<'w>,
|
||||
query_state: &'s QueryState<Q, F>,
|
||||
query_state: &'s QueryState<D, F>,
|
||||
entity_list: EntityList,
|
||||
last_run: Tick,
|
||||
this_run: Tick,
|
||||
) -> QueryManyIter<'w, 's, Q, F, I> {
|
||||
let fetch = Q::init_fetch(world, &query_state.fetch_state, last_run, this_run);
|
||||
) -> QueryManyIter<'w, 's, D, F, I> {
|
||||
let fetch = D::init_fetch(world, &query_state.fetch_state, last_run, this_run);
|
||||
let filter = F::init_fetch(world, &query_state.filter_state, last_run, this_run);
|
||||
QueryManyIter {
|
||||
query_state,
|
||||
|
@ -316,7 +316,7 @@ where
|
|||
///
|
||||
/// It is always safe for shared access.
|
||||
#[inline(always)]
|
||||
unsafe fn fetch_next_aliased_unchecked(&mut self) -> Option<Q::Item<'w>> {
|
||||
unsafe fn fetch_next_aliased_unchecked(&mut self) -> Option<D::Item<'w>> {
|
||||
for entity in self.entity_iter.by_ref() {
|
||||
let entity = *entity.borrow();
|
||||
let Some(location) = self.entities.get(entity) else {
|
||||
|
@ -339,7 +339,7 @@ where
|
|||
|
||||
// SAFETY: `archetype` is from the world that `fetch/filter` were created for,
|
||||
// `fetch_state`/`filter_state` are the states that `fetch/filter` were initialized with
|
||||
Q::set_archetype(
|
||||
D::set_archetype(
|
||||
&mut self.fetch,
|
||||
&self.query_state.fetch_state,
|
||||
archetype,
|
||||
|
@ -360,7 +360,7 @@ where
|
|||
// SAFETY:
|
||||
// - set_archetype was called prior, `location.archetype_row` is an archetype index in range of the current archetype
|
||||
// - fetch is only called once for each entity.
|
||||
return Some(Q::fetch(&mut self.fetch, entity, location.table_row));
|
||||
return Some(D::fetch(&mut self.fetch, entity, location.table_row));
|
||||
}
|
||||
}
|
||||
None
|
||||
|
@ -368,20 +368,20 @@ where
|
|||
|
||||
/// Get next result from the query
|
||||
#[inline(always)]
|
||||
pub fn fetch_next(&mut self) -> Option<Q::Item<'_>> {
|
||||
pub fn fetch_next(&mut self) -> Option<D::Item<'_>> {
|
||||
// SAFETY: we are limiting the returned reference to self,
|
||||
// making sure this method cannot be called multiple times without getting rid
|
||||
// of any previously returned unique references first, thus preventing aliasing.
|
||||
unsafe { self.fetch_next_aliased_unchecked().map(Q::shrink) }
|
||||
unsafe { self.fetch_next_aliased_unchecked().map(D::shrink) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'w, 's, Q: ReadOnlyQueryData, F: QueryFilter, I: Iterator> Iterator
|
||||
for QueryManyIter<'w, 's, Q, F, I>
|
||||
impl<'w, 's, D: ReadOnlyQueryData, F: QueryFilter, I: Iterator> Iterator
|
||||
for QueryManyIter<'w, 's, D, F, I>
|
||||
where
|
||||
I::Item: Borrow<Entity>,
|
||||
{
|
||||
type Item = Q::Item<'w>;
|
||||
type Item = D::Item<'w>;
|
||||
|
||||
#[inline(always)]
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
|
@ -396,8 +396,8 @@ where
|
|||
}
|
||||
|
||||
// This is correct as [`QueryManyIter`] always returns `None` once exhausted.
|
||||
impl<'w, 's, Q: ReadOnlyQueryData, F: QueryFilter, I: Iterator> FusedIterator
|
||||
for QueryManyIter<'w, 's, Q, F, I>
|
||||
impl<'w, 's, D: ReadOnlyQueryData, F: QueryFilter, I: Iterator> FusedIterator
|
||||
for QueryManyIter<'w, 's, D, F, I>
|
||||
where
|
||||
I::Item: Borrow<Entity>,
|
||||
{
|
||||
|
@ -466,30 +466,30 @@ where
|
|||
/// [`Query`]: crate::system::Query
|
||||
/// [`Query::iter_combinations`]: crate::system::Query::iter_combinations
|
||||
/// [`Query::iter_combinations_mut`]: crate::system::Query::iter_combinations_mut
|
||||
pub struct QueryCombinationIter<'w, 's, Q: QueryData, F: QueryFilter, const K: usize> {
|
||||
pub struct QueryCombinationIter<'w, 's, D: QueryData, F: QueryFilter, const K: usize> {
|
||||
tables: &'w Tables,
|
||||
archetypes: &'w Archetypes,
|
||||
query_state: &'s QueryState<Q, F>,
|
||||
cursors: [QueryIterationCursor<'w, 's, Q, F>; K],
|
||||
query_state: &'s QueryState<D, F>,
|
||||
cursors: [QueryIterationCursor<'w, 's, D, F>; K],
|
||||
}
|
||||
|
||||
impl<'w, 's, Q: QueryData, F: QueryFilter, const K: usize> QueryCombinationIter<'w, 's, Q, F, K> {
|
||||
impl<'w, 's, D: QueryData, F: QueryFilter, const K: usize> QueryCombinationIter<'w, 's, D, F, K> {
|
||||
/// # Safety
|
||||
/// - `world` must have permission to access any of the components registered in `query_state`.
|
||||
/// - `world` must be the same one used to initialize `query_state`.
|
||||
pub(crate) unsafe fn new(
|
||||
world: UnsafeWorldCell<'w>,
|
||||
query_state: &'s QueryState<Q, F>,
|
||||
query_state: &'s QueryState<D, F>,
|
||||
last_run: Tick,
|
||||
this_run: Tick,
|
||||
) -> Self {
|
||||
// Initialize array with cursors.
|
||||
// There is no FromIterator on arrays, so instead initialize it manually with MaybeUninit
|
||||
|
||||
let mut array: MaybeUninit<[QueryIterationCursor<'w, 's, Q, F>; K]> = MaybeUninit::uninit();
|
||||
let mut array: MaybeUninit<[QueryIterationCursor<'w, 's, D, F>; K]> = MaybeUninit::uninit();
|
||||
let ptr = array
|
||||
.as_mut_ptr()
|
||||
.cast::<QueryIterationCursor<'w, 's, Q, F>>();
|
||||
.cast::<QueryIterationCursor<'w, 's, D, F>>();
|
||||
if K != 0 {
|
||||
ptr.write(QueryIterationCursor::init(
|
||||
world,
|
||||
|
@ -522,13 +522,13 @@ impl<'w, 's, Q: QueryData, F: QueryFilter, const K: usize> QueryCombinationIter<
|
|||
/// references to the same component, leading to unique reference aliasing.
|
||||
///.
|
||||
/// It is always safe for shared access.
|
||||
unsafe fn fetch_next_aliased_unchecked(&mut self) -> Option<[Q::Item<'w>; K]> {
|
||||
unsafe fn fetch_next_aliased_unchecked(&mut self) -> Option<[D::Item<'w>; K]> {
|
||||
if K == 0 {
|
||||
return None;
|
||||
}
|
||||
|
||||
// PERF: can speed up the following code using `cursor.remaining()` instead of `next_item.is_none()`
|
||||
// when Q::IS_ARCHETYPAL && F::IS_ARCHETYPAL
|
||||
// when D::IS_ARCHETYPAL && F::IS_ARCHETYPAL
|
||||
//
|
||||
// let `i` be the index of `c`, the last cursor in `self.cursors` that
|
||||
// returns `K-i` or more elements.
|
||||
|
@ -552,9 +552,9 @@ impl<'w, 's, Q: QueryData, F: QueryFilter, const K: usize> QueryCombinationIter<
|
|||
}
|
||||
}
|
||||
|
||||
let mut values = MaybeUninit::<[Q::Item<'w>; K]>::uninit();
|
||||
let mut values = MaybeUninit::<[D::Item<'w>; K]>::uninit();
|
||||
|
||||
let ptr = values.as_mut_ptr().cast::<Q::Item<'w>>();
|
||||
let ptr = values.as_mut_ptr().cast::<D::Item<'w>>();
|
||||
for (offset, cursor) in self.cursors.iter_mut().enumerate() {
|
||||
ptr.add(offset).write(cursor.peek_last().unwrap());
|
||||
}
|
||||
|
@ -564,13 +564,13 @@ impl<'w, 's, Q: QueryData, F: QueryFilter, const K: usize> QueryCombinationIter<
|
|||
|
||||
/// Get next combination of queried components
|
||||
#[inline]
|
||||
pub fn fetch_next(&mut self) -> Option<[Q::Item<'_>; K]> {
|
||||
pub fn fetch_next(&mut self) -> Option<[D::Item<'_>; K]> {
|
||||
// SAFETY: we are limiting the returned reference to self,
|
||||
// making sure this method cannot be called multiple times without getting rid
|
||||
// of any previously returned unique references first, thus preventing aliasing.
|
||||
unsafe {
|
||||
self.fetch_next_aliased_unchecked()
|
||||
.map(|array| array.map(Q::shrink))
|
||||
.map(|array| array.map(D::shrink))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -578,10 +578,10 @@ impl<'w, 's, Q: QueryData, F: QueryFilter, const K: usize> QueryCombinationIter<
|
|||
// Iterator type is intentionally implemented only for read-only access.
|
||||
// Doing so for mutable references would be unsound, because calling `next`
|
||||
// multiple times would allow multiple owned references to the same data to exist.
|
||||
impl<'w, 's, Q: ReadOnlyQueryData, F: QueryFilter, const K: usize> Iterator
|
||||
for QueryCombinationIter<'w, 's, Q, F, K>
|
||||
impl<'w, 's, D: ReadOnlyQueryData, F: QueryFilter, const K: usize> Iterator
|
||||
for QueryCombinationIter<'w, 's, D, F, K>
|
||||
{
|
||||
type Item = [Q::Item<'w>; K];
|
||||
type Item = [D::Item<'w>; K];
|
||||
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
|
@ -621,7 +621,7 @@ impl<'w, 's, Q: ReadOnlyQueryData, F: QueryFilter, const K: usize> Iterator
|
|||
}
|
||||
}
|
||||
|
||||
impl<'w, 's, Q: QueryData, F: QueryFilter> ExactSizeIterator for QueryIter<'w, 's, Q, F>
|
||||
impl<'w, 's, D: QueryData, F: QueryFilter> ExactSizeIterator for QueryIter<'w, 's, D, F>
|
||||
where
|
||||
F: ArchetypeFilter,
|
||||
{
|
||||
|
@ -631,25 +631,25 @@ where
|
|||
}
|
||||
|
||||
// This is correct as [`QueryCombinationIter`] always returns `None` once exhausted.
|
||||
impl<'w, 's, Q: ReadOnlyQueryData, F: QueryFilter, const K: usize> FusedIterator
|
||||
for QueryCombinationIter<'w, 's, Q, F, K>
|
||||
impl<'w, 's, D: ReadOnlyQueryData, F: QueryFilter, const K: usize> FusedIterator
|
||||
for QueryCombinationIter<'w, 's, D, F, K>
|
||||
{
|
||||
}
|
||||
|
||||
struct QueryIterationCursor<'w, 's, Q: QueryData, F: QueryFilter> {
|
||||
struct QueryIterationCursor<'w, 's, D: QueryData, F: QueryFilter> {
|
||||
table_id_iter: std::slice::Iter<'s, TableId>,
|
||||
archetype_id_iter: std::slice::Iter<'s, ArchetypeId>,
|
||||
table_entities: &'w [Entity],
|
||||
archetype_entities: &'w [ArchetypeEntity],
|
||||
fetch: Q::Fetch<'w>,
|
||||
fetch: D::Fetch<'w>,
|
||||
filter: F::Fetch<'w>,
|
||||
// length of the table table or length of the archetype, depending on whether both `Q`'s and `F`'s fetches are dense
|
||||
// length of the table table or length of the archetype, depending on whether both `D`'s and `F`'s fetches are dense
|
||||
current_len: usize,
|
||||
// either table row or archetype index, depending on whether both `Q`'s and `F`'s fetches are dense
|
||||
// either table row or archetype index, depending on whether both `D`'s and `F`'s fetches are dense
|
||||
current_row: usize,
|
||||
}
|
||||
|
||||
impl<Q: QueryData, F: QueryFilter> Clone for QueryIterationCursor<'_, '_, Q, F> {
|
||||
impl<D: QueryData, F: QueryFilter> Clone for QueryIterationCursor<'_, '_, D, F> {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
table_id_iter: self.table_id_iter.clone(),
|
||||
|
@ -664,12 +664,12 @@ impl<Q: QueryData, F: QueryFilter> Clone for QueryIterationCursor<'_, '_, Q, F>
|
|||
}
|
||||
}
|
||||
|
||||
impl<'w, 's, Q: QueryData, F: QueryFilter> QueryIterationCursor<'w, 's, Q, F> {
|
||||
const IS_DENSE: bool = Q::IS_DENSE && F::IS_DENSE;
|
||||
impl<'w, 's, D: QueryData, F: QueryFilter> QueryIterationCursor<'w, 's, D, F> {
|
||||
const IS_DENSE: bool = D::IS_DENSE && F::IS_DENSE;
|
||||
|
||||
unsafe fn init_empty(
|
||||
world: UnsafeWorldCell<'w>,
|
||||
query_state: &'s QueryState<Q, F>,
|
||||
query_state: &'s QueryState<D, F>,
|
||||
last_run: Tick,
|
||||
this_run: Tick,
|
||||
) -> Self {
|
||||
|
@ -685,11 +685,11 @@ impl<'w, 's, Q: QueryData, F: QueryFilter> QueryIterationCursor<'w, 's, Q, F> {
|
|||
/// - `world` must be the same one used to initialize `query_state`.
|
||||
unsafe fn init(
|
||||
world: UnsafeWorldCell<'w>,
|
||||
query_state: &'s QueryState<Q, F>,
|
||||
query_state: &'s QueryState<D, F>,
|
||||
last_run: Tick,
|
||||
this_run: Tick,
|
||||
) -> Self {
|
||||
let fetch = Q::init_fetch(world, &query_state.fetch_state, last_run, this_run);
|
||||
let fetch = D::init_fetch(world, &query_state.fetch_state, last_run, this_run);
|
||||
let filter = F::init_fetch(world, &query_state.filter_state, last_run, this_run);
|
||||
QueryIterationCursor {
|
||||
fetch,
|
||||
|
@ -705,19 +705,19 @@ impl<'w, 's, Q: QueryData, F: QueryFilter> QueryIterationCursor<'w, 's, Q, F> {
|
|||
|
||||
/// retrieve item returned from most recent `next` call again.
|
||||
#[inline]
|
||||
unsafe fn peek_last(&mut self) -> Option<Q::Item<'w>> {
|
||||
unsafe fn peek_last(&mut self) -> Option<D::Item<'w>> {
|
||||
if self.current_row > 0 {
|
||||
let index = self.current_row - 1;
|
||||
if Self::IS_DENSE {
|
||||
let entity = self.table_entities.get_unchecked(index);
|
||||
Some(Q::fetch(
|
||||
Some(D::fetch(
|
||||
&mut self.fetch,
|
||||
*entity,
|
||||
TableRow::from_usize(index),
|
||||
))
|
||||
} else {
|
||||
let archetype_entity = self.archetype_entities.get_unchecked(index);
|
||||
Some(Q::fetch(
|
||||
Some(D::fetch(
|
||||
&mut self.fetch,
|
||||
archetype_entity.entity(),
|
||||
archetype_entity.table_row(),
|
||||
|
@ -730,7 +730,7 @@ impl<'w, 's, Q: QueryData, F: QueryFilter> QueryIterationCursor<'w, 's, Q, F> {
|
|||
|
||||
/// How many values will this cursor return at most?
|
||||
///
|
||||
/// Note that if `Q::IS_ARCHETYPAL && F::IS_ARCHETYPAL`, the return value
|
||||
/// Note that if `D::IS_ARCHETYPAL && F::IS_ARCHETYPAL`, the return value
|
||||
/// will be **the exact count of remaining values**.
|
||||
fn max_remaining(&self, tables: &'w Tables, archetypes: &'w Archetypes) -> usize {
|
||||
let remaining_matched: usize = if Self::IS_DENSE {
|
||||
|
@ -754,8 +754,8 @@ impl<'w, 's, Q: QueryData, F: QueryFilter> QueryIterationCursor<'w, 's, Q, F> {
|
|||
&mut self,
|
||||
tables: &'w Tables,
|
||||
archetypes: &'w Archetypes,
|
||||
query_state: &'s QueryState<Q, F>,
|
||||
) -> Option<Q::Item<'w>> {
|
||||
query_state: &'s QueryState<D, F>,
|
||||
) -> Option<D::Item<'w>> {
|
||||
if Self::IS_DENSE {
|
||||
loop {
|
||||
// we are on the beginning of the query, or finished processing a table, so skip to the next
|
||||
|
@ -764,7 +764,7 @@ impl<'w, 's, Q: QueryData, F: QueryFilter> QueryIterationCursor<'w, 's, Q, F> {
|
|||
let table = tables.get(*table_id).debug_checked_unwrap();
|
||||
// SAFETY: `table` is from the world that `fetch/filter` were created for,
|
||||
// `fetch_state`/`filter_state` are the states that `fetch/filter` were initialized with
|
||||
Q::set_table(&mut self.fetch, &query_state.fetch_state, table);
|
||||
D::set_table(&mut self.fetch, &query_state.fetch_state, table);
|
||||
F::set_table(&mut self.filter, &query_state.filter_state, table);
|
||||
self.table_entities = table.entities();
|
||||
self.current_len = table.entity_count();
|
||||
|
@ -786,7 +786,7 @@ impl<'w, 's, Q: QueryData, F: QueryFilter> QueryIterationCursor<'w, 's, Q, F> {
|
|||
// - `current_row` must be a table row in range of the current table,
|
||||
// because if it was not, then the if above would have been executed.
|
||||
// - fetch is only called once for each `entity`.
|
||||
let item = Q::fetch(&mut self.fetch, *entity, row);
|
||||
let item = D::fetch(&mut self.fetch, *entity, row);
|
||||
|
||||
self.current_row += 1;
|
||||
return Some(item);
|
||||
|
@ -799,7 +799,7 @@ impl<'w, 's, Q: QueryData, F: QueryFilter> QueryIterationCursor<'w, 's, Q, F> {
|
|||
let table = tables.get(archetype.table_id()).debug_checked_unwrap();
|
||||
// SAFETY: `archetype` and `tables` are from the world that `fetch/filter` were created for,
|
||||
// `fetch_state`/`filter_state` are the states that `fetch/filter` were initialized with
|
||||
Q::set_archetype(&mut self.fetch, &query_state.fetch_state, archetype, table);
|
||||
D::set_archetype(&mut self.fetch, &query_state.fetch_state, archetype, table);
|
||||
F::set_archetype(
|
||||
&mut self.filter,
|
||||
&query_state.filter_state,
|
||||
|
@ -829,7 +829,7 @@ impl<'w, 's, Q: QueryData, F: QueryFilter> QueryIterationCursor<'w, 's, Q, F> {
|
|||
// - `current_row` must be an archetype index row in range of the current archetype,
|
||||
// because if it was not, then the if above would have been executed.
|
||||
// - fetch is only called once for each `archetype_entity`.
|
||||
let item = Q::fetch(
|
||||
let item = D::fetch(
|
||||
&mut self.fetch,
|
||||
archetype_entity.entity(),
|
||||
archetype_entity.table_row(),
|
||||
|
|
|
@ -115,13 +115,13 @@ mod tests {
|
|||
let ns = (n - k + 1..=n).rev();
|
||||
ks.zip(ns).fold(1, |acc, (k, n)| acc * n / k)
|
||||
}
|
||||
fn assert_combination<Q, F, const K: usize>(world: &mut World, expected_size: usize)
|
||||
fn assert_combination<D, F, const K: usize>(world: &mut World, expected_size: usize)
|
||||
where
|
||||
Q: ReadOnlyQueryData,
|
||||
D: ReadOnlyQueryData,
|
||||
F: ArchetypeFilter,
|
||||
{
|
||||
let mut query = world.query_filtered::<Q, F>();
|
||||
let query_type = type_name::<QueryCombinationIter<Q, F, K>>();
|
||||
let mut query = world.query_filtered::<D, F>();
|
||||
let query_type = type_name::<QueryCombinationIter<D, F, K>>();
|
||||
let iter = query.iter_combinations::<K>(world);
|
||||
assert_all_sizes_iterator_equal(iter, expected_size, 0, query_type);
|
||||
let iter = query.iter_combinations::<K>(world);
|
||||
|
@ -129,24 +129,24 @@ mod tests {
|
|||
let iter = query.iter_combinations::<K>(world);
|
||||
assert_all_sizes_iterator_equal(iter, expected_size, 5, query_type);
|
||||
}
|
||||
fn assert_all_sizes_equal<Q, F>(world: &mut World, expected_size: usize)
|
||||
fn assert_all_sizes_equal<D, F>(world: &mut World, expected_size: usize)
|
||||
where
|
||||
Q: ReadOnlyQueryData,
|
||||
D: ReadOnlyQueryData,
|
||||
F: ArchetypeFilter,
|
||||
{
|
||||
let mut query = world.query_filtered::<Q, F>();
|
||||
let query_type = type_name::<QueryState<Q, F>>();
|
||||
let mut query = world.query_filtered::<D, F>();
|
||||
let query_type = type_name::<QueryState<D, F>>();
|
||||
assert_all_exact_sizes_iterator_equal(query.iter(world), expected_size, 0, query_type);
|
||||
assert_all_exact_sizes_iterator_equal(query.iter(world), expected_size, 1, query_type);
|
||||
assert_all_exact_sizes_iterator_equal(query.iter(world), expected_size, 5, query_type);
|
||||
|
||||
let expected = expected_size;
|
||||
assert_combination::<Q, F, 0>(world, choose(expected, 0));
|
||||
assert_combination::<Q, F, 1>(world, choose(expected, 1));
|
||||
assert_combination::<Q, F, 2>(world, choose(expected, 2));
|
||||
assert_combination::<Q, F, 5>(world, choose(expected, 5));
|
||||
assert_combination::<Q, F, 43>(world, choose(expected, 43));
|
||||
assert_combination::<Q, F, 64>(world, choose(expected, 64));
|
||||
assert_combination::<D, F, 0>(world, choose(expected, 0));
|
||||
assert_combination::<D, F, 1>(world, choose(expected, 1));
|
||||
assert_combination::<D, F, 2>(world, choose(expected, 2));
|
||||
assert_combination::<D, F, 5>(world, choose(expected, 5));
|
||||
assert_combination::<D, F, 43>(world, choose(expected, 43));
|
||||
assert_combination::<D, F, 64>(world, choose(expected, 64));
|
||||
}
|
||||
fn assert_all_exact_sizes_iterator_equal(
|
||||
iterator: impl ExactSizeIterator,
|
||||
|
|
|
@ -82,15 +82,15 @@ impl BatchingStrategy {
|
|||
///
|
||||
/// This struct is created by the [`Query::par_iter`](crate::system::Query::par_iter) and
|
||||
/// [`Query::par_iter_mut`](crate::system::Query::par_iter_mut) methods.
|
||||
pub struct QueryParIter<'w, 's, Q: QueryData, F: QueryFilter> {
|
||||
pub struct QueryParIter<'w, 's, D: QueryData, F: QueryFilter> {
|
||||
pub(crate) world: UnsafeWorldCell<'w>,
|
||||
pub(crate) state: &'s QueryState<Q, F>,
|
||||
pub(crate) state: &'s QueryState<D, F>,
|
||||
pub(crate) last_run: Tick,
|
||||
pub(crate) this_run: Tick,
|
||||
pub(crate) batching_strategy: BatchingStrategy,
|
||||
}
|
||||
|
||||
impl<'w, 's, Q: QueryData, F: QueryFilter> QueryParIter<'w, 's, Q, F> {
|
||||
impl<'w, 's, D: QueryData, F: QueryFilter> QueryParIter<'w, 's, D, F> {
|
||||
/// Changes the batching strategy used when iterating.
|
||||
///
|
||||
/// For more information on how this affects the resultant iteration, see
|
||||
|
@ -108,7 +108,7 @@ impl<'w, 's, Q: QueryData, F: QueryFilter> QueryParIter<'w, 's, Q, F> {
|
|||
///
|
||||
/// [`ComputeTaskPool`]: bevy_tasks::ComputeTaskPool
|
||||
#[inline]
|
||||
pub fn for_each<FN: Fn(QueryItem<'w, Q>) + Send + Sync + Clone>(self, func: FN) {
|
||||
pub fn for_each<FN: Fn(QueryItem<'w, D>) + Send + Sync + Clone>(self, func: FN) {
|
||||
#[cfg(any(target = "wasm32", not(feature = "multi-threaded")))]
|
||||
{
|
||||
// SAFETY:
|
||||
|
@ -160,7 +160,7 @@ impl<'w, 's, Q: QueryData, F: QueryFilter> QueryParIter<'w, 's, Q, F> {
|
|||
thread_count > 0,
|
||||
"Attempted to run parallel iteration over a query with an empty TaskPool"
|
||||
);
|
||||
let max_size = if Q::IS_DENSE && F::IS_DENSE {
|
||||
let max_size = if D::IS_DENSE && F::IS_DENSE {
|
||||
// SAFETY: We only access table metadata.
|
||||
let tables = unsafe { &self.world.world_metadata().storages().tables };
|
||||
self.state
|
||||
|
|
|
@ -24,9 +24,9 @@ use super::{
|
|||
/// Provides scoped access to a [`World`] state according to a given [`QueryData`] and [`QueryFilter`].
|
||||
#[repr(C)]
|
||||
// SAFETY NOTE:
|
||||
// Do not add any new fields that use the `Q` or `F` generic parameters as this may
|
||||
// Do not add any new fields that use the `D` or `F` generic parameters as this may
|
||||
// make `QueryState::as_transmuted_state` unsound if not done with care.
|
||||
pub struct QueryState<Q: QueryData, F: QueryFilter = ()> {
|
||||
pub struct QueryState<D: QueryData, F: QueryFilter = ()> {
|
||||
world_id: WorldId,
|
||||
pub(crate) archetype_generation: ArchetypeGeneration,
|
||||
pub(crate) matched_tables: FixedBitSet,
|
||||
|
@ -37,13 +37,13 @@ pub struct QueryState<Q: QueryData, F: QueryFilter = ()> {
|
|||
pub(crate) matched_table_ids: Vec<TableId>,
|
||||
// NOTE: we maintain both a ArchetypeId bitset and a vec because iterating the vec is faster
|
||||
pub(crate) matched_archetype_ids: Vec<ArchetypeId>,
|
||||
pub(crate) fetch_state: Q::State,
|
||||
pub(crate) fetch_state: D::State,
|
||||
pub(crate) filter_state: F::State,
|
||||
#[cfg(feature = "trace")]
|
||||
par_iter_span: Span,
|
||||
}
|
||||
|
||||
impl<Q: QueryData, F: QueryFilter> fmt::Debug for QueryState<Q, F> {
|
||||
impl<D: QueryData, F: QueryFilter> fmt::Debug for QueryState<D, F> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("QueryState")
|
||||
.field("world_id", &self.world_id)
|
||||
|
@ -53,18 +53,18 @@ impl<Q: QueryData, F: QueryFilter> fmt::Debug for QueryState<Q, F> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<Q: QueryData, F: QueryFilter> FromWorld for QueryState<Q, F> {
|
||||
impl<D: QueryData, F: QueryFilter> FromWorld for QueryState<D, F> {
|
||||
fn from_world(world: &mut World) -> Self {
|
||||
world.query_filtered()
|
||||
}
|
||||
}
|
||||
|
||||
impl<Q: QueryData, F: QueryFilter> QueryState<Q, F> {
|
||||
impl<D: QueryData, F: QueryFilter> QueryState<D, F> {
|
||||
/// Converts this `QueryState` reference to a `QueryState` that does not access anything mutably.
|
||||
pub fn as_readonly(&self) -> &QueryState<Q::ReadOnly, F> {
|
||||
// SAFETY: invariant on `WorldQuery` trait upholds that `Q::ReadOnly` and `F::ReadOnly`
|
||||
// have a subset of the access, and match the exact same archetypes/tables as `Q`/`F` respectively.
|
||||
unsafe { self.as_transmuted_state::<Q::ReadOnly, F>() }
|
||||
pub fn as_readonly(&self) -> &QueryState<D::ReadOnly, F> {
|
||||
// SAFETY: invariant on `WorldQuery` trait upholds that `D::ReadOnly` and `F::ReadOnly`
|
||||
// have a subset of the access, and match the exact same archetypes/tables as `D`/`F` respectively.
|
||||
unsafe { self.as_transmuted_state::<D::ReadOnly, F>() }
|
||||
}
|
||||
|
||||
/// Converts this `QueryState` reference to a `QueryState` that does not return any data
|
||||
|
@ -72,10 +72,10 @@ impl<Q: QueryData, F: QueryFilter> QueryState<Q, F> {
|
|||
///
|
||||
/// This doesn't use `NopWorldQuery` as it loses filter functionality, for example
|
||||
/// `NopWorldQuery<Changed<T>>` is functionally equivalent to `With<T>`.
|
||||
pub fn as_nop(&self) -> &QueryState<NopWorldQuery<Q>, F> {
|
||||
pub fn as_nop(&self) -> &QueryState<NopWorldQuery<D>, F> {
|
||||
// SAFETY: `NopWorldQuery` doesn't have any accesses and defers to
|
||||
// `Q` for table/archetype matching
|
||||
unsafe { self.as_transmuted_state::<NopWorldQuery<Q>, F>() }
|
||||
// `D` for table/archetype matching
|
||||
unsafe { self.as_transmuted_state::<NopWorldQuery<D>, F>() }
|
||||
}
|
||||
|
||||
/// Converts this `QueryState` reference to any other `QueryState` with
|
||||
|
@ -85,26 +85,26 @@ impl<Q: QueryData, F: QueryFilter> QueryState<Q, F> {
|
|||
///
|
||||
/// # SAFETY
|
||||
///
|
||||
/// `NewQ` must have a subset of the access that `Q` does and match the exact same archetypes/tables
|
||||
/// `NewD` must have a subset of the access that `D` does and match the exact same archetypes/tables
|
||||
/// `NewF` must have a subset of the access that `F` does and match the exact same archetypes/tables
|
||||
pub(crate) unsafe fn as_transmuted_state<
|
||||
NewQ: QueryData<State = Q::State>,
|
||||
NewD: QueryData<State = D::State>,
|
||||
NewF: QueryFilter<State = F::State>,
|
||||
>(
|
||||
&self,
|
||||
) -> &QueryState<NewQ, NewF> {
|
||||
&*(self as *const QueryState<Q, F> as *const QueryState<NewQ, NewF>)
|
||||
) -> &QueryState<NewD, NewF> {
|
||||
&*(self as *const QueryState<D, F> as *const QueryState<NewD, NewF>)
|
||||
}
|
||||
}
|
||||
|
||||
impl<Q: QueryData, F: QueryFilter> QueryState<Q, F> {
|
||||
impl<D: QueryData, F: QueryFilter> QueryState<D, F> {
|
||||
/// Creates a new [`QueryState`] from a given [`World`] and inherits the result of `world.id()`.
|
||||
pub fn new(world: &mut World) -> Self {
|
||||
let fetch_state = Q::init_state(world);
|
||||
let fetch_state = D::init_state(world);
|
||||
let filter_state = F::init_state(world);
|
||||
|
||||
let mut component_access = FilteredAccess::default();
|
||||
Q::update_component_access(&fetch_state, &mut component_access);
|
||||
D::update_component_access(&fetch_state, &mut component_access);
|
||||
|
||||
// Use a temporary empty FilteredAccess for filters. This prevents them from conflicting with the
|
||||
// main Query's `fetch_state` access. Filters are allowed to conflict with the main query fetch
|
||||
|
@ -130,7 +130,7 @@ impl<Q: QueryData, F: QueryFilter> QueryState<Q, F> {
|
|||
#[cfg(feature = "trace")]
|
||||
par_iter_span: bevy_utils::tracing::info_span!(
|
||||
"par_for_each",
|
||||
query = std::any::type_name::<Q>(),
|
||||
query = std::any::type_name::<D>(),
|
||||
filter = std::any::type_name::<F>(),
|
||||
),
|
||||
};
|
||||
|
@ -248,10 +248,10 @@ impl<Q: QueryData, F: QueryFilter> QueryState<Q, F> {
|
|||
/// Update the current [`QueryState`] with information from the provided [`Archetype`]
|
||||
/// (if applicable, i.e. if the archetype has any intersecting [`ComponentId`] with the current [`QueryState`]).
|
||||
pub fn new_archetype(&mut self, archetype: &Archetype) {
|
||||
if Q::matches_component_set(&self.fetch_state, &|id| archetype.contains(id))
|
||||
if D::matches_component_set(&self.fetch_state, &|id| archetype.contains(id))
|
||||
&& F::matches_component_set(&self.filter_state, &|id| archetype.contains(id))
|
||||
{
|
||||
Q::update_archetype_component_access(
|
||||
D::update_archetype_component_access(
|
||||
&self.fetch_state,
|
||||
archetype,
|
||||
&mut self.archetype_component_access,
|
||||
|
@ -284,7 +284,7 @@ impl<Q: QueryData, F: QueryFilter> QueryState<Q, F> {
|
|||
&mut self,
|
||||
world: &'w World,
|
||||
entity: Entity,
|
||||
) -> Result<ROQueryItem<'w, Q>, QueryEntityError> {
|
||||
) -> Result<ROQueryItem<'w, D>, QueryEntityError> {
|
||||
self.update_archetypes(world);
|
||||
// SAFETY: query is read only
|
||||
unsafe {
|
||||
|
@ -334,7 +334,7 @@ impl<Q: QueryData, F: QueryFilter> QueryState<Q, F> {
|
|||
&mut self,
|
||||
world: &'w World,
|
||||
entities: [Entity; N],
|
||||
) -> Result<[ROQueryItem<'w, Q>; N], QueryEntityError> {
|
||||
) -> Result<[ROQueryItem<'w, D>; N], QueryEntityError> {
|
||||
self.update_archetypes(world);
|
||||
|
||||
// SAFETY:
|
||||
|
@ -356,7 +356,7 @@ impl<Q: QueryData, F: QueryFilter> QueryState<Q, F> {
|
|||
&mut self,
|
||||
world: &'w mut World,
|
||||
entity: Entity,
|
||||
) -> Result<Q::Item<'w>, QueryEntityError> {
|
||||
) -> Result<D::Item<'w>, QueryEntityError> {
|
||||
self.update_archetypes(world);
|
||||
let change_tick = world.change_tick();
|
||||
let last_change_tick = world.last_change_tick();
|
||||
|
@ -414,7 +414,7 @@ impl<Q: QueryData, F: QueryFilter> QueryState<Q, F> {
|
|||
&mut self,
|
||||
world: &'w mut World,
|
||||
entities: [Entity; N],
|
||||
) -> Result<[Q::Item<'w>; N], QueryEntityError> {
|
||||
) -> Result<[D::Item<'w>; N], QueryEntityError> {
|
||||
self.update_archetypes(world);
|
||||
|
||||
let change_tick = world.change_tick();
|
||||
|
@ -447,7 +447,7 @@ impl<Q: QueryData, F: QueryFilter> QueryState<Q, F> {
|
|||
&self,
|
||||
world: &'w World,
|
||||
entity: Entity,
|
||||
) -> Result<ROQueryItem<'w, Q>, QueryEntityError> {
|
||||
) -> Result<ROQueryItem<'w, D>, QueryEntityError> {
|
||||
self.validate_world(world.id());
|
||||
// SAFETY: query is read only and world is validated
|
||||
unsafe {
|
||||
|
@ -471,7 +471,7 @@ impl<Q: QueryData, F: QueryFilter> QueryState<Q, F> {
|
|||
&mut self,
|
||||
world: UnsafeWorldCell<'w>,
|
||||
entity: Entity,
|
||||
) -> Result<Q::Item<'w>, QueryEntityError> {
|
||||
) -> Result<D::Item<'w>, QueryEntityError> {
|
||||
self.update_archetypes_unsafe_world_cell(world);
|
||||
self.get_unchecked_manual(world, entity, world.last_change_tick(), world.change_tick())
|
||||
}
|
||||
|
@ -492,7 +492,7 @@ impl<Q: QueryData, F: QueryFilter> QueryState<Q, F> {
|
|||
entity: Entity,
|
||||
last_run: Tick,
|
||||
this_run: Tick,
|
||||
) -> Result<Q::Item<'w>, QueryEntityError> {
|
||||
) -> Result<D::Item<'w>, QueryEntityError> {
|
||||
let location = world
|
||||
.entities()
|
||||
.get(entity)
|
||||
|
@ -507,7 +507,7 @@ impl<Q: QueryData, F: QueryFilter> QueryState<Q, F> {
|
|||
.archetypes()
|
||||
.get(location.archetype_id)
|
||||
.debug_checked_unwrap();
|
||||
let mut fetch = Q::init_fetch(world, &self.fetch_state, last_run, this_run);
|
||||
let mut fetch = D::init_fetch(world, &self.fetch_state, last_run, this_run);
|
||||
let mut filter = F::init_fetch(world, &self.filter_state, last_run, this_run);
|
||||
|
||||
let table = world
|
||||
|
@ -515,11 +515,11 @@ impl<Q: QueryData, F: QueryFilter> QueryState<Q, F> {
|
|||
.tables
|
||||
.get(location.table_id)
|
||||
.debug_checked_unwrap();
|
||||
Q::set_archetype(&mut fetch, &self.fetch_state, archetype, table);
|
||||
D::set_archetype(&mut fetch, &self.fetch_state, archetype, table);
|
||||
F::set_archetype(&mut filter, &self.filter_state, archetype, table);
|
||||
|
||||
if F::filter_fetch(&mut filter, entity, location.table_row) {
|
||||
Ok(Q::fetch(&mut fetch, entity, location.table_row))
|
||||
Ok(D::fetch(&mut fetch, entity, location.table_row))
|
||||
} else {
|
||||
Err(QueryEntityError::QueryDoesNotMatch(entity))
|
||||
}
|
||||
|
@ -644,7 +644,7 @@ impl<Q: QueryData, F: QueryFilter> QueryState<Q, F> {
|
|||
entities: [Entity; N],
|
||||
last_run: Tick,
|
||||
this_run: Tick,
|
||||
) -> Result<[ROQueryItem<'w, Q>; N], QueryEntityError> {
|
||||
) -> Result<[ROQueryItem<'w, D>; N], QueryEntityError> {
|
||||
let mut values = [(); N].map(|_| MaybeUninit::uninit());
|
||||
|
||||
for (value, entity) in std::iter::zip(&mut values, entities) {
|
||||
|
@ -676,7 +676,7 @@ impl<Q: QueryData, F: QueryFilter> QueryState<Q, F> {
|
|||
entities: [Entity; N],
|
||||
last_run: Tick,
|
||||
this_run: Tick,
|
||||
) -> Result<[Q::Item<'w>; N], QueryEntityError> {
|
||||
) -> Result<[D::Item<'w>; N], QueryEntityError> {
|
||||
// Verify that all entities are unique
|
||||
for i in 0..N {
|
||||
for j in 0..i {
|
||||
|
@ -701,7 +701,7 @@ impl<Q: QueryData, F: QueryFilter> QueryState<Q, F> {
|
|||
///
|
||||
/// This can only be called for read-only queries, see [`Self::iter_mut`] for write-queries.
|
||||
#[inline]
|
||||
pub fn iter<'w, 's>(&'s mut self, world: &'w World) -> QueryIter<'w, 's, Q::ReadOnly, F> {
|
||||
pub fn iter<'w, 's>(&'s mut self, world: &'w World) -> QueryIter<'w, 's, D::ReadOnly, F> {
|
||||
self.update_archetypes(world);
|
||||
// SAFETY: query is read only
|
||||
unsafe {
|
||||
|
@ -715,7 +715,7 @@ impl<Q: QueryData, F: QueryFilter> QueryState<Q, F> {
|
|||
|
||||
/// Returns an [`Iterator`] over the query results for the given [`World`].
|
||||
#[inline]
|
||||
pub fn iter_mut<'w, 's>(&'s mut self, world: &'w mut World) -> QueryIter<'w, 's, Q, F> {
|
||||
pub fn iter_mut<'w, 's>(&'s mut self, world: &'w mut World) -> QueryIter<'w, 's, D, F> {
|
||||
self.update_archetypes(world);
|
||||
let change_tick = world.change_tick();
|
||||
let last_change_tick = world.last_change_tick();
|
||||
|
@ -730,7 +730,7 @@ impl<Q: QueryData, F: QueryFilter> QueryState<Q, F> {
|
|||
///
|
||||
/// This can only be called for read-only queries.
|
||||
#[inline]
|
||||
pub fn iter_manual<'w, 's>(&'s self, world: &'w World) -> QueryIter<'w, 's, Q::ReadOnly, F> {
|
||||
pub fn iter_manual<'w, 's>(&'s self, world: &'w World) -> QueryIter<'w, 's, D::ReadOnly, F> {
|
||||
self.validate_world(world.id());
|
||||
// SAFETY: query is read only and world is validated
|
||||
unsafe {
|
||||
|
@ -767,7 +767,7 @@ impl<Q: QueryData, F: QueryFilter> QueryState<Q, F> {
|
|||
pub fn iter_combinations<'w, 's, const K: usize>(
|
||||
&'s mut self,
|
||||
world: &'w World,
|
||||
) -> QueryCombinationIter<'w, 's, Q::ReadOnly, F, K> {
|
||||
) -> QueryCombinationIter<'w, 's, D::ReadOnly, F, K> {
|
||||
self.update_archetypes(world);
|
||||
// SAFETY: query is read only
|
||||
unsafe {
|
||||
|
@ -800,7 +800,7 @@ impl<Q: QueryData, F: QueryFilter> QueryState<Q, F> {
|
|||
pub fn iter_combinations_mut<'w, 's, const K: usize>(
|
||||
&'s mut self,
|
||||
world: &'w mut World,
|
||||
) -> QueryCombinationIter<'w, 's, Q, F, K> {
|
||||
) -> QueryCombinationIter<'w, 's, D, F, K> {
|
||||
self.update_archetypes(world);
|
||||
let change_tick = world.change_tick();
|
||||
let last_change_tick = world.last_change_tick();
|
||||
|
@ -827,7 +827,7 @@ impl<Q: QueryData, F: QueryFilter> QueryState<Q, F> {
|
|||
&'s mut self,
|
||||
world: &'w World,
|
||||
entities: EntityList,
|
||||
) -> QueryManyIter<'w, 's, Q::ReadOnly, F, EntityList::IntoIter>
|
||||
) -> QueryManyIter<'w, 's, D::ReadOnly, F, EntityList::IntoIter>
|
||||
where
|
||||
EntityList::Item: Borrow<Entity>,
|
||||
{
|
||||
|
@ -862,7 +862,7 @@ impl<Q: QueryData, F: QueryFilter> QueryState<Q, F> {
|
|||
&'s self,
|
||||
world: &'w World,
|
||||
entities: EntityList,
|
||||
) -> QueryManyIter<'w, 's, Q::ReadOnly, F, EntityList::IntoIter>
|
||||
) -> QueryManyIter<'w, 's, D::ReadOnly, F, EntityList::IntoIter>
|
||||
where
|
||||
EntityList::Item: Borrow<Entity>,
|
||||
{
|
||||
|
@ -887,7 +887,7 @@ impl<Q: QueryData, F: QueryFilter> QueryState<Q, F> {
|
|||
&'s mut self,
|
||||
world: &'w mut World,
|
||||
entities: EntityList,
|
||||
) -> QueryManyIter<'w, 's, Q, F, EntityList::IntoIter>
|
||||
) -> QueryManyIter<'w, 's, D, F, EntityList::IntoIter>
|
||||
where
|
||||
EntityList::Item: Borrow<Entity>,
|
||||
{
|
||||
|
@ -915,7 +915,7 @@ impl<Q: QueryData, F: QueryFilter> QueryState<Q, F> {
|
|||
pub unsafe fn iter_unchecked<'w, 's>(
|
||||
&'s mut self,
|
||||
world: UnsafeWorldCell<'w>,
|
||||
) -> QueryIter<'w, 's, Q, F> {
|
||||
) -> QueryIter<'w, 's, D, F> {
|
||||
self.update_archetypes_unsafe_world_cell(world);
|
||||
self.iter_unchecked_manual(world, world.last_change_tick(), world.change_tick())
|
||||
}
|
||||
|
@ -932,7 +932,7 @@ impl<Q: QueryData, F: QueryFilter> QueryState<Q, F> {
|
|||
pub unsafe fn iter_combinations_unchecked<'w, 's, const K: usize>(
|
||||
&'s mut self,
|
||||
world: UnsafeWorldCell<'w>,
|
||||
) -> QueryCombinationIter<'w, 's, Q, F, K> {
|
||||
) -> QueryCombinationIter<'w, 's, D, F, K> {
|
||||
self.update_archetypes_unsafe_world_cell(world);
|
||||
self.iter_combinations_unchecked_manual(
|
||||
world,
|
||||
|
@ -956,7 +956,7 @@ impl<Q: QueryData, F: QueryFilter> QueryState<Q, F> {
|
|||
world: UnsafeWorldCell<'w>,
|
||||
last_run: Tick,
|
||||
this_run: Tick,
|
||||
) -> QueryIter<'w, 's, Q, F> {
|
||||
) -> QueryIter<'w, 's, D, F> {
|
||||
QueryIter::new(world, self, last_run, this_run)
|
||||
}
|
||||
|
||||
|
@ -977,7 +977,7 @@ impl<Q: QueryData, F: QueryFilter> QueryState<Q, F> {
|
|||
world: UnsafeWorldCell<'w>,
|
||||
last_run: Tick,
|
||||
this_run: Tick,
|
||||
) -> QueryManyIter<'w, 's, Q, F, EntityList::IntoIter>
|
||||
) -> QueryManyIter<'w, 's, D, F, EntityList::IntoIter>
|
||||
where
|
||||
EntityList::Item: Borrow<Entity>,
|
||||
{
|
||||
|
@ -1000,7 +1000,7 @@ impl<Q: QueryData, F: QueryFilter> QueryState<Q, F> {
|
|||
world: UnsafeWorldCell<'w>,
|
||||
last_run: Tick,
|
||||
this_run: Tick,
|
||||
) -> QueryCombinationIter<'w, 's, Q, F, K> {
|
||||
) -> QueryCombinationIter<'w, 's, D, F, K> {
|
||||
QueryCombinationIter::new(world, self, last_run, this_run)
|
||||
}
|
||||
|
||||
|
@ -1015,7 +1015,7 @@ impl<Q: QueryData, F: QueryFilter> QueryState<Q, F> {
|
|||
since = "0.13.0",
|
||||
note = "QueryState::for_each was not idiomatic Rust and has been moved to query.iter().for_each()"
|
||||
)]
|
||||
pub fn for_each<'w, FN: FnMut(ROQueryItem<'w, Q>)>(&mut self, world: &'w World, func: FN) {
|
||||
pub fn for_each<'w, FN: FnMut(ROQueryItem<'w, D>)>(&mut self, world: &'w World, func: FN) {
|
||||
self.iter(world).for_each(func);
|
||||
}
|
||||
|
||||
|
@ -1028,7 +1028,7 @@ impl<Q: QueryData, F: QueryFilter> QueryState<Q, F> {
|
|||
since = "0.13.0",
|
||||
note = "QueryState::for_each_mut was not idiomatic Rust and has been moved to query.iter_mut().for_each()"
|
||||
)]
|
||||
pub fn for_each_mut<'w, FN: FnMut(Q::Item<'w>)>(&mut self, world: &'w mut World, func: FN) {
|
||||
pub fn for_each_mut<'w, FN: FnMut(D::Item<'w>)>(&mut self, world: &'w mut World, func: FN) {
|
||||
self.iter_mut(world).for_each(func);
|
||||
}
|
||||
|
||||
|
@ -1044,7 +1044,7 @@ impl<Q: QueryData, F: QueryFilter> QueryState<Q, F> {
|
|||
since = "0.13.0",
|
||||
note = "QueryState::for_each_unchecked was not idiomatic Rust and has been moved to query.iter_unchecked_manual().for_each()"
|
||||
)]
|
||||
pub unsafe fn for_each_unchecked<'w, FN: FnMut(Q::Item<'w>)>(
|
||||
pub unsafe fn for_each_unchecked<'w, FN: FnMut(D::Item<'w>)>(
|
||||
&mut self,
|
||||
world: UnsafeWorldCell<'w>,
|
||||
func: FN,
|
||||
|
@ -1063,7 +1063,7 @@ impl<Q: QueryData, F: QueryFilter> QueryState<Q, F> {
|
|||
pub fn par_iter<'w, 's>(
|
||||
&'s mut self,
|
||||
world: &'w World,
|
||||
) -> QueryParIter<'w, 's, Q::ReadOnly, F> {
|
||||
) -> QueryParIter<'w, 's, D::ReadOnly, F> {
|
||||
self.update_archetypes(world);
|
||||
QueryParIter {
|
||||
world: world.as_unsafe_world_cell_readonly(),
|
||||
|
@ -1080,7 +1080,7 @@ impl<Q: QueryData, F: QueryFilter> QueryState<Q, F> {
|
|||
///
|
||||
/// [`par_iter`]: Self::par_iter
|
||||
#[inline]
|
||||
pub fn par_iter_mut<'w, 's>(&'s mut self, world: &'w mut World) -> QueryParIter<'w, 's, Q, F> {
|
||||
pub fn par_iter_mut<'w, 's>(&'s mut self, world: &'w mut World) -> QueryParIter<'w, 's, D, F> {
|
||||
self.update_archetypes(world);
|
||||
let this_run = world.change_tick();
|
||||
let last_run = world.last_change_tick();
|
||||
|
@ -1112,7 +1112,7 @@ impl<Q: QueryData, F: QueryFilter> QueryState<Q, F> {
|
|||
#[cfg(all(not(target = "wasm32"), feature = "multi-threaded"))]
|
||||
pub(crate) unsafe fn par_for_each_unchecked_manual<
|
||||
'w,
|
||||
FN: Fn(Q::Item<'w>) + Send + Sync + Clone,
|
||||
FN: Fn(D::Item<'w>) + Send + Sync + Clone,
|
||||
>(
|
||||
&self,
|
||||
world: UnsafeWorldCell<'w>,
|
||||
|
@ -1124,7 +1124,7 @@ impl<Q: QueryData, F: QueryFilter> QueryState<Q, F> {
|
|||
// NOTE: If you are changing query iteration code, remember to update the following places, where relevant:
|
||||
// QueryIter, QueryIterationCursor, QueryManyIter, QueryCombinationIter, QueryState::for_each_unchecked_manual, QueryState::par_for_each_unchecked_manual
|
||||
bevy_tasks::ComputeTaskPool::get().scope(|scope| {
|
||||
if Q::IS_DENSE && F::IS_DENSE {
|
||||
if D::IS_DENSE && F::IS_DENSE {
|
||||
// SAFETY: We only access table data that has been registered in `self.archetype_component_access`.
|
||||
let tables = &world.storages().tables;
|
||||
for table_id in &self.matched_table_ids {
|
||||
|
@ -1192,7 +1192,7 @@ impl<Q: QueryData, F: QueryFilter> QueryState<Q, F> {
|
|||
/// [`get_single`](Self::get_single) to return a `Result` instead of panicking.
|
||||
#[track_caller]
|
||||
#[inline]
|
||||
pub fn single<'w>(&mut self, world: &'w World) -> ROQueryItem<'w, Q> {
|
||||
pub fn single<'w>(&mut self, world: &'w World) -> ROQueryItem<'w, D> {
|
||||
match self.get_single(world) {
|
||||
Ok(items) => items,
|
||||
Err(error) => panic!("Cannot get single mutable query result: {error}"),
|
||||
|
@ -1211,7 +1211,7 @@ impl<Q: QueryData, F: QueryFilter> QueryState<Q, F> {
|
|||
pub fn get_single<'w>(
|
||||
&mut self,
|
||||
world: &'w World,
|
||||
) -> Result<ROQueryItem<'w, Q>, QuerySingleError> {
|
||||
) -> Result<ROQueryItem<'w, D>, QuerySingleError> {
|
||||
self.update_archetypes(world);
|
||||
|
||||
// SAFETY: query is read only
|
||||
|
@ -1233,7 +1233,7 @@ impl<Q: QueryData, F: QueryFilter> QueryState<Q, F> {
|
|||
/// [`get_single_mut`](Self::get_single_mut) to return a `Result` instead of panicking.
|
||||
#[track_caller]
|
||||
#[inline]
|
||||
pub fn single_mut<'w>(&mut self, world: &'w mut World) -> Q::Item<'w> {
|
||||
pub fn single_mut<'w>(&mut self, world: &'w mut World) -> D::Item<'w> {
|
||||
// SAFETY: query has unique world access
|
||||
match self.get_single_mut(world) {
|
||||
Ok(items) => items,
|
||||
|
@ -1250,7 +1250,7 @@ impl<Q: QueryData, F: QueryFilter> QueryState<Q, F> {
|
|||
pub fn get_single_mut<'w>(
|
||||
&mut self,
|
||||
world: &'w mut World,
|
||||
) -> Result<Q::Item<'w>, QuerySingleError> {
|
||||
) -> Result<D::Item<'w>, QuerySingleError> {
|
||||
self.update_archetypes(world);
|
||||
|
||||
let change_tick = world.change_tick();
|
||||
|
@ -1278,7 +1278,7 @@ impl<Q: QueryData, F: QueryFilter> QueryState<Q, F> {
|
|||
pub unsafe fn get_single_unchecked<'w>(
|
||||
&mut self,
|
||||
world: UnsafeWorldCell<'w>,
|
||||
) -> Result<Q::Item<'w>, QuerySingleError> {
|
||||
) -> Result<D::Item<'w>, QuerySingleError> {
|
||||
self.update_archetypes_unsafe_world_cell(world);
|
||||
self.get_single_unchecked_manual(world, world.last_change_tick(), world.change_tick())
|
||||
}
|
||||
|
@ -1299,7 +1299,7 @@ impl<Q: QueryData, F: QueryFilter> QueryState<Q, F> {
|
|||
world: UnsafeWorldCell<'w>,
|
||||
last_run: Tick,
|
||||
this_run: Tick,
|
||||
) -> Result<Q::Item<'w>, QuerySingleError> {
|
||||
) -> Result<D::Item<'w>, QuerySingleError> {
|
||||
let mut query = self.iter_unchecked_manual(world, last_run, this_run);
|
||||
let first = query.next();
|
||||
let extra = query.next().is_some();
|
||||
|
|
|
@ -29,11 +29,11 @@ pub trait ExclusiveSystemParam: Sized {
|
|||
/// for a given [`ExclusiveSystemParam`].
|
||||
pub type ExclusiveSystemParamItem<'s, P> = <P as ExclusiveSystemParam>::Item<'s>;
|
||||
|
||||
impl<'a, Q: QueryData + 'static, F: QueryFilter + 'static> ExclusiveSystemParam
|
||||
for &'a mut QueryState<Q, F>
|
||||
impl<'a, D: QueryData + 'static, F: QueryFilter + 'static> ExclusiveSystemParam
|
||||
for &'a mut QueryState<D, F>
|
||||
{
|
||||
type State = QueryState<Q, F>;
|
||||
type Item<'s> = &'s mut QueryState<Q, F>;
|
||||
type State = QueryState<D, F>;
|
||||
type Item<'s> = &'s mut QueryState<D, F>;
|
||||
|
||||
fn init(world: &mut World, _system_meta: &mut SystemMeta) -> Self::State {
|
||||
QueryState::new(world)
|
||||
|
|
|
@ -18,7 +18,7 @@ use std::{any::TypeId, borrow::Borrow};
|
|||
///
|
||||
/// `Query` is a generic data structure that accepts two type parameters:
|
||||
///
|
||||
/// - **`Q` (query fetch).**
|
||||
/// - **`D` (query data).**
|
||||
/// The type of data contained in the query item.
|
||||
/// Only entities that match the requested data will generate an item.
|
||||
/// Must implement the [`QueryData`] trait.
|
||||
|
@ -325,10 +325,10 @@ use std::{any::TypeId, borrow::Borrow};
|
|||
/// [`Table`]: crate::storage::Table
|
||||
/// [`With`]: crate::query::With
|
||||
/// [`Without`]: crate::query::Without
|
||||
pub struct Query<'world, 'state, Q: QueryData, F: QueryFilter = ()> {
|
||||
pub struct Query<'world, 'state, D: QueryData, F: QueryFilter = ()> {
|
||||
// SAFETY: Must have access to the components registered in `state`.
|
||||
world: UnsafeWorldCell<'world>,
|
||||
state: &'state QueryState<Q, F>,
|
||||
state: &'state QueryState<D, F>,
|
||||
last_run: Tick,
|
||||
this_run: Tick,
|
||||
// SAFETY: This is used to ensure that `get_component_mut::<C>` properly fails when a Query writes C
|
||||
|
@ -339,7 +339,7 @@ pub struct Query<'world, 'state, Q: QueryData, F: QueryFilter = ()> {
|
|||
force_read_only_component_access: bool,
|
||||
}
|
||||
|
||||
impl<Q: QueryData, F: QueryFilter> std::fmt::Debug for Query<'_, '_, Q, F> {
|
||||
impl<D: QueryData, F: QueryFilter> std::fmt::Debug for Query<'_, '_, D, F> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
f.debug_struct("Query")
|
||||
.field("matched_entities", &self.iter().count())
|
||||
|
@ -351,7 +351,7 @@ impl<Q: QueryData, F: QueryFilter> std::fmt::Debug for Query<'_, '_, Q, F> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'w, 's, Q: QueryData, F: QueryFilter> Query<'w, 's, Q, F> {
|
||||
impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> {
|
||||
/// Creates a new query.
|
||||
///
|
||||
/// # Panics
|
||||
|
@ -365,7 +365,7 @@ impl<'w, 's, Q: QueryData, F: QueryFilter> Query<'w, 's, Q, F> {
|
|||
#[inline]
|
||||
pub(crate) unsafe fn new(
|
||||
world: UnsafeWorldCell<'w>,
|
||||
state: &'s QueryState<Q, F>,
|
||||
state: &'s QueryState<D, F>,
|
||||
last_run: Tick,
|
||||
this_run: Tick,
|
||||
force_read_only_component_access: bool,
|
||||
|
@ -383,10 +383,10 @@ impl<'w, 's, Q: QueryData, F: QueryFilter> Query<'w, 's, Q, F> {
|
|||
|
||||
/// Returns another `Query` from this that fetches the read-only version of the query items.
|
||||
///
|
||||
/// For example, `Query<(&mut A, &B, &mut C), With<D>>` will become `Query<(&A, &B, &C), With<D>>`.
|
||||
/// For example, `Query<(&mut D1, &D2, &mut D3), With<F>>` will become `Query<(&D1, &D2, &D3), With<F>>`.
|
||||
/// This can be useful when working around the borrow checker,
|
||||
/// or reusing functionality between systems via functions that accept query types.
|
||||
pub fn to_readonly(&self) -> Query<'_, 's, Q::ReadOnly, F> {
|
||||
pub fn to_readonly(&self) -> Query<'_, 's, D::ReadOnly, F> {
|
||||
let new_state = self.state.as_readonly();
|
||||
// SAFETY: This is memory safe because it turns the query immutable.
|
||||
unsafe {
|
||||
|
@ -427,7 +427,7 @@ impl<'w, 's, Q: QueryData, F: QueryFilter> Query<'w, 's, Q, F> {
|
|||
/// - [`iter_mut`](Self::iter_mut) for mutable query items.
|
||||
/// - [`for_each`](Self::for_each) for the closure based alternative.
|
||||
#[inline]
|
||||
pub fn iter(&self) -> QueryIter<'_, 's, Q::ReadOnly, F> {
|
||||
pub fn iter(&self) -> QueryIter<'_, 's, D::ReadOnly, F> {
|
||||
// SAFETY:
|
||||
// - `self.world` has permission to access the required components.
|
||||
// - The query is read-only, so it can be aliased even if it was originally mutable.
|
||||
|
@ -463,7 +463,7 @@ impl<'w, 's, Q: QueryData, F: QueryFilter> Query<'w, 's, Q, F> {
|
|||
/// - [`iter`](Self::iter) for read-only query items.
|
||||
/// - [`for_each_mut`](Self::for_each_mut) for the closure based alternative.
|
||||
#[inline]
|
||||
pub fn iter_mut(&mut self) -> QueryIter<'_, 's, Q, F> {
|
||||
pub fn iter_mut(&mut self) -> QueryIter<'_, 's, D, F> {
|
||||
// SAFETY: `self.world` has permission to access the required components.
|
||||
unsafe {
|
||||
self.state
|
||||
|
@ -493,7 +493,7 @@ impl<'w, 's, Q: QueryData, F: QueryFilter> Query<'w, 's, Q, F> {
|
|||
#[inline]
|
||||
pub fn iter_combinations<const K: usize>(
|
||||
&self,
|
||||
) -> QueryCombinationIter<'_, 's, Q::ReadOnly, F, K> {
|
||||
) -> QueryCombinationIter<'_, 's, D::ReadOnly, F, K> {
|
||||
// SAFETY:
|
||||
// - `self.world` has permission to access the required components.
|
||||
// - The query is read-only, so it can be aliased even if it was originally mutable.
|
||||
|
@ -528,7 +528,7 @@ impl<'w, 's, Q: QueryData, F: QueryFilter> Query<'w, 's, Q, F> {
|
|||
#[inline]
|
||||
pub fn iter_combinations_mut<const K: usize>(
|
||||
&mut self,
|
||||
) -> QueryCombinationIter<'_, 's, Q, F, K> {
|
||||
) -> QueryCombinationIter<'_, 's, D, F, K> {
|
||||
// SAFETY: `self.world` has permission to access the required components.
|
||||
unsafe {
|
||||
self.state
|
||||
|
@ -576,7 +576,7 @@ impl<'w, 's, Q: QueryData, F: QueryFilter> Query<'w, 's, Q, F> {
|
|||
pub fn iter_many<EntityList: IntoIterator>(
|
||||
&self,
|
||||
entities: EntityList,
|
||||
) -> QueryManyIter<'_, 's, Q::ReadOnly, F, EntityList::IntoIter>
|
||||
) -> QueryManyIter<'_, 's, D::ReadOnly, F, EntityList::IntoIter>
|
||||
where
|
||||
EntityList::Item: Borrow<Entity>,
|
||||
{
|
||||
|
@ -630,7 +630,7 @@ impl<'w, 's, Q: QueryData, F: QueryFilter> Query<'w, 's, Q, F> {
|
|||
pub fn iter_many_mut<EntityList: IntoIterator>(
|
||||
&mut self,
|
||||
entities: EntityList,
|
||||
) -> QueryManyIter<'_, 's, Q, F, EntityList::IntoIter>
|
||||
) -> QueryManyIter<'_, 's, D, F, EntityList::IntoIter>
|
||||
where
|
||||
EntityList::Item: Borrow<Entity>,
|
||||
{
|
||||
|
@ -656,7 +656,7 @@ impl<'w, 's, Q: QueryData, F: QueryFilter> Query<'w, 's, Q, F> {
|
|||
///
|
||||
/// - [`iter`](Self::iter) and [`iter_mut`](Self::iter_mut) for the safe versions.
|
||||
#[inline]
|
||||
pub unsafe fn iter_unsafe(&self) -> QueryIter<'_, 's, Q, F> {
|
||||
pub unsafe fn iter_unsafe(&self) -> QueryIter<'_, 's, D, F> {
|
||||
// SAFETY:
|
||||
// - `self.world` has permission to access the required components.
|
||||
// - The caller ensures that this operation will not result in any aliased mutable accesses.
|
||||
|
@ -677,7 +677,7 @@ impl<'w, 's, Q: QueryData, F: QueryFilter> Query<'w, 's, Q, F> {
|
|||
#[inline]
|
||||
pub unsafe fn iter_combinations_unsafe<const K: usize>(
|
||||
&self,
|
||||
) -> QueryCombinationIter<'_, 's, Q, F, K> {
|
||||
) -> QueryCombinationIter<'_, 's, D, F, K> {
|
||||
// SAFETY:
|
||||
// - `self.world` has permission to access the required components.
|
||||
// - The caller ensures that this operation will not result in any aliased mutable accesses.
|
||||
|
@ -699,7 +699,7 @@ impl<'w, 's, Q: QueryData, F: QueryFilter> Query<'w, 's, Q, F> {
|
|||
pub unsafe fn iter_many_unsafe<EntityList: IntoIterator>(
|
||||
&self,
|
||||
entities: EntityList,
|
||||
) -> QueryManyIter<'_, 's, Q, F, EntityList::IntoIter>
|
||||
) -> QueryManyIter<'_, 's, D, F, EntityList::IntoIter>
|
||||
where
|
||||
EntityList::Item: Borrow<Entity>,
|
||||
{
|
||||
|
@ -741,7 +741,7 @@ impl<'w, 's, Q: QueryData, F: QueryFilter> Query<'w, 's, Q, F> {
|
|||
since = "0.13.0",
|
||||
note = "Query::for_each was not idiomatic Rust and has been moved to query.iter().for_each()"
|
||||
)]
|
||||
pub fn for_each<'this>(&'this self, f: impl FnMut(ROQueryItem<'this, Q>)) {
|
||||
pub fn for_each<'this>(&'this self, f: impl FnMut(ROQueryItem<'this, D>)) {
|
||||
// SAFETY:
|
||||
// - `self.world` has permission to access the required components.
|
||||
// - The query is read-only, so it can be aliased even if it was originally mutable.
|
||||
|
@ -784,7 +784,7 @@ impl<'w, 's, Q: QueryData, F: QueryFilter> Query<'w, 's, Q, F> {
|
|||
since = "0.13.0",
|
||||
note = "Query::for_each_mut was not idiomatic Rust and has been moved to query.iter_mut().for_each()"
|
||||
)]
|
||||
pub fn for_each_mut<'a>(&'a mut self, f: impl FnMut(Q::Item<'a>)) {
|
||||
pub fn for_each_mut<'a>(&'a mut self, f: impl FnMut(D::Item<'a>)) {
|
||||
// SAFETY: `self.world` has permission to access the required components.
|
||||
unsafe {
|
||||
self.state
|
||||
|
@ -800,7 +800,7 @@ impl<'w, 's, Q: QueryData, F: QueryFilter> Query<'w, 's, Q, F> {
|
|||
/// [`par_iter_mut`]: Self::par_iter_mut
|
||||
/// [`World`]: crate::world::World
|
||||
#[inline]
|
||||
pub fn par_iter(&self) -> QueryParIter<'_, '_, Q::ReadOnly, F> {
|
||||
pub fn par_iter(&self) -> QueryParIter<'_, '_, D::ReadOnly, F> {
|
||||
QueryParIter {
|
||||
world: self.world,
|
||||
state: self.state.as_readonly(),
|
||||
|
@ -817,7 +817,7 @@ impl<'w, 's, Q: QueryData, F: QueryFilter> Query<'w, 's, Q, F> {
|
|||
/// [`par_iter`]: Self::par_iter
|
||||
/// [`World`]: crate::world::World
|
||||
#[inline]
|
||||
pub fn par_iter_mut(&mut self) -> QueryParIter<'_, '_, Q, F> {
|
||||
pub fn par_iter_mut(&mut self) -> QueryParIter<'_, '_, D, F> {
|
||||
QueryParIter {
|
||||
world: self.world,
|
||||
state: self.state,
|
||||
|
@ -859,7 +859,7 @@ impl<'w, 's, Q: QueryData, F: QueryFilter> Query<'w, 's, Q, F> {
|
|||
///
|
||||
/// - [`get_mut`](Self::get_mut) to get a mutable query item.
|
||||
#[inline]
|
||||
pub fn get(&self, entity: Entity) -> Result<ROQueryItem<'_, Q>, QueryEntityError> {
|
||||
pub fn get(&self, entity: Entity) -> Result<ROQueryItem<'_, D>, QueryEntityError> {
|
||||
// SAFETY: system runs without conflicts with other systems.
|
||||
// same-system queries have runtime borrow checks when they conflict
|
||||
unsafe {
|
||||
|
@ -886,7 +886,7 @@ impl<'w, 's, Q: QueryData, F: QueryFilter> Query<'w, 's, Q, F> {
|
|||
pub fn get_many<const N: usize>(
|
||||
&self,
|
||||
entities: [Entity; N],
|
||||
) -> Result<[ROQueryItem<'_, Q>; N], QueryEntityError> {
|
||||
) -> Result<[ROQueryItem<'_, D>; N], QueryEntityError> {
|
||||
// SAFETY:
|
||||
// - `&self` ensures there is no mutable access to any components accessible to this query.
|
||||
// - `self.world` matches `self.state`.
|
||||
|
@ -938,7 +938,7 @@ impl<'w, 's, Q: QueryData, F: QueryFilter> Query<'w, 's, Q, F> {
|
|||
///
|
||||
/// - [`get_many`](Self::get_many) for the non-panicking version.
|
||||
#[inline]
|
||||
pub fn many<const N: usize>(&self, entities: [Entity; N]) -> [ROQueryItem<'_, Q>; N] {
|
||||
pub fn many<const N: usize>(&self, entities: [Entity; N]) -> [ROQueryItem<'_, D>; N] {
|
||||
match self.get_many(entities) {
|
||||
Ok(items) => items,
|
||||
Err(error) => panic!("Cannot get query results: {error}"),
|
||||
|
@ -973,7 +973,7 @@ impl<'w, 's, Q: QueryData, F: QueryFilter> Query<'w, 's, Q, F> {
|
|||
///
|
||||
/// - [`get`](Self::get) to get a read-only query item.
|
||||
#[inline]
|
||||
pub fn get_mut(&mut self, entity: Entity) -> Result<Q::Item<'_>, QueryEntityError> {
|
||||
pub fn get_mut(&mut self, entity: Entity) -> Result<D::Item<'_>, QueryEntityError> {
|
||||
// SAFETY: system runs without conflicts with other systems.
|
||||
// same-system queries have runtime borrow checks when they conflict
|
||||
unsafe {
|
||||
|
@ -995,7 +995,7 @@ impl<'w, 's, Q: QueryData, F: QueryFilter> Query<'w, 's, Q, F> {
|
|||
pub fn get_many_mut<const N: usize>(
|
||||
&mut self,
|
||||
entities: [Entity; N],
|
||||
) -> Result<[Q::Item<'_>; N], QueryEntityError> {
|
||||
) -> Result<[D::Item<'_>; N], QueryEntityError> {
|
||||
// SAFETY: scheduler ensures safe Query world access
|
||||
unsafe {
|
||||
self.state
|
||||
|
@ -1052,7 +1052,7 @@ impl<'w, 's, Q: QueryData, F: QueryFilter> Query<'w, 's, Q, F> {
|
|||
/// - [`get_many_mut`](Self::get_many_mut) for the non panicking version.
|
||||
/// - [`many`](Self::many) to get read-only query items.
|
||||
#[inline]
|
||||
pub fn many_mut<const N: usize>(&mut self, entities: [Entity; N]) -> [Q::Item<'_>; N] {
|
||||
pub fn many_mut<const N: usize>(&mut self, entities: [Entity; N]) -> [D::Item<'_>; N] {
|
||||
match self.get_many_mut(entities) {
|
||||
Ok(items) => items,
|
||||
Err(error) => panic!("Cannot get query result: {error}"),
|
||||
|
@ -1072,7 +1072,7 @@ impl<'w, 's, Q: QueryData, F: QueryFilter> Query<'w, 's, Q, F> {
|
|||
///
|
||||
/// - [`get_mut`](Self::get_mut) for the safe version.
|
||||
#[inline]
|
||||
pub unsafe fn get_unchecked(&self, entity: Entity) -> Result<Q::Item<'_>, QueryEntityError> {
|
||||
pub unsafe fn get_unchecked(&self, entity: Entity) -> Result<D::Item<'_>, QueryEntityError> {
|
||||
// SEMI-SAFETY: system runs without conflicts with other systems.
|
||||
// same-system queries have runtime borrow checks when they conflict
|
||||
self.state
|
||||
|
@ -1250,7 +1250,7 @@ impl<'w, 's, Q: QueryData, F: QueryFilter> Query<'w, 's, Q, F> {
|
|||
/// - [`get_single`](Self::get_single) for the non-panicking version.
|
||||
/// - [`single_mut`](Self::single_mut) to get the mutable query item.
|
||||
#[track_caller]
|
||||
pub fn single(&self) -> ROQueryItem<'_, Q> {
|
||||
pub fn single(&self) -> ROQueryItem<'_, D> {
|
||||
self.get_single().unwrap()
|
||||
}
|
||||
|
||||
|
@ -1286,7 +1286,7 @@ impl<'w, 's, Q: QueryData, F: QueryFilter> Query<'w, 's, Q, F> {
|
|||
/// - [`get_single_mut`](Self::get_single_mut) to get the mutable query item.
|
||||
/// - [`single`](Self::single) for the panicking version.
|
||||
#[inline]
|
||||
pub fn get_single(&self) -> Result<ROQueryItem<'_, Q>, QuerySingleError> {
|
||||
pub fn get_single(&self) -> Result<ROQueryItem<'_, D>, QuerySingleError> {
|
||||
// SAFETY:
|
||||
// the query ensures that the components it accesses are not mutably accessible somewhere else
|
||||
// and the query is read only.
|
||||
|
@ -1327,7 +1327,7 @@ impl<'w, 's, Q: QueryData, F: QueryFilter> Query<'w, 's, Q, F> {
|
|||
/// - [`get_single_mut`](Self::get_single_mut) for the non-panicking version.
|
||||
/// - [`single`](Self::single) to get the read-only query item.
|
||||
#[track_caller]
|
||||
pub fn single_mut(&mut self) -> Q::Item<'_> {
|
||||
pub fn single_mut(&mut self) -> D::Item<'_> {
|
||||
self.get_single_mut().unwrap()
|
||||
}
|
||||
|
||||
|
@ -1357,7 +1357,7 @@ impl<'w, 's, Q: QueryData, F: QueryFilter> Query<'w, 's, Q, F> {
|
|||
/// - [`get_single`](Self::get_single) to get the read-only query item.
|
||||
/// - [`single_mut`](Self::single_mut) for the panicking version.
|
||||
#[inline]
|
||||
pub fn get_single_mut(&mut self) -> Result<Q::Item<'_>, QuerySingleError> {
|
||||
pub fn get_single_mut(&mut self) -> Result<D::Item<'_>, QuerySingleError> {
|
||||
// SAFETY:
|
||||
// the query ensures mutable access to the components it accesses, and the query
|
||||
// is uniquely borrowed
|
||||
|
@ -1433,25 +1433,25 @@ impl<'w, 's, Q: QueryData, F: QueryFilter> Query<'w, 's, Q, F> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'w, 's, Q: QueryData, F: QueryFilter> IntoIterator for &'w Query<'_, 's, Q, F> {
|
||||
type Item = ROQueryItem<'w, Q>;
|
||||
type IntoIter = QueryIter<'w, 's, Q::ReadOnly, F>;
|
||||
impl<'w, 's, D: QueryData, F: QueryFilter> IntoIterator for &'w Query<'_, 's, D, F> {
|
||||
type Item = ROQueryItem<'w, D>;
|
||||
type IntoIter = QueryIter<'w, 's, D::ReadOnly, F>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
self.iter()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'w, 's, Q: QueryData, F: QueryFilter> IntoIterator for &'w mut Query<'_, 's, Q, F> {
|
||||
type Item = Q::Item<'w>;
|
||||
type IntoIter = QueryIter<'w, 's, Q, F>;
|
||||
impl<'w, 's, D: QueryData, F: QueryFilter> IntoIterator for &'w mut Query<'_, 's, D, F> {
|
||||
type Item = D::Item<'w>;
|
||||
type IntoIter = QueryIter<'w, 's, D, F>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
self.iter_mut()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'w, 's, Q: ReadOnlyQueryData, F: QueryFilter> Query<'w, 's, Q, F> {
|
||||
impl<'w, 's, D: ReadOnlyQueryData, F: QueryFilter> Query<'w, 's, D, F> {
|
||||
/// Returns the query item for the given [`Entity`], with the actual "inner" world lifetime.
|
||||
///
|
||||
/// In case of a nonexisting entity or mismatched component, a [`QueryEntityError`] is
|
||||
|
@ -1485,7 +1485,7 @@ impl<'w, 's, Q: ReadOnlyQueryData, F: QueryFilter> Query<'w, 's, Q, F> {
|
|||
/// # bevy_ecs::system::assert_is_system(print_selected_character_name_system);
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn get_inner(&self, entity: Entity) -> Result<ROQueryItem<'w, Q>, QueryEntityError> {
|
||||
pub fn get_inner(&self, entity: Entity) -> Result<ROQueryItem<'w, D>, QueryEntityError> {
|
||||
// SAFETY: system runs without conflicts with other systems.
|
||||
// same-system queries have runtime borrow checks when they conflict
|
||||
unsafe {
|
||||
|
@ -1522,7 +1522,7 @@ impl<'w, 's, Q: ReadOnlyQueryData, F: QueryFilter> Query<'w, 's, Q, F> {
|
|||
/// # bevy_ecs::system::assert_is_system(report_names_system);
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn iter_inner(&self) -> QueryIter<'w, 's, Q::ReadOnly, F> {
|
||||
pub fn iter_inner(&self) -> QueryIter<'w, 's, D::ReadOnly, F> {
|
||||
// SAFETY: system runs without conflicts with other systems.
|
||||
// same-system queries have runtime borrow checks when they conflict
|
||||
unsafe {
|
||||
|
|
|
@ -153,22 +153,22 @@ pub unsafe trait ReadOnlySystemParam: SystemParam {}
|
|||
pub type SystemParamItem<'w, 's, P> = <P as SystemParam>::Item<'w, 's>;
|
||||
|
||||
// SAFETY: QueryState is constrained to read-only fetches, so it only reads World.
|
||||
unsafe impl<'w, 's, Q: ReadOnlyQueryData + 'static, F: QueryFilter + 'static> ReadOnlySystemParam
|
||||
for Query<'w, 's, Q, F>
|
||||
unsafe impl<'w, 's, D: ReadOnlyQueryData + 'static, F: QueryFilter + 'static> ReadOnlySystemParam
|
||||
for Query<'w, 's, D, F>
|
||||
{
|
||||
}
|
||||
|
||||
// SAFETY: Relevant query ComponentId and ArchetypeComponentId access is applied to SystemMeta. If
|
||||
// this Query conflicts with any prior access, a panic will occur.
|
||||
unsafe impl<Q: QueryData + 'static, F: QueryFilter + 'static> SystemParam for Query<'_, '_, Q, F> {
|
||||
type State = QueryState<Q, F>;
|
||||
type Item<'w, 's> = Query<'w, 's, Q, F>;
|
||||
unsafe impl<D: QueryData + 'static, F: QueryFilter + 'static> SystemParam for Query<'_, '_, D, F> {
|
||||
type State = QueryState<D, F>;
|
||||
type Item<'w, 's> = Query<'w, 's, D, F>;
|
||||
|
||||
fn init_state(world: &mut World, system_meta: &mut SystemMeta) -> Self::State {
|
||||
let state = QueryState::new(world);
|
||||
assert_component_access_compatibility(
|
||||
&system_meta.name,
|
||||
std::any::type_name::<Q>(),
|
||||
std::any::type_name::<D>(),
|
||||
std::any::type_name::<F>(),
|
||||
&system_meta.component_access_set,
|
||||
&state.component_access,
|
||||
|
@ -1408,7 +1408,7 @@ all_tuples!(impl_system_param_tuple, 0, 16, P);
|
|||
/// [`SystemParam`]: super::SystemParam
|
||||
pub mod lifetimeless {
|
||||
/// A [`Query`](super::Query) with `'static` lifetimes.
|
||||
pub type SQuery<Q, F = ()> = super::Query<'static, 'static, Q, F>;
|
||||
pub type SQuery<D, F = ()> = super::Query<'static, 'static, D, F>;
|
||||
/// A shorthand for writing `&'static T`.
|
||||
pub type Read<T> = &'static T;
|
||||
/// A shorthand for writing `&'static mut T`.
|
||||
|
@ -1566,10 +1566,10 @@ mod tests {
|
|||
pub struct SpecialQuery<
|
||||
'w,
|
||||
's,
|
||||
Q: QueryData + Send + Sync + 'static,
|
||||
D: QueryData + Send + Sync + 'static,
|
||||
F: QueryFilter + Send + Sync + 'static = (),
|
||||
> {
|
||||
_query: Query<'w, 's, Q, F>,
|
||||
_query: Query<'w, 's, D, F>,
|
||||
}
|
||||
|
||||
fn my_system(_: SpecialQuery<(), ()>) {}
|
||||
|
@ -1686,11 +1686,11 @@ mod tests {
|
|||
#[test]
|
||||
fn system_param_where_clause() {
|
||||
#[derive(SystemParam)]
|
||||
pub struct WhereParam<'w, 's, Q>
|
||||
pub struct WhereParam<'w, 's, D>
|
||||
where
|
||||
Q: 'static + QueryData,
|
||||
D: 'static + QueryData,
|
||||
{
|
||||
_q: Query<'w, 's, Q, ()>,
|
||||
_q: Query<'w, 's, D, ()>,
|
||||
}
|
||||
|
||||
fn my_system(_: WhereParam<()>) {}
|
||||
|
|
|
@ -991,8 +991,8 @@ impl World {
|
|||
/// ]);
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn query<Q: QueryData>(&mut self) -> QueryState<Q, ()> {
|
||||
self.query_filtered::<Q, ()>()
|
||||
pub fn query<D: QueryData>(&mut self) -> QueryState<D, ()> {
|
||||
self.query_filtered::<D, ()>()
|
||||
}
|
||||
|
||||
/// Returns [`QueryState`] for the given filtered [`QueryData`], which is used to efficiently
|
||||
|
@ -1015,7 +1015,7 @@ impl World {
|
|||
/// assert_eq!(matching_entities, vec![e2]);
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn query_filtered<Q: QueryData, F: QueryFilter>(&mut self) -> QueryState<Q, F> {
|
||||
pub fn query_filtered<D: QueryData, F: QueryFilter>(&mut self) -> QueryState<D, F> {
|
||||
QueryState::new(self)
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ use bevy_ecs::{
|
|||
use crate::{Children, Parent};
|
||||
|
||||
/// An extension trait for [`Query`] that adds hierarchy related methods.
|
||||
pub trait HierarchyQueryExt<'w, 's, Q: QueryData, F: QueryFilter> {
|
||||
pub trait HierarchyQueryExt<'w, 's, D: QueryData, F: QueryFilter> {
|
||||
/// Returns an [`Iterator`] of [`Entity`]s over all of `entity`s descendants.
|
||||
///
|
||||
/// Can only be called on a [`Query`] of [`Children`] (i.e. `Query<&Children>`).
|
||||
|
@ -30,9 +30,9 @@ pub trait HierarchyQueryExt<'w, 's, Q: QueryData, F: QueryFilter> {
|
|||
/// }
|
||||
/// # bevy_ecs::system::assert_is_system(system);
|
||||
/// ```
|
||||
fn iter_descendants(&'w self, entity: Entity) -> DescendantIter<'w, 's, Q, F>
|
||||
fn iter_descendants(&'w self, entity: Entity) -> DescendantIter<'w, 's, D, F>
|
||||
where
|
||||
Q::ReadOnly: WorldQuery<Item<'w> = &'w Children>;
|
||||
D::ReadOnly: WorldQuery<Item<'w> = &'w Children>;
|
||||
|
||||
/// Returns an [`Iterator`] of [`Entity`]s over all of `entity`s ancestors.
|
||||
///
|
||||
|
@ -52,22 +52,22 @@ pub trait HierarchyQueryExt<'w, 's, Q: QueryData, F: QueryFilter> {
|
|||
/// }
|
||||
/// # bevy_ecs::system::assert_is_system(system);
|
||||
/// ```
|
||||
fn iter_ancestors(&'w self, entity: Entity) -> AncestorIter<'w, 's, Q, F>
|
||||
fn iter_ancestors(&'w self, entity: Entity) -> AncestorIter<'w, 's, D, F>
|
||||
where
|
||||
Q::ReadOnly: WorldQuery<Item<'w> = &'w Parent>;
|
||||
D::ReadOnly: WorldQuery<Item<'w> = &'w Parent>;
|
||||
}
|
||||
|
||||
impl<'w, 's, Q: QueryData, F: QueryFilter> HierarchyQueryExt<'w, 's, Q, F> for Query<'w, 's, Q, F> {
|
||||
fn iter_descendants(&'w self, entity: Entity) -> DescendantIter<'w, 's, Q, F>
|
||||
impl<'w, 's, D: QueryData, F: QueryFilter> HierarchyQueryExt<'w, 's, D, F> for Query<'w, 's, D, F> {
|
||||
fn iter_descendants(&'w self, entity: Entity) -> DescendantIter<'w, 's, D, F>
|
||||
where
|
||||
Q::ReadOnly: WorldQuery<Item<'w> = &'w Children>,
|
||||
D::ReadOnly: WorldQuery<Item<'w> = &'w Children>,
|
||||
{
|
||||
DescendantIter::new(self, entity)
|
||||
}
|
||||
|
||||
fn iter_ancestors(&'w self, entity: Entity) -> AncestorIter<'w, 's, Q, F>
|
||||
fn iter_ancestors(&'w self, entity: Entity) -> AncestorIter<'w, 's, D, F>
|
||||
where
|
||||
Q::ReadOnly: WorldQuery<Item<'w> = &'w Parent>,
|
||||
D::ReadOnly: WorldQuery<Item<'w> = &'w Parent>,
|
||||
{
|
||||
AncestorIter::new(self, entity)
|
||||
}
|
||||
|
@ -76,20 +76,20 @@ impl<'w, 's, Q: QueryData, F: QueryFilter> HierarchyQueryExt<'w, 's, Q, F> for Q
|
|||
/// An [`Iterator`] of [`Entity`]s over the descendants of an [`Entity`].
|
||||
///
|
||||
/// Traverses the hierarchy breadth-first.
|
||||
pub struct DescendantIter<'w, 's, Q: QueryData, F: QueryFilter>
|
||||
pub struct DescendantIter<'w, 's, D: QueryData, F: QueryFilter>
|
||||
where
|
||||
Q::ReadOnly: WorldQuery<Item<'w> = &'w Children>,
|
||||
D::ReadOnly: WorldQuery<Item<'w> = &'w Children>,
|
||||
{
|
||||
children_query: &'w Query<'w, 's, Q, F>,
|
||||
children_query: &'w Query<'w, 's, D, F>,
|
||||
vecdeque: VecDeque<Entity>,
|
||||
}
|
||||
|
||||
impl<'w, 's, Q: QueryData, F: QueryFilter> DescendantIter<'w, 's, Q, F>
|
||||
impl<'w, 's, D: QueryData, F: QueryFilter> DescendantIter<'w, 's, D, F>
|
||||
where
|
||||
Q::ReadOnly: WorldQuery<Item<'w> = &'w Children>,
|
||||
D::ReadOnly: WorldQuery<Item<'w> = &'w Children>,
|
||||
{
|
||||
/// Returns a new [`DescendantIter`].
|
||||
pub fn new(children_query: &'w Query<'w, 's, Q, F>, entity: Entity) -> Self {
|
||||
pub fn new(children_query: &'w Query<'w, 's, D, F>, entity: Entity) -> Self {
|
||||
DescendantIter {
|
||||
children_query,
|
||||
vecdeque: children_query
|
||||
|
@ -102,9 +102,9 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<'w, 's, Q: QueryData, F: QueryFilter> Iterator for DescendantIter<'w, 's, Q, F>
|
||||
impl<'w, 's, D: QueryData, F: QueryFilter> Iterator for DescendantIter<'w, 's, D, F>
|
||||
where
|
||||
Q::ReadOnly: WorldQuery<Item<'w> = &'w Children>,
|
||||
D::ReadOnly: WorldQuery<Item<'w> = &'w Children>,
|
||||
{
|
||||
type Item = Entity;
|
||||
|
||||
|
@ -120,20 +120,20 @@ where
|
|||
}
|
||||
|
||||
/// An [`Iterator`] of [`Entity`]s over the ancestors of an [`Entity`].
|
||||
pub struct AncestorIter<'w, 's, Q: QueryData, F: QueryFilter>
|
||||
pub struct AncestorIter<'w, 's, D: QueryData, F: QueryFilter>
|
||||
where
|
||||
Q::ReadOnly: WorldQuery<Item<'w> = &'w Parent>,
|
||||
D::ReadOnly: WorldQuery<Item<'w> = &'w Parent>,
|
||||
{
|
||||
parent_query: &'w Query<'w, 's, Q, F>,
|
||||
parent_query: &'w Query<'w, 's, D, F>,
|
||||
next: Option<Entity>,
|
||||
}
|
||||
|
||||
impl<'w, 's, Q: QueryData, F: QueryFilter> AncestorIter<'w, 's, Q, F>
|
||||
impl<'w, 's, D: QueryData, F: QueryFilter> AncestorIter<'w, 's, D, F>
|
||||
where
|
||||
Q::ReadOnly: WorldQuery<Item<'w> = &'w Parent>,
|
||||
D::ReadOnly: WorldQuery<Item<'w> = &'w Parent>,
|
||||
{
|
||||
/// Returns a new [`AncestorIter`].
|
||||
pub fn new(parent_query: &'w Query<'w, 's, Q, F>, entity: Entity) -> Self {
|
||||
pub fn new(parent_query: &'w Query<'w, 's, D, F>, entity: Entity) -> Self {
|
||||
AncestorIter {
|
||||
parent_query,
|
||||
next: Some(entity),
|
||||
|
@ -141,9 +141,9 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<'w, 's, Q: QueryData, F: QueryFilter> Iterator for AncestorIter<'w, 's, Q, F>
|
||||
impl<'w, 's, D: QueryData, F: QueryFilter> Iterator for AncestorIter<'w, 's, D, F>
|
||||
where
|
||||
Q::ReadOnly: WorldQuery<Item<'w> = &'w Parent>,
|
||||
D::ReadOnly: WorldQuery<Item<'w> = &'w Parent>,
|
||||
{
|
||||
type Item = Entity;
|
||||
|
||||
|
|
Loading…
Reference in a new issue