From 5fd536202d4c14a42e7dc161cdee0ef05732473d Mon Sep 17 00:00:00 2001 From: targrub Date: Sat, 17 Sep 2022 21:10:53 -0400 Subject: [PATCH] Changing WorldQuery to ReadOnlyWorldQuery as per https://github.com/bevyengine/bevy/issues/6005. --- crates/bevy_ecs/src/lib.rs | 6 +++-- crates/bevy_ecs/src/query/iter.rs | 26 ++++++++++++---------- crates/bevy_ecs/src/query/mod.rs | 6 ++--- crates/bevy_ecs/src/query/state.rs | 12 +++++----- crates/bevy_ecs/src/system/query.rs | 10 ++++----- crates/bevy_ecs/src/system/system_param.rs | 17 +++++++++----- crates/bevy_ecs/src/world/mod.rs | 4 ++-- crates/bevy_ui/src/flex/mod.rs | 4 ++-- 8 files changed, 47 insertions(+), 38 deletions(-) diff --git a/crates/bevy_ecs/src/lib.rs b/crates/bevy_ecs/src/lib.rs index 124a7c7261369..f2328fdf0de7a 100644 --- a/crates/bevy_ecs/src/lib.rs +++ b/crates/bevy_ecs/src/lib.rs @@ -57,7 +57,9 @@ mod tests { bundle::Bundle, component::{Component, ComponentId}, entity::Entity, - query::{Added, ChangeTrackers, Changed, FilteredAccess, With, Without, WorldQuery}, + query::{ + Added, ChangeTrackers, Changed, FilteredAccess, ReadOnlyWorldQuery, With, Without, + }, system::Resource, world::{Mut, World}, }; @@ -902,7 +904,7 @@ mod tests { } } - fn get_filtered(world: &mut World) -> Vec { + fn get_filtered(world: &mut World) -> Vec { world .query_filtered::() .iter(world) diff --git a/crates/bevy_ecs/src/query/iter.rs b/crates/bevy_ecs/src/query/iter.rs index b75b13aa54e92..20f70a6c4340d 100644 --- a/crates/bevy_ecs/src/query/iter.rs +++ b/crates/bevy_ecs/src/query/iter.rs @@ -13,14 +13,14 @@ use super::{QueryFetch, QueryItem, ReadOnlyWorldQuery}; /// /// 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: WorldQuery, F: WorldQuery> { +pub struct QueryIter<'w, 's, Q: WorldQuery, F: ReadOnlyWorldQuery> { tables: &'w Tables, archetypes: &'w Archetypes, query_state: &'s QueryState, cursor: QueryIterationCursor<'w, 's, Q, F>, } -impl<'w, 's, Q: WorldQuery, F: WorldQuery> QueryIter<'w, 's, Q, F> { +impl<'w, 's, Q: WorldQuery, F: ReadOnlyWorldQuery> QueryIter<'w, 's, Q, F> { /// # Safety /// This does not check for mutable query correctness. To be safe, make sure mutable queries /// have unique access to the components they query. @@ -41,7 +41,7 @@ impl<'w, 's, Q: WorldQuery, F: WorldQuery> QueryIter<'w, 's, Q, F> { } } -impl<'w, 's, Q: WorldQuery, F: WorldQuery> Iterator for QueryIter<'w, 's, Q, F> { +impl<'w, 's, Q: WorldQuery, F: ReadOnlyWorldQuery> Iterator for QueryIter<'w, 's, Q, F> { type Item = QueryItem<'w, Q>; #[inline(always)] @@ -70,12 +70,12 @@ impl<'w, 's, Q: WorldQuery, F: WorldQuery> Iterator for QueryIter<'w, 's, Q, F> } // This is correct as [`QueryIter`] always returns `None` once exhausted. -impl<'w, 's, Q: WorldQuery, F: WorldQuery> FusedIterator for QueryIter<'w, 's, Q, F> {} +impl<'w, 's, Q: WorldQuery, F: ReadOnlyWorldQuery> FusedIterator for QueryIter<'w, 's, Q, F> {} /// An [`Iterator`] over [`Query`](crate::system::Query) results of a list of [`Entity`]s. /// /// 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: WorldQuery, F: WorldQuery, I: Iterator> +pub struct QueryManyIter<'w, 's, Q: WorldQuery, F: ReadOnlyWorldQuery, I: Iterator> where I::Item: Borrow, { @@ -88,7 +88,7 @@ where query_state: &'s QueryState, } -impl<'w, 's, Q: WorldQuery, F: WorldQuery, I: Iterator> QueryManyIter<'w, 's, Q, F, I> +impl<'w, 's, Q: WorldQuery, F: ReadOnlyWorldQuery, I: Iterator> QueryManyIter<'w, 's, Q, F, I> where I::Item: Borrow, { @@ -267,14 +267,16 @@ 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: WorldQuery, F: WorldQuery, const K: usize> { +pub struct QueryCombinationIter<'w, 's, Q: WorldQuery, F: ReadOnlyWorldQuery, const K: usize> { tables: &'w Tables, archetypes: &'w Archetypes, query_state: &'s QueryState, cursors: [QueryIterationCursor<'w, 's, Q, F>; K], } -impl<'w, 's, Q: WorldQuery, F: WorldQuery, const K: usize> QueryCombinationIter<'w, 's, Q, F, K> { +impl<'w, 's, Q: WorldQuery, F: ReadOnlyWorldQuery, const K: usize> + QueryCombinationIter<'w, 's, Q, F, K> +{ /// # Safety /// This does not check for mutable query correctness. To be safe, make sure mutable queries /// have unique access to the components they query. @@ -436,7 +438,7 @@ where } } -impl<'w, 's, Q: WorldQuery, F: WorldQuery> ExactSizeIterator for QueryIter<'w, 's, Q, F> +impl<'w, 's, Q: WorldQuery, F: ReadOnlyWorldQuery> ExactSizeIterator for QueryIter<'w, 's, Q, F> where F: ArchetypeFilter, { @@ -473,7 +475,7 @@ where { } -struct QueryIterationCursor<'w, 's, Q: WorldQuery, F: WorldQuery> { +struct QueryIterationCursor<'w, 's, Q: WorldQuery, F: ReadOnlyWorldQuery> { table_id_iter: std::slice::Iter<'s, TableId>, archetype_id_iter: std::slice::Iter<'s, ArchetypeId>, fetch: QueryFetch<'w, Q>, @@ -485,7 +487,7 @@ struct QueryIterationCursor<'w, 's, Q: WorldQuery, F: WorldQuery> { phantom: PhantomData, } -impl<'w, 's, Q: WorldQuery, F: WorldQuery> Clone for QueryIterationCursor<'w, 's, Q, F> +impl<'w, 's, Q: WorldQuery, F: ReadOnlyWorldQuery> Clone for QueryIterationCursor<'w, 's, Q, F> where QueryFetch<'w, Q>: Clone, QueryFetch<'w, F>: Clone, @@ -503,7 +505,7 @@ where } } -impl<'w, 's, Q: WorldQuery, F: WorldQuery> QueryIterationCursor<'w, 's, Q, F> { +impl<'w, 's, Q: WorldQuery, F: ReadOnlyWorldQuery> QueryIterationCursor<'w, 's, Q, F> { const IS_DENSE: bool = Q::IS_DENSE && F::IS_DENSE; unsafe fn init_empty( diff --git a/crates/bevy_ecs/src/query/mod.rs b/crates/bevy_ecs/src/query/mod.rs index 3efb6a5dc1017..c45a10af7d0b0 100644 --- a/crates/bevy_ecs/src/query/mod.rs +++ b/crates/bevy_ecs/src/query/mod.rs @@ -19,7 +19,7 @@ pub(crate) unsafe fn debug_checked_unreachable() -> ! { #[cfg(test)] mod tests { - use super::WorldQuery; + use super::{ReadOnlyWorldQuery, WorldQuery}; use crate::prelude::{AnyOf, Entity, Or, QueryState, With, Without}; use crate::query::{ArchetypeFilter, QueryCombinationIter, QueryFetch}; use crate::system::{IntoSystem, Query, System, SystemState}; @@ -68,7 +68,7 @@ mod tests { fn assert_combination(world: &mut World, expected_size: usize) where Q: WorldQuery, - F: WorldQuery, + F: ReadOnlyWorldQuery, F::ReadOnly: ArchetypeFilter, for<'w> QueryFetch<'w, Q::ReadOnly>: Clone, for<'w> QueryFetch<'w, F::ReadOnly>: Clone, @@ -81,7 +81,7 @@ mod tests { fn assert_all_sizes_equal(world: &mut World, expected_size: usize) where Q: WorldQuery, - F: WorldQuery, + F: ReadOnlyWorldQuery, F::ReadOnly: ArchetypeFilter, for<'w> QueryFetch<'w, Q::ReadOnly>: Clone, for<'w> QueryFetch<'w, F::ReadOnly>: Clone, diff --git a/crates/bevy_ecs/src/query/state.rs b/crates/bevy_ecs/src/query/state.rs index 9a1f08cde42d3..9a0942d646624 100644 --- a/crates/bevy_ecs/src/query/state.rs +++ b/crates/bevy_ecs/src/query/state.rs @@ -13,14 +13,14 @@ use bevy_utils::tracing::Instrument; use fixedbitset::FixedBitSet; use std::{borrow::Borrow, fmt}; -use super::{NopWorldQuery, QueryItem, QueryManyIter, ROQueryItem}; +use super::{NopWorldQuery, QueryItem, QueryManyIter, ROQueryItem, ReadOnlyWorldQuery}; /// Provides scoped access to a [`World`] state according to a given [`WorldQuery`] and query filter. #[repr(C)] // SAFETY NOTE: // Do not add any new fields that use the `Q` or `F` generic parameters as this may // make `QueryState::as_transmuted_state` unsound if not done with care. -pub struct QueryState { +pub struct QueryState { world_id: WorldId, pub(crate) archetype_generation: ArchetypeGeneration, pub(crate) matched_tables: FixedBitSet, @@ -35,13 +35,13 @@ pub struct QueryState { pub(crate) filter_state: F::State, } -impl FromWorld for QueryState { +impl FromWorld for QueryState { fn from_world(world: &mut World) -> Self { world.query_filtered() } } -impl QueryState { +impl QueryState { /// Converts this `QueryState` reference to a `QueryState` that does not access anything mutably. pub fn as_readonly(&self) -> &QueryState { // SAFETY: invariant on `WorldQuery` trait upholds that `Q::ReadOnly` and `F::ReadOnly` @@ -71,7 +71,7 @@ impl QueryState { /// `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: WorldQuery, - NewF: WorldQuery, + NewF: ReadOnlyWorldQuery, >( &self, ) -> &QueryState { @@ -79,7 +79,7 @@ impl QueryState { } } -impl QueryState { +impl QueryState { /// 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); diff --git a/crates/bevy_ecs/src/system/query.rs b/crates/bevy_ecs/src/system/query.rs index 3e4d37914b622..ce6cc2e470151 100644 --- a/crates/bevy_ecs/src/system/query.rs +++ b/crates/bevy_ecs/src/system/query.rs @@ -273,14 +273,14 @@ use std::{any::TypeId, borrow::Borrow, fmt::Debug}; /// [`Table`]: crate::storage::Table /// [`With`]: crate::query::With /// [`Without`]: crate::query::Without -pub struct Query<'world, 'state, Q: WorldQuery, F: WorldQuery = ()> { +pub struct Query<'world, 'state, Q: WorldQuery, F: ReadOnlyWorldQuery = ()> { pub(crate) world: &'world World, pub(crate) state: &'state QueryState, pub(crate) last_change_tick: u32, pub(crate) change_tick: u32, } -impl<'w, 's, Q: WorldQuery, F: WorldQuery> Query<'w, 's, Q, F> { +impl<'w, 's, Q: WorldQuery, F: ReadOnlyWorldQuery> Query<'w, 's, Q, F> { /// Creates a new query. /// /// # Safety @@ -1380,7 +1380,7 @@ impl<'w, 's, Q: WorldQuery, F: WorldQuery> Query<'w, 's, Q, F> { } } -impl<'w, 's, Q: WorldQuery, F: WorldQuery> IntoIterator for &'w Query<'_, 's, Q, F> { +impl<'w, 's, Q: WorldQuery, F: ReadOnlyWorldQuery> IntoIterator for &'w Query<'_, 's, Q, F> { type Item = ROQueryItem<'w, Q>; type IntoIter = QueryIter<'w, 's, Q::ReadOnly, F::ReadOnly>; @@ -1389,7 +1389,7 @@ impl<'w, 's, Q: WorldQuery, F: WorldQuery> IntoIterator for &'w Query<'_, 's, Q, } } -impl<'w, 's, Q: WorldQuery, F: WorldQuery> IntoIterator for &'w mut Query<'_, 's, Q, F> { +impl<'w, 's, Q: WorldQuery, F: ReadOnlyWorldQuery> IntoIterator for &'w mut Query<'_, 's, Q, F> { type Item = QueryItem<'w, Q>; type IntoIter = QueryIter<'w, 's, Q, F>; @@ -1434,7 +1434,7 @@ impl std::fmt::Display for QueryComponentError { } } -impl<'w, 's, Q: ReadOnlyWorldQuery, F: WorldQuery> Query<'w, 's, Q, F> { +impl<'w, 's, Q: ReadOnlyWorldQuery, F: ReadOnlyWorldQuery> Query<'w, 's, Q, 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 diff --git a/crates/bevy_ecs/src/system/system_param.rs b/crates/bevy_ecs/src/system/system_param.rs index ef956c25d553e..9fe9ed0af3cd1 100644 --- a/crates/bevy_ecs/src/system/system_param.rs +++ b/crates/bevy_ecs/src/system/system_param.rs @@ -135,16 +135,21 @@ pub trait SystemParamFetch<'world, 'state>: SystemParamState { ) -> Self::Item; } -impl<'w, 's, Q: WorldQuery + 'static, F: WorldQuery + 'static> SystemParam for Query<'w, 's, Q, F> { +impl<'w, 's, Q: WorldQuery + 'static, F: ReadOnlyWorldQuery + 'static> SystemParam + for Query<'w, 's, Q, F> +{ type Fetch = QueryState; } // SAFETY: QueryState is constrained to read-only fetches, so it only reads World. -unsafe impl ReadOnlySystemParamFetch for QueryState {} +unsafe impl ReadOnlySystemParamFetch + for QueryState +{ +} // SAFETY: Relevant query ComponentId and ArchetypeComponentId access is applied to SystemMeta. If // this QueryState conflicts with any prior access, a panic will occur. -unsafe impl SystemParamState +unsafe impl SystemParamState for QueryState { fn init(world: &mut World, system_meta: &mut SystemMeta) -> Self { @@ -174,7 +179,7 @@ unsafe impl SystemParamState } } -impl<'w, 's, Q: WorldQuery + 'static, F: WorldQuery + 'static> SystemParamFetch<'w, 's> +impl<'w, 's, Q: WorldQuery + 'static, F: ReadOnlyWorldQuery + 'static> SystemParamFetch<'w, 's> for QueryState { type Item = Query<'w, 's, Q, F>; @@ -1595,7 +1600,7 @@ mod tests { use super::SystemParam; use crate::{ self as bevy_ecs, // Necessary for the `SystemParam` Derive when used inside `bevy_ecs`. - query::WorldQuery, + query::{ReadOnlyWorldQuery, WorldQuery}, system::Query, }; @@ -1605,7 +1610,7 @@ mod tests { 'w, 's, Q: WorldQuery + Send + Sync + 'static, - F: WorldQuery + Send + Sync + 'static = (), + F: ReadOnlyWorldQuery + Send + Sync + 'static = (), > { _query: Query<'w, 's, Q, F>, } diff --git a/crates/bevy_ecs/src/world/mod.rs b/crates/bevy_ecs/src/world/mod.rs index 82863ef36cae1..3537b0a232b29 100644 --- a/crates/bevy_ecs/src/world/mod.rs +++ b/crates/bevy_ecs/src/world/mod.rs @@ -16,7 +16,7 @@ use crate::{ StorageType, }, entity::{AllocAtWithoutReplacement, Entities, Entity}, - query::{QueryState, WorldQuery}, + query::{QueryState, ReadOnlyWorldQuery, WorldQuery}, storage::{Column, SparseSet, Storages}, system::Resource, }; @@ -610,7 +610,7 @@ impl World { /// assert_eq!(matching_entities, vec![e2]); /// ``` #[inline] - pub fn query_filtered(&mut self) -> QueryState { + pub fn query_filtered(&mut self) -> QueryState { QueryState::new(self) } diff --git a/crates/bevy_ui/src/flex/mod.rs b/crates/bevy_ui/src/flex/mod.rs index db2f30be8cdfc..ba49e6572b9d1 100644 --- a/crates/bevy_ui/src/flex/mod.rs +++ b/crates/bevy_ui/src/flex/mod.rs @@ -4,7 +4,7 @@ use crate::{CalculatedSize, Node, Style, UiScale}; use bevy_ecs::{ entity::Entity, event::EventReader, - query::{Changed, With, Without, WorldQuery}, + query::{Changed, ReadOnlyWorldQuery, With, Without}, system::{Query, RemovedComponents, Res, ResMut, Resource}, }; use bevy_hierarchy::{Children, Parent}; @@ -234,7 +234,7 @@ pub fn flex_node_system( update_changed(&mut flex_surface, scale_factor, node_query); } - fn update_changed( + fn update_changed( flex_surface: &mut FlexSurface, scaling_factor: f64, query: Query<(Entity, &Style, Option<&CalculatedSize>), F>,