diff --git a/.github/contributing/example_style_guide.md b/.github/contributing/example_style_guide.md index 782d5550c73c7f..8b6ee4c7af0cdd 100644 --- a/.github/contributing/example_style_guide.md +++ b/.github/contributing/example_style_guide.md @@ -36,7 +36,7 @@ For more advice on writing examples, see the [relevant section](../../CONTRIBUTI 2. Prefer `for` loops over `.for_each`. The latter is faster (for now), but it is less clear for beginners, less idiomatic, and less flexible. 3. Use `.single` and `.single_mut` where appropriate. 4. In Queries, prefer `With` filters over actually fetching unused data with `&T`. -5. Prefer disjoint queries using `With` and `Without` over query sets when you need more than one query in a single system. +5. Prefer disjoint queries using `With` and `Without` over param sets when you need more than one query in a single system. 6. Prefer structs with named fields over tuple structs except in the case of single-field wrapper types. 7. Use enum-labels over string-labels for system / stage / etc. labels. diff --git a/crates/bevy_ecs/macros/src/lib.rs b/crates/bevy_ecs/macros/src/lib.rs index f2f0cddf38514a..8f5a4b9bb65997 100644 --- a/crates/bevy_ecs/macros/src/lib.rs +++ b/crates/bevy_ecs/macros/src/lib.rs @@ -178,88 +178,83 @@ fn get_idents(fmt_string: fn(usize) -> String, count: usize) -> Vec { } #[proc_macro] -pub fn impl_query_set(_input: TokenStream) -> TokenStream { +pub fn impl_param_set(_input: TokenStream) -> TokenStream { let mut tokens = TokenStream::new(); - let max_queries = 4; - let queries = get_idents(|i| format!("Q{}", i), max_queries); - let filters = get_idents(|i| format!("F{}", i), max_queries); - let mut query_fn_muts = Vec::new(); - for i in 0..max_queries { - let query = &queries[i]; - let filter = &filters[i]; - let fn_name = Ident::new(&format!("q{}", i), Span::call_site()); + let max_params = 8; + let params = get_idents(|i| format!("P{}", i), max_params); + let params_fetch = get_idents(|i| format!("PF{}", i), max_params); + let metas = get_idents(|i| format!("m{}", i), max_params); + let mut param_fn_muts = Vec::new(); + for (i, param) in params.iter().enumerate() { + let fn_name = Ident::new(&format!("p{}", i), Span::call_site()); let index = Index::from(i); - query_fn_muts.push(quote! { - pub fn #fn_name(&mut self) -> Query<'_, '_, #query, #filter> { + param_fn_muts.push(quote! { + pub fn #fn_name<'a>(&'a mut self) -> <#param::Fetch as SystemParamFetch<'a, 'a>>::Item { // SAFE: systems run without conflicts with other systems. - // Conflicting queries in QuerySet are not accessible at the same time - // QuerySets are guaranteed to not conflict with other SystemParams + // Conflicting params in ParamSet are not accessible at the same time + // ParamSets are guaranteed to not conflict with other SystemParams unsafe { - Query::new(self.world, &self.query_states.#index, self.last_change_tick, self.change_tick) + <#param::Fetch as SystemParamFetch<'a, 'a>>::get_param(&mut self.param_states.#index, &self.system_meta, self.world, self.change_tick) } } }); } - for query_count in 1..=max_queries { - let query = &queries[0..query_count]; - let filter = &filters[0..query_count]; - let query_fn_mut = &query_fn_muts[0..query_count]; + for param_count in 1..=max_params { + let param = ¶ms[0..param_count]; + let param_fetch = ¶ms_fetch[0..param_count]; + let meta = &metas[0..param_count]; + let param_fn_mut = ¶m_fn_muts[0..param_count]; tokens.extend(TokenStream::from(quote! { - impl<'w, 's, #(#query: WorldQuery + 'static,)* #(#filter: WorldQuery + 'static,)*> SystemParam for QuerySet<'w, 's, (#(QueryState<#query, #filter>,)*)> - where #(#filter::Fetch: FilterFetch,)* + impl<'w, 's, #(#param: SystemParam,)*> SystemParam for ParamSet<'w, 's, (#(#param,)*)> { - type Fetch = QuerySetState<(#(QueryState<#query, #filter>,)*)>; + type Fetch = ParamSetState<(#(#param::Fetch,)*)>; } - // SAFE: All Queries are constrained to ReadOnlyFetch, so World is only read - unsafe impl<#(#query: WorldQuery + 'static,)* #(#filter: WorldQuery + 'static,)*> ReadOnlySystemParamFetch for QuerySetState<(#(QueryState<#query, #filter>,)*)> - where #(#query::Fetch: ReadOnlyFetch,)* #(#filter::Fetch: FilterFetch,)* + // SAFE: All parameters are constrained to ReadOnlyFetch, so World is only read + + unsafe impl<#(#param_fetch: for<'w1, 's1> SystemParamFetch<'w1, 's1>,)*> ReadOnlySystemParamFetch for ParamSetState<(#(#param_fetch,)*)> + where #(#param_fetch: ReadOnlySystemParamFetch,)* { } - // SAFE: Relevant query ComponentId and ArchetypeComponentId access is applied to SystemMeta. If any QueryState conflicts + // SAFE: Relevant parameter ComponentId and ArchetypeComponentId access is applied to SystemMeta. If any ParamState conflicts // with any prior access, a panic will occur. - unsafe impl<#(#query: WorldQuery + 'static,)* #(#filter: WorldQuery + 'static,)*> SystemParamState for QuerySetState<(#(QueryState<#query, #filter>,)*)> - where #(#filter::Fetch: FilterFetch,)* + + unsafe impl<#(#param_fetch: for<'w1, 's1> SystemParamFetch<'w1, 's1>,)*> SystemParamState for ParamSetState<(#(#param_fetch,)*)> { fn init(world: &mut World, system_meta: &mut SystemMeta) -> Self { #( - let mut #query = QueryState::<#query, #filter>::new(world); - assert_component_access_compatibility( - &system_meta.name, - std::any::type_name::<#query>(), - std::any::type_name::<#filter>(), - &system_meta.component_access_set, - &#query.component_access, - world, - ); + // Pretend to add each param to the system alone, see if it conflicts + let mut #meta = system_meta.clone(); + #meta.component_access_set.clear(); + #meta.archetype_component_access.clear(); + #param_fetch::init(world, &mut #meta); + let #param = #param_fetch::init(world, &mut system_meta.clone()); )* #( system_meta .component_access_set - .add(#query.component_access.clone()); + .extend(#meta.component_access_set); system_meta .archetype_component_access - .extend(&#query.archetype_component_access); + .extend(&#meta.archetype_component_access); )* - QuerySetState((#(#query,)*)) + ParamSetState((#(#param,)*)) } fn new_archetype(&mut self, archetype: &Archetype, system_meta: &mut SystemMeta) { - let (#(#query,)*) = &mut self.0; + let (#(#param,)*) = &mut self.0; #( - #query.new_archetype(archetype); - system_meta - .archetype_component_access - .extend(&#query.archetype_component_access); + #param.new_archetype(archetype, system_meta); )* } } - impl<'w, 's, #(#query: WorldQuery + 'static,)* #(#filter: WorldQuery + 'static,)*> SystemParamFetch<'w, 's> for QuerySetState<(#(QueryState<#query, #filter>,)*)> - where #(#filter::Fetch: FilterFetch,)* + + + impl<'w, 's, #(#param_fetch: for<'w1, 's1> SystemParamFetch<'w1, 's1>,)*> SystemParamFetch<'w, 's> for ParamSetState<(#(#param_fetch,)*)> { - type Item = QuerySet<'w, 's, (#(QueryState<#query, #filter>,)*)>; + type Item = ParamSet<'w, 's, (#(<#param_fetch as SystemParamFetch<'w, 's>>::Item,)*)>; #[inline] unsafe fn get_param( @@ -268,19 +263,19 @@ pub fn impl_query_set(_input: TokenStream) -> TokenStream { world: &'w World, change_tick: u32, ) -> Self::Item { - QuerySet { - query_states: &state.0, + ParamSet { + param_states: &mut state.0, + system_meta: system_meta.clone(), world, - last_change_tick: system_meta.last_change_tick, change_tick, } } } - impl<'w, 's, #(#query: WorldQuery,)* #(#filter: WorldQuery,)*> QuerySet<'w, 's, (#(QueryState<#query, #filter>,)*)> - where #(#filter::Fetch: FilterFetch,)* + impl<'w, 's, #(#param: SystemParam,)*> ParamSet<'w, 's, (#(#param,)*)> { - #(#query_fn_mut)* + + #(#param_fn_mut)* } })); } diff --git a/crates/bevy_ecs/src/lib.rs b/crates/bevy_ecs/src/lib.rs index 1183e71cd6e396..ad93f91d0d1509 100644 --- a/crates/bevy_ecs/src/lib.rs +++ b/crates/bevy_ecs/src/lib.rs @@ -34,7 +34,7 @@ pub mod prelude { }, system::{ Commands, In, IntoChainSystem, IntoExclusiveSystem, IntoSystem, Local, NonSend, - NonSendMut, Query, QuerySet, RemovedComponents, Res, ResMut, System, + NonSendMut, ParamSet, Query, RemovedComponents, Res, ResMut, System, SystemParamFunction, }, world::{FromWorld, Mut, World}, diff --git a/crates/bevy_ecs/src/query/access.rs b/crates/bevy_ecs/src/query/access.rs index 1de838ae017454..b324792460ad82 100644 --- a/crates/bevy_ecs/src/query/access.rs +++ b/crates/bevy_ecs/src/query/access.rs @@ -1,4 +1,5 @@ use crate::storage::SparseSetIndex; +use bevy_utils::HashSet; use fixedbitset::FixedBitSet; use std::marker::PhantomData; @@ -129,7 +130,7 @@ impl Access { } } -#[derive(Clone, Eq, PartialEq)] +#[derive(Clone, Eq, PartialEq, Debug)] pub struct FilteredAccess { access: Access, with: FixedBitSet, @@ -146,6 +147,14 @@ impl Default for FilteredAccess { } } +impl From> for FilteredAccessSet { + fn from(filtered_access: FilteredAccess) -> Self { + let mut base = FilteredAccessSet::::default(); + base.add(filtered_access); + base + } +} + impl FilteredAccess { #[inline] pub fn access(&self) -> &Access { @@ -191,7 +200,7 @@ impl FilteredAccess { self.access.read_all(); } } - +#[derive(Clone, Debug)] pub struct FilteredAccessSet { combined_access: Access, filtered_accesses: Vec>, @@ -211,22 +220,42 @@ impl FilteredAccessSet { pub fn get_conflicts(&self, filtered_access: &FilteredAccess) -> Vec { // if combined unfiltered access is incompatible, check each filtered access for // compatibility + let mut conflicts = HashSet::::default(); if !filtered_access.access.is_compatible(&self.combined_access) { for current_filtered_access in &self.filtered_accesses { if !current_filtered_access.is_compatible(filtered_access) { - return current_filtered_access - .access - .get_conflicts(&filtered_access.access); + conflicts.extend( + current_filtered_access + .access + .get_conflicts(&filtered_access.access) + .iter() + .map(|ind| ind.sparse_set_index()), + ); } } } - Vec::new() + conflicts + .iter() + .map(|ind| T::get_sparse_set_index(*ind)) + .collect() } pub fn add(&mut self, filtered_access: FilteredAccess) { self.combined_access.extend(&filtered_access.access); self.filtered_accesses.push(filtered_access); } + + pub fn extend(&mut self, filtered_access_set: FilteredAccessSet) { + self.combined_access + .extend(&filtered_access_set.combined_access); + self.filtered_accesses + .extend(filtered_access_set.filtered_accesses); + } + + pub fn clear(&mut self) { + self.combined_access.clear(); + self.filtered_accesses.clear(); + } } impl Default for FilteredAccessSet { diff --git a/crates/bevy_ecs/src/system/function_system.rs b/crates/bevy_ecs/src/system/function_system.rs index d77edf3da24d8b..c03d09684f8443 100644 --- a/crates/bevy_ecs/src/system/function_system.rs +++ b/crates/bevy_ecs/src/system/function_system.rs @@ -13,6 +13,7 @@ use bevy_ecs_macros::all_tuples; use std::{borrow::Cow, fmt::Debug, hash::Hash, marker::PhantomData}; /// The metadata of a [`System`]. +#[derive(Clone)] pub struct SystemMeta { pub(crate) name: Cow<'static, str>, pub(crate) component_access_set: FilteredAccessSet, diff --git a/crates/bevy_ecs/src/system/mod.rs b/crates/bevy_ecs/src/system/mod.rs index f8a68bd7b7d4ec..27dee44f2514ed 100644 --- a/crates/bevy_ecs/src/system/mod.rs +++ b/crates/bevy_ecs/src/system/mod.rs @@ -100,10 +100,10 @@ mod tests { bundle::Bundles, component::{Component, Components}, entity::{Entities, Entity}, - query::{Added, Changed, Or, QueryState, With, Without}, + query::{Added, Changed, Or, With, Without}, schedule::{Schedule, Stage, SystemStage}, system::{ - IntoExclusiveSystem, IntoSystem, Local, NonSend, NonSendMut, Query, QuerySet, + IntoExclusiveSystem, IntoSystem, Local, NonSend, NonSendMut, ParamSet, Query, RemovedComponents, Res, ResMut, System, SystemState, }, world::{FromWorld, World}, @@ -211,17 +211,17 @@ mod tests { } #[test] - fn or_query_set_system() { + fn or_param_set_system() { // Regression test for issue #762 fn query_system( mut ran: ResMut, - mut set: QuerySet<( - QueryState<(), Or<(Changed, Changed)>>, - QueryState<(), Or<(Added, Added)>>, + mut set: ParamSet<( + Query<(), Or<(Changed, Changed)>>, + Query<(), Or<(Added, Added)>>, )>, ) { - let changed = set.q0().iter().count(); - let added = set.q1().iter().count(); + let changed = set.p0().iter().count(); + let added = set.p1().iter().count(); assert_eq!(changed, 1); assert_eq!(added, 1); @@ -320,7 +320,7 @@ mod tests { #[test] fn query_set_system() { - fn sys(mut _set: QuerySet<(QueryState<&mut A>, QueryState<&A>)>) {} + fn sys(mut _set: ParamSet<(Query<&mut A>, Query<&A>)>) {} let mut world = World::default(); run_system(&mut world, sys); } @@ -328,7 +328,7 @@ mod tests { #[test] #[should_panic] fn conflicting_query_with_query_set_system() { - fn sys(_query: Query<&mut A>, _set: QuerySet<(QueryState<&mut A>, QueryState<&B>)>) {} + fn sys(_query: Query<&mut A>, _set: ParamSet<(Query<&mut A>, Query<&B>)>) {} let mut world = World::default(); run_system(&mut world, sys); @@ -337,11 +337,7 @@ mod tests { #[test] #[should_panic] fn conflicting_query_sets_system() { - fn sys( - _set_1: QuerySet<(QueryState<&mut A>,)>, - _set_2: QuerySet<(QueryState<&mut A>, QueryState<&B>)>, - ) { - } + fn sys(_set_1: ParamSet<(Query<&mut A>,)>, _set_2: ParamSet<(Query<&mut A>, Query<&B>)>) {} let mut world = World::default(); run_system(&mut world, sys); @@ -674,11 +670,8 @@ mod tests { world.insert_resource(A(42)); world.spawn().insert(B(7)); - let mut system_state: SystemState<( - Res, - Query<&B>, - QuerySet<(QueryState<&C>, QueryState<&D>)>, - )> = SystemState::new(&mut world); + let mut system_state: SystemState<(Res, Query<&B>, ParamSet<(Query<&C>, Query<&D>)>)> = + SystemState::new(&mut world); let (a, query, _) = system_state.get(&world); assert_eq!(*a, A(42), "returned resource matches initial value"); assert_eq!( diff --git a/crates/bevy_ecs/src/system/query.rs b/crates/bevy_ecs/src/system/query.rs index 349121b06bd87b..df66160b78e87f 100644 --- a/crates/bevy_ecs/src/system/query.rs +++ b/crates/bevy_ecs/src/system/query.rs @@ -83,7 +83,7 @@ use thiserror::Error; /// /// Similarly, a system cannot contain two queries that would break Rust's mutability Rules. /// If you need such Queries, you can use Filters to make the Queries disjoint or use a -/// [`QuerySet`](super::QuerySet). +/// [`ParamSet`](super::ParamSet). /// /// ## Entity ID access /// diff --git a/crates/bevy_ecs/src/system/system_param.rs b/crates/bevy_ecs/src/system/system_param.rs index 049fee84e0401c..669f8df92bb924 100644 --- a/crates/bevy_ecs/src/system/system_param.rs +++ b/crates/bevy_ecs/src/system/system_param.rs @@ -13,7 +13,7 @@ use crate::{ world::{FromWorld, World}, }; pub use bevy_ecs_macros::SystemParam; -use bevy_ecs_macros::{all_tuples, impl_query_set}; +use bevy_ecs_macros::{all_tuples, impl_param_set}; use std::{ fmt::Debug, marker::PhantomData, @@ -74,7 +74,7 @@ pub unsafe trait SystemParamState: Send + Sync + 'static { pub unsafe trait ReadOnlySystemParamFetch {} pub trait SystemParamFetch<'world, 'state>: SystemParamState { - type Item; + type Item: SystemParam; /// # Safety /// /// This call might access any of the input parameters in an unsafe way. Make sure the data @@ -170,21 +170,20 @@ fn assert_component_access_compatibility( .map(|component_id| world.components.get_info(component_id).unwrap().name()) .collect::>(); let accesses = conflicting_components.join(", "); - panic!("error[B0001]: Query<{}, {}> in system {} accesses component(s) {} in a way that conflicts with a previous system parameter. Consider using `Without` to create disjoint Queries or merging conflicting Queries into a `QuerySet`.", + panic!("error[B0001]: Query<{}, {}> in system {} accesses component(s) {} in a way that conflicts with a previous system parameter. Consider using `Without` to create disjoint Queries or merging conflicting Queries into a `ParamSet`.", query_type, filter_type, system_name, accesses); } -pub struct QuerySet<'w, 's, T> { - query_states: &'s T, +pub struct ParamSet<'w, 's, T: SystemParam> { + param_states: &'s mut T::Fetch, world: &'w World, - last_change_tick: u32, + system_meta: SystemMeta, change_tick: u32, } +/// The [`SystemParamState`] of [`ParamSet`]. +pub struct ParamSetState SystemParamFetch<'w, 's>>(T); -#[doc(hidden)] -pub struct QuerySetState(T); - -impl_query_set!(); +impl_param_set!(); pub trait Resource: Send + Sync + 'static {} diff --git a/crates/bevy_ecs_compile_fail_tests/tests/ui/system_query_set_get_lifetime_safety.rs b/crates/bevy_ecs_compile_fail_tests/tests/ui/system_query_set_get_lifetime_safety.rs index 0fff26700dde0b..b9e161382027c9 100644 --- a/crates/bevy_ecs_compile_fail_tests/tests/ui/system_query_set_get_lifetime_safety.rs +++ b/crates/bevy_ecs_compile_fail_tests/tests/ui/system_query_set_get_lifetime_safety.rs @@ -3,22 +3,22 @@ use bevy_ecs::prelude::*; #[derive(Component)] struct A(usize); -fn query_set(mut queries: QuerySet<(QueryState<&mut A>, QueryState<&A>)>, e: Res) { - let mut q2 = queries.q0(); +fn query_set(mut queries: ParamSet<(Query<&mut A>, Query<&A>)>, e: Res) { + let mut q2 = queries.p0(); let mut b = q2.get_mut(*e).unwrap(); - let q1 = queries.q1(); + let q1 = queries.p1(); let a = q1.get(*e).unwrap(); // this should fail to compile b.0 = a.0 } -fn query_set_flip(mut queries: QuerySet<(QueryState<&mut A>, QueryState<&A>)>, e: Res) { - let q1 = queries.q1(); +fn query_set_flip(mut queries: ParamSet<(Query<&mut A>, Query<&A>)>, e: Res) { + let q1 = queries.p1(); let a = q1.get(*e).unwrap(); - let mut q2 = queries.q0(); + let mut q2 = queries.p0(); let mut b = q2.get_mut(*e).unwrap(); // this should fail to compile diff --git a/crates/bevy_ecs_compile_fail_tests/tests/ui/system_query_set_get_lifetime_safety.stderr b/crates/bevy_ecs_compile_fail_tests/tests/ui/system_query_set_get_lifetime_safety.stderr index 860e3ba2ccb2ff..53d95e32d75d8d 100644 --- a/crates/bevy_ecs_compile_fail_tests/tests/ui/system_query_set_get_lifetime_safety.stderr +++ b/crates/bevy_ecs_compile_fail_tests/tests/ui/system_query_set_get_lifetime_safety.stderr @@ -1,10 +1,10 @@ error[E0499]: cannot borrow `queries` as mutable more than once at a time --> tests/ui/system_query_set_get_lifetime_safety.rs:10:14 | -7 | let mut q2 = queries.q0(); +7 | let mut q2 = queries.p0(); | ------------ first mutable borrow occurs here ... -10 | let q1 = queries.q1(); +10 | let q1 = queries.p1(); | ^^^^^^^^^^^^ second mutable borrow occurs here ... 14 | b.0 = a.0 @@ -13,10 +13,10 @@ error[E0499]: cannot borrow `queries` as mutable more than once at a time error[E0499]: cannot borrow `queries` as mutable more than once at a time --> tests/ui/system_query_set_get_lifetime_safety.rs:21:18 | -18 | let q1 = queries.q1(); +18 | let q1 = queries.p1(); | ------------ first mutable borrow occurs here ... -21 | let mut q2 = queries.q0(); +21 | let mut q2 = queries.p0(); | ^^^^^^^^^^^^ second mutable borrow occurs here ... 25 | b.0 = a.0 diff --git a/crates/bevy_ecs_compile_fail_tests/tests/ui/system_query_set_iter_lifetime_safety.rs b/crates/bevy_ecs_compile_fail_tests/tests/ui/system_query_set_iter_lifetime_safety.rs index 4207b8ccd5cbfc..37bd31324b409d 100644 --- a/crates/bevy_ecs_compile_fail_tests/tests/ui/system_query_set_iter_lifetime_safety.rs +++ b/crates/bevy_ecs_compile_fail_tests/tests/ui/system_query_set_iter_lifetime_safety.rs @@ -3,12 +3,12 @@ use bevy_ecs::prelude::*; #[derive(Component)] struct A(usize); -fn query_set(mut queries: QuerySet<(QueryState<&mut A>, QueryState<&A>)>) { - let mut q2 = queries.q0(); +fn query_set(mut queries: ParamSet<(Query<&mut A>, Query<&A>)>) { + let mut q2 = queries.p0(); let mut iter2 = q2.iter_mut(); let mut b = iter2.next().unwrap(); - let q1 = queries.q1(); + let q1 = queries.p1(); let mut iter = q1.iter(); let a = &*iter.next().unwrap(); @@ -16,12 +16,12 @@ fn query_set(mut queries: QuerySet<(QueryState<&mut A>, QueryState<&A>)>) { b.0 = a.0 } -fn query_set_flip(mut queries: QuerySet<(QueryState<&mut A>, QueryState<&A>)>) { - let q1 = queries.q1(); +fn query_set_flip(mut queries: ParamSet<(Query<&mut A>, Query<&A>)>) { + let q1 = queries.p1(); let mut iter = q1.iter(); let a = &*iter.next().unwrap(); - let mut q2 = queries.q0(); + let mut q2 = queries.p0(); let mut iter2 = q2.iter_mut(); let mut b = iter2.next().unwrap(); diff --git a/crates/bevy_ecs_compile_fail_tests/tests/ui/system_query_set_iter_lifetime_safety.stderr b/crates/bevy_ecs_compile_fail_tests/tests/ui/system_query_set_iter_lifetime_safety.stderr index 8a0a7bc111e24e..3878322c7173c3 100644 --- a/crates/bevy_ecs_compile_fail_tests/tests/ui/system_query_set_iter_lifetime_safety.stderr +++ b/crates/bevy_ecs_compile_fail_tests/tests/ui/system_query_set_iter_lifetime_safety.stderr @@ -1,10 +1,10 @@ error[E0499]: cannot borrow `queries` as mutable more than once at a time --> tests/ui/system_query_set_iter_lifetime_safety.rs:11:14 | -7 | let mut q2 = queries.q0(); +7 | let mut q2 = queries.p0(); | ------------ first mutable borrow occurs here ... -11 | let q1 = queries.q1(); +11 | let q1 = queries.p1(); | ^^^^^^^^^^^^ second mutable borrow occurs here ... 16 | b.0 = a.0 @@ -13,10 +13,10 @@ error[E0499]: cannot borrow `queries` as mutable more than once at a time error[E0499]: cannot borrow `queries` as mutable more than once at a time --> tests/ui/system_query_set_iter_lifetime_safety.rs:24:18 | -20 | let q1 = queries.q1(); +20 | let q1 = queries.p1(); | ------------ first mutable borrow occurs here ... -24 | let mut q2 = queries.q0(); +24 | let mut q2 = queries.p0(); | ^^^^^^^^^^^^ second mutable borrow occurs here ... 29 | b.0 = a.0; diff --git a/crates/bevy_pbr/src/wireframe.rs b/crates/bevy_pbr/src/wireframe.rs index b4cfefbd8fc729..c79b04513570fd 100644 --- a/crates/bevy_pbr/src/wireframe.rs +++ b/crates/bevy_pbr/src/wireframe.rs @@ -110,9 +110,9 @@ fn queue_wireframes( mut pipelines: ResMut>, mut pipeline_cache: ResMut, msaa: Res, - mut material_meshes: QuerySet<( - QueryState<(Entity, &Handle, &MeshUniform)>, - QueryState<(Entity, &Handle, &MeshUniform), With>, + mut material_meshes: ParamSet<( + Query<(Entity, &Handle, &MeshUniform)>, + Query<(Entity, &Handle, &MeshUniform), With>, )>, mut views: Query<(&ExtractedView, &mut RenderPhase)>, ) { @@ -153,9 +153,9 @@ fn queue_wireframes( }; if wireframe_config.global { - material_meshes.q0().iter().for_each(add_render_phase); + material_meshes.p0().iter().for_each(add_render_phase); } else { - material_meshes.q1().iter().for_each(add_render_phase); + material_meshes.p1().iter().for_each(add_render_phase); } } } diff --git a/crates/bevy_render/src/camera/camera.rs b/crates/bevy_render/src/camera/camera.rs index 6da11ccb66473c..528926ebd4be96 100644 --- a/crates/bevy_render/src/camera/camera.rs +++ b/crates/bevy_render/src/camera/camera.rs @@ -11,13 +11,14 @@ use crate::{ use bevy_app::{App, CoreStage, Plugin, StartupStage}; use bevy_asset::{AssetEvent, Assets, Handle}; use bevy_ecs::{ + change_detection::DetectChanges, component::Component, entity::Entity, event::EventReader, - prelude::{DetectChanges, QueryState, With}, + prelude::With, query::Added, reflect::ReflectComponent, - system::{Commands, Query, QuerySet, Res, ResMut}, + system::{Commands, ParamSet, Query, Res, ResMut}, }; use bevy_math::{Mat4, UVec2, Vec2, Vec3}; use bevy_reflect::{Reflect, ReflectDeserialize}; @@ -153,9 +154,9 @@ pub fn camera_system( mut image_asset_events: EventReader>, windows: Res, images: Res>, - mut queries: QuerySet<( - QueryState<(Entity, &mut Camera, &mut T)>, - QueryState>, + mut queries: ParamSet<( + Query<(Entity, &mut Camera, &mut T)>, + Query>, )>, ) { let mut changed_window_ids = Vec::new(); @@ -191,10 +192,10 @@ pub fn camera_system( .collect(); let mut added_cameras = vec![]; - for entity in &mut queries.q1().iter() { + for entity in &mut queries.p1().iter() { added_cameras.push(entity); } - for (entity, mut camera, mut camera_projection) in queries.q0().iter_mut() { + for (entity, mut camera, mut camera_projection) in queries.p0().iter_mut() { if camera .target .is_changed(&changed_window_ids, &changed_image_handles) diff --git a/crates/bevy_render/src/view/visibility/mod.rs b/crates/bevy_render/src/view/visibility/mod.rs index 6d2a57c6e10c27..e7cd28c78ce613 100644 --- a/crates/bevy_render/src/view/visibility/mod.rs +++ b/crates/bevy_render/src/view/visibility/mod.rs @@ -140,9 +140,9 @@ pub fn update_frusta( pub fn check_visibility( mut view_query: Query<(&mut VisibleEntities, &Frustum, Option<&RenderLayers>), With>, - mut visible_entity_query: QuerySet<( - QueryState<&mut ComputedVisibility>, - QueryState<( + mut visible_entity_query: ParamSet<( + Query<&mut ComputedVisibility>, + Query<( Entity, &Visibility, &mut ComputedVisibility, @@ -154,7 +154,7 @@ pub fn check_visibility( )>, ) { // Reset the computed visibility to false - for mut computed_visibility in visible_entity_query.q0().iter_mut() { + for mut computed_visibility in visible_entity_query.p0().iter_mut() { computed_visibility.is_visible = false; } @@ -170,7 +170,7 @@ pub fn check_visibility( maybe_aabb, maybe_no_frustum_culling, maybe_transform, - ) in visible_entity_query.q1().iter_mut() + ) in visible_entity_query.p1().iter_mut() { if !visibility.is_visible { continue; diff --git a/crates/bevy_text/src/text2d.rs b/crates/bevy_text/src/text2d.rs index 3b4ff0c3e74fb8..86bb4c998f0803 100644 --- a/crates/bevy_text/src/text2d.rs +++ b/crates/bevy_text/src/text2d.rs @@ -3,9 +3,9 @@ use bevy_ecs::{ bundle::Bundle, component::Component, entity::Entity, - query::{Changed, QueryState, With}, + query::{Changed, With}, reflect::ReflectComponent, - system::{Local, Query, QuerySet, Res, ResMut}, + system::{Local, ParamSet, Query, Res, ResMut}, }; use bevy_math::{Size, Vec3}; use bevy_reflect::Reflect; @@ -138,13 +138,13 @@ pub fn text2d_system( mut texture_atlases: ResMut>, mut font_atlas_set_storage: ResMut>, mut text_pipeline: ResMut, - mut text_queries: QuerySet<( - QueryState, Changed)>, - QueryState<(&Text, Option<&Text2dBounds>, &mut Text2dSize), With>, + mut text_queries: ParamSet<( + Query, Changed)>, + Query<(&Text, Option<&Text2dBounds>, &mut Text2dSize), With>, )>, ) { // Adds all entities where the text or the style has changed to the local queue - for entity in text_queries.q0().iter_mut() { + for entity in text_queries.p0().iter_mut() { queued_text.entities.push(entity); } @@ -156,7 +156,7 @@ pub fn text2d_system( // Computes all text in the local queue let mut new_queue = Vec::new(); - let mut query = text_queries.q1(); + let mut query = text_queries.p1(); for entity in queued_text.entities.drain(..) { if let Ok((text, bounds, mut calculated_size)) = query.get_mut(entity) { let text_bounds = match bounds { diff --git a/crates/bevy_ui/src/widget/text.rs b/crates/bevy_ui/src/widget/text.rs index d462c3fbb2c86b..9b2d6a9b17b2eb 100644 --- a/crates/bevy_ui/src/widget/text.rs +++ b/crates/bevy_ui/src/widget/text.rs @@ -2,9 +2,8 @@ use crate::{CalculatedSize, Style, Val}; use bevy_asset::Assets; use bevy_ecs::{ entity::Entity, - prelude::QueryState, query::{Changed, Or, With}, - system::{Local, QuerySet, Res, ResMut}, + system::{Local, ParamSet, Query, Res, ResMut}, }; use bevy_math::Size; use bevy_render::texture::Image; @@ -46,10 +45,10 @@ pub fn text_system( mut texture_atlases: ResMut>, mut font_atlas_set_storage: ResMut>, mut text_pipeline: ResMut, - mut text_queries: QuerySet<( - QueryState, Changed