diff --git a/benches/benches/bevy_ecs/change_detection.rs b/benches/benches/bevy_ecs/change_detection.rs index 6c4428efed8bb..384b857c18381 100644 --- a/benches/benches/bevy_ecs/change_detection.rs +++ b/benches/benches/bevy_ecs/change_detection.rs @@ -71,7 +71,7 @@ fn setup(entity_count: u32) -> World { // create a cached query in setup to avoid extra costs in each iter fn generic_filter_query(world: &mut World) -> QueryState { - world.query_filtered::() + world.query_state_filtered::() } fn generic_bench( @@ -135,7 +135,7 @@ fn all_changed_detection_generic( || { let mut world = setup::(entity_count); world.clear_trackers(); - let mut query = world.query::<&mut T>(); + let mut query = world.query_state::<&mut T>(); for mut component in query.iter_mut(&mut world) { black_box(component.bench_modify()); } @@ -185,7 +185,7 @@ fn few_changed_detection_generic( || { let mut world = setup::(entity_count); world.clear_trackers(); - let mut query = world.query::<&mut T>(); + let mut query = world.query_state::<&mut T>(); let mut to_modify: Vec> = query.iter_mut(&mut world).collect(); to_modify.shuffle(&mut deterministic_rand()); @@ -316,7 +316,7 @@ fn multiple_archetype_none_changed_detection_generic(&mut world, archetype_count, entity_count); world.clear_trackers(); - let mut query = world.query::<( + let mut query = world.query_state::<( Option<&mut Data<0>>, Option<&mut Data<1>>, Option<&mut Data<2>>, diff --git a/benches/benches/bevy_ecs/iteration/iter_frag.rs b/benches/benches/bevy_ecs/iteration/iter_frag.rs index 376ac6ea934cd..5c24fec3d558b 100644 --- a/benches/benches/bevy_ecs/iteration/iter_frag.rs +++ b/benches/benches/bevy_ecs/iteration/iter_frag.rs @@ -23,7 +23,7 @@ impl<'w> Benchmark<'w> { create_entities!(world; A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z); - let query = world.query::<&mut Data>(); + let query = world.query_state::<&mut Data>(); Self(world, query) } diff --git a/benches/benches/bevy_ecs/iteration/iter_frag_foreach.rs b/benches/benches/bevy_ecs/iteration/iter_frag_foreach.rs index c345fe9008749..949d1ff446d6f 100644 --- a/benches/benches/bevy_ecs/iteration/iter_frag_foreach.rs +++ b/benches/benches/bevy_ecs/iteration/iter_frag_foreach.rs @@ -23,7 +23,7 @@ impl<'w> Benchmark<'w> { create_entities!(world; A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z); - let query = world.query::<&mut Data>(); + let query = world.query_state::<&mut Data>(); Self(world, query) } diff --git a/benches/benches/bevy_ecs/iteration/iter_frag_foreach_sparse.rs b/benches/benches/bevy_ecs/iteration/iter_frag_foreach_sparse.rs index c616f737c21a8..00c273f3ac739 100644 --- a/benches/benches/bevy_ecs/iteration/iter_frag_foreach_sparse.rs +++ b/benches/benches/bevy_ecs/iteration/iter_frag_foreach_sparse.rs @@ -34,7 +34,7 @@ impl<'w> Benchmark<'w> { create_entities!(world; C70, C71, C72, C73, C74, C75, C76, C77, C78, C79); create_entities!(world; C80, C81, C82, C83, C84, C85, C86, C87, C88, C89); create_entities!(world; C90, C91, C92, C93, C94, C95, C96, C97, C98, C99); - let query = world.query::<&mut Data>(); + let query = world.query_state::<&mut Data>(); Self(world, query) } diff --git a/benches/benches/bevy_ecs/iteration/iter_frag_foreach_wide.rs b/benches/benches/bevy_ecs/iteration/iter_frag_foreach_wide.rs index 0ea09053b8251..1575a97d78d27 100644 --- a/benches/benches/bevy_ecs/iteration/iter_frag_foreach_wide.rs +++ b/benches/benches/bevy_ecs/iteration/iter_frag_foreach_wide.rs @@ -51,7 +51,7 @@ impl<'w> Benchmark<'w> { create_entities!(world; A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z); - let query = world.query(); + let query = world.query_state(); Self(world, query) } diff --git a/benches/benches/bevy_ecs/iteration/iter_frag_foreach_wide_sparse.rs b/benches/benches/bevy_ecs/iteration/iter_frag_foreach_wide_sparse.rs index 6949d1b90d23b..d8aedbce40912 100644 --- a/benches/benches/bevy_ecs/iteration/iter_frag_foreach_wide_sparse.rs +++ b/benches/benches/bevy_ecs/iteration/iter_frag_foreach_wide_sparse.rs @@ -61,7 +61,7 @@ impl<'w> Benchmark<'w> { create_entities!(world; C70, C71, C72, C73, C74, C75, C76, C77, C78, C79); create_entities!(world; C80, C81, C82, C83, C84, C85, C86, C87, C88, C89); create_entities!(world; C90, C91, C92, C93, C94, C95, C96, C97, C98, C99); - let query = world.query(); + let query = world.query_state(); Self(world, query) } diff --git a/benches/benches/bevy_ecs/iteration/iter_frag_sparse.rs b/benches/benches/bevy_ecs/iteration/iter_frag_sparse.rs index 7385bf28d403c..afabeb7878d22 100644 --- a/benches/benches/bevy_ecs/iteration/iter_frag_sparse.rs +++ b/benches/benches/bevy_ecs/iteration/iter_frag_sparse.rs @@ -34,7 +34,7 @@ impl<'w> Benchmark<'w> { create_entities!(world; C70, C71, C72, C73, C74, C75, C76, C77, C78, C79); create_entities!(world; C80, C81, C82, C83, C84, C85, C86, C87, C88, C89); create_entities!(world; C90, C91, C92, C93, C94, C95, C96, C97, C98, C99); - let query = world.query::<&mut Data>(); + let query = world.query_state::<&mut Data>(); Self(world, query) } diff --git a/benches/benches/bevy_ecs/iteration/iter_frag_wide.rs b/benches/benches/bevy_ecs/iteration/iter_frag_wide.rs index 84442c78e547c..ec2627ca17dfd 100644 --- a/benches/benches/bevy_ecs/iteration/iter_frag_wide.rs +++ b/benches/benches/bevy_ecs/iteration/iter_frag_wide.rs @@ -51,7 +51,7 @@ impl<'w> Benchmark<'w> { create_entities!(world; A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z); - let query = world.query(); + let query = world.query_state(); Self(world, query) } diff --git a/benches/benches/bevy_ecs/iteration/iter_frag_wide_sparse.rs b/benches/benches/bevy_ecs/iteration/iter_frag_wide_sparse.rs index 928ffea0731be..46b93de312bfe 100644 --- a/benches/benches/bevy_ecs/iteration/iter_frag_wide_sparse.rs +++ b/benches/benches/bevy_ecs/iteration/iter_frag_wide_sparse.rs @@ -61,7 +61,7 @@ impl<'w> Benchmark<'w> { create_entities!(world; C70, C71, C72, C73, C74, C75, C76, C77, C78, C79); create_entities!(world; C80, C81, C82, C83, C84, C85, C86, C87, C88, C89); create_entities!(world; C90, C91, C92, C93, C94, C95, C96, C97, C98, C99); - let query = world.query(); + let query = world.query_state(); Self(world, query) } diff --git a/benches/benches/bevy_ecs/iteration/iter_simple.rs b/benches/benches/bevy_ecs/iteration/iter_simple.rs index 1fc86f5087679..09f23bc18fa8c 100644 --- a/benches/benches/bevy_ecs/iteration/iter_simple.rs +++ b/benches/benches/bevy_ecs/iteration/iter_simple.rs @@ -29,7 +29,7 @@ impl<'w> Benchmark<'w> { .take(10_000), ); - let query = world.query::<(&Velocity, &mut Position)>(); + let query = world.query_state::<(&Velocity, &mut Position)>(); Self(world, query) } diff --git a/benches/benches/bevy_ecs/iteration/iter_simple_foreach.rs b/benches/benches/bevy_ecs/iteration/iter_simple_foreach.rs index f0a41d18be53b..1ec3f732589ae 100644 --- a/benches/benches/bevy_ecs/iteration/iter_simple_foreach.rs +++ b/benches/benches/bevy_ecs/iteration/iter_simple_foreach.rs @@ -29,7 +29,7 @@ impl<'w> Benchmark<'w> { .take(10_000), ); - let query = world.query::<(&Velocity, &mut Position)>(); + let query = world.query_state::<(&Velocity, &mut Position)>(); Self(world, query) } diff --git a/benches/benches/bevy_ecs/iteration/iter_simple_foreach_hybrid.rs b/benches/benches/bevy_ecs/iteration/iter_simple_foreach_hybrid.rs index 0db614c9aca44..e0fb32a4506a5 100644 --- a/benches/benches/bevy_ecs/iteration/iter_simple_foreach_hybrid.rs +++ b/benches/benches/bevy_ecs/iteration/iter_simple_foreach_hybrid.rs @@ -30,7 +30,7 @@ impl<'w> Benchmark<'w> { world.entity_mut(e).despawn(); } - let query = world.query::<(&mut TableData, &SparseData)>(); + let query = world.query_state::<(&mut TableData, &SparseData)>(); Self(world, query) } diff --git a/benches/benches/bevy_ecs/iteration/iter_simple_foreach_sparse_set.rs b/benches/benches/bevy_ecs/iteration/iter_simple_foreach_sparse_set.rs index 0075c2706ba20..29b2035fff55c 100644 --- a/benches/benches/bevy_ecs/iteration/iter_simple_foreach_sparse_set.rs +++ b/benches/benches/bevy_ecs/iteration/iter_simple_foreach_sparse_set.rs @@ -31,7 +31,7 @@ impl<'w> Benchmark<'w> { .take(10_000), ); - let query = world.query::<(&Velocity, &mut Position)>(); + let query = world.query_state::<(&Velocity, &mut Position)>(); Self(world, query) } diff --git a/benches/benches/bevy_ecs/iteration/iter_simple_foreach_wide.rs b/benches/benches/bevy_ecs/iteration/iter_simple_foreach_wide.rs index 7dbd11d1e0499..da3f906b03dc3 100644 --- a/benches/benches/bevy_ecs/iteration/iter_simple_foreach_wide.rs +++ b/benches/benches/bevy_ecs/iteration/iter_simple_foreach_wide.rs @@ -51,7 +51,7 @@ impl<'w> Benchmark<'w> { .take(10_000), ); - let query = world.query(); + let query = world.query_state(); Self(world, query) } diff --git a/benches/benches/bevy_ecs/iteration/iter_simple_foreach_wide_sparse_set.rs b/benches/benches/bevy_ecs/iteration/iter_simple_foreach_wide_sparse_set.rs index f520ffde42662..185bb5889042a 100644 --- a/benches/benches/bevy_ecs/iteration/iter_simple_foreach_wide_sparse_set.rs +++ b/benches/benches/bevy_ecs/iteration/iter_simple_foreach_wide_sparse_set.rs @@ -53,7 +53,7 @@ impl<'w> Benchmark<'w> { .take(10_000), ); - let query = world.query(); + let query = world.query_state(); Self(world, query) } diff --git a/benches/benches/bevy_ecs/iteration/iter_simple_sparse_set.rs b/benches/benches/bevy_ecs/iteration/iter_simple_sparse_set.rs index e4ba3759412c7..ce646ab0f9b70 100644 --- a/benches/benches/bevy_ecs/iteration/iter_simple_sparse_set.rs +++ b/benches/benches/bevy_ecs/iteration/iter_simple_sparse_set.rs @@ -31,7 +31,7 @@ impl<'w> Benchmark<'w> { .take(10_000), ); - let query = world.query::<(&Velocity, &mut Position)>(); + let query = world.query_state::<(&Velocity, &mut Position)>(); Self(world, query) } diff --git a/benches/benches/bevy_ecs/iteration/iter_simple_wide.rs b/benches/benches/bevy_ecs/iteration/iter_simple_wide.rs index 7d013b3bf6003..4e93cc52d4a18 100644 --- a/benches/benches/bevy_ecs/iteration/iter_simple_wide.rs +++ b/benches/benches/bevy_ecs/iteration/iter_simple_wide.rs @@ -51,7 +51,7 @@ impl<'w> Benchmark<'w> { .take(10_000), ); - let query = world.query(); + let query = world.query_state(); Self(world, query) } diff --git a/benches/benches/bevy_ecs/iteration/iter_simple_wide_sparse_set.rs b/benches/benches/bevy_ecs/iteration/iter_simple_wide_sparse_set.rs index 28a6dbd85dc28..3f22c78a45a11 100644 --- a/benches/benches/bevy_ecs/iteration/iter_simple_wide_sparse_set.rs +++ b/benches/benches/bevy_ecs/iteration/iter_simple_wide_sparse_set.rs @@ -53,7 +53,7 @@ impl<'w> Benchmark<'w> { .take(10_000), ); - let query = world.query(); + let query = world.query_state(); Self(world, query) } diff --git a/benches/benches/bevy_ecs/iteration/par_iter_simple.rs b/benches/benches/bevy_ecs/iteration/par_iter_simple.rs index dfd3f9dfdab0d..efc52fbd4e05e 100644 --- a/benches/benches/bevy_ecs/iteration/par_iter_simple.rs +++ b/benches/benches/bevy_ecs/iteration/par_iter_simple.rs @@ -60,7 +60,7 @@ impl<'w> Benchmark<'w> { insert_if_bit_enabled::<15>(&mut e, i); } - let query = world.query::<(&Velocity, &mut Position)>(); + let query = world.query_state::<(&Velocity, &mut Position)>(); Self(world, query) } diff --git a/benches/benches/bevy_ecs/iteration/par_iter_simple_foreach_hybrid.rs b/benches/benches/bevy_ecs/iteration/par_iter_simple_foreach_hybrid.rs index e2044c0956287..580e1eca95880 100644 --- a/benches/benches/bevy_ecs/iteration/par_iter_simple_foreach_hybrid.rs +++ b/benches/benches/bevy_ecs/iteration/par_iter_simple_foreach_hybrid.rs @@ -32,7 +32,7 @@ impl<'w> Benchmark<'w> { world.entity_mut(e).despawn(); } - let query = world.query::<(&mut TableData, &SparseData)>(); + let query = world.query_state::<(&mut TableData, &SparseData)>(); Self(world, query) } diff --git a/benches/benches/bevy_ecs/world/world_get.rs b/benches/benches/bevy_ecs/world/world_get.rs index 4c235cd1b46e3..83c5875aa37f5 100644 --- a/benches/benches/bevy_ecs/world/world_get.rs +++ b/benches/benches/bevy_ecs/world/world_get.rs @@ -100,7 +100,7 @@ pub fn world_query_get(criterion: &mut Criterion) { for entity_count in RANGE.map(|i| i * 10_000) { group.bench_function(format!("{}_entities_table", entity_count), |bencher| { let mut world = setup::(entity_count); - let mut query = world.query::<&Table>(); + let mut query = world.query_state::<&Table>(); bencher.iter(|| { for i in 0..entity_count { @@ -118,7 +118,7 @@ pub fn world_query_get(criterion: &mut Criterion) { WideTable<4>, WideTable<5>, )>(entity_count); - let mut query = world.query::<( + let mut query = world.query_state::<( &WideTable<0>, &WideTable<1>, &WideTable<2>, @@ -136,7 +136,7 @@ pub fn world_query_get(criterion: &mut Criterion) { }); group.bench_function(format!("{}_entities_sparse", entity_count), |bencher| { let mut world = setup::(entity_count); - let mut query = world.query::<&Sparse>(); + let mut query = world.query_state::<&Sparse>(); bencher.iter(|| { for i in 0..entity_count { @@ -156,7 +156,7 @@ pub fn world_query_get(criterion: &mut Criterion) { WideSparse<4>, WideSparse<5>, )>(entity_count); - let mut query = world.query::<( + let mut query = world.query_state::<( &WideSparse<0>, &WideSparse<1>, &WideSparse<2>, @@ -186,7 +186,7 @@ pub fn world_query_iter(criterion: &mut Criterion) { for entity_count in RANGE.map(|i| i * 10_000) { group.bench_function(format!("{}_entities_table", entity_count), |bencher| { let mut world = setup::
(entity_count); - let mut query = world.query::<&Table>(); + let mut query = world.query_state::<&Table>(); bencher.iter(|| { let mut count = 0; @@ -200,7 +200,7 @@ pub fn world_query_iter(criterion: &mut Criterion) { }); group.bench_function(format!("{}_entities_sparse", entity_count), |bencher| { let mut world = setup::(entity_count); - let mut query = world.query::<&Sparse>(); + let mut query = world.query_state::<&Sparse>(); bencher.iter(|| { let mut count = 0; @@ -225,7 +225,7 @@ pub fn world_query_for_each(criterion: &mut Criterion) { for entity_count in RANGE.map(|i| i * 10_000) { group.bench_function(format!("{}_entities_table", entity_count), |bencher| { let mut world = setup::
(entity_count); - let mut query = world.query::<&Table>(); + let mut query = world.query_state::<&Table>(); bencher.iter(|| { let mut count = 0; @@ -239,7 +239,7 @@ pub fn world_query_for_each(criterion: &mut Criterion) { }); group.bench_function(format!("{}_entities_sparse", entity_count), |bencher| { let mut world = setup::(entity_count); - let mut query = world.query::<&Sparse>(); + let mut query = world.query_state::<&Sparse>(); bencher.iter(|| { let mut count = 0; diff --git a/crates/bevy_core/src/name.rs b/crates/bevy_core/src/name.rs index 8c00762199dfa..be4c84d017708 100644 --- a/crates/bevy_core/src/name.rs +++ b/crates/bevy_core/src/name.rs @@ -226,7 +226,7 @@ mod tests { let e1 = world.spawn_empty().id(); let name = Name::new("MyName"); let e2 = world.spawn(name.clone()).id(); - let mut query = world.query::(); + let mut query = world.query_state::(); let d1 = query.get(&world, e1).unwrap(); let d2 = query.get(&world, e2).unwrap(); // NameOrEntity Display for entities without a Name should be {index}v{generation} diff --git a/crates/bevy_core_pipeline/src/taa/mod.rs b/crates/bevy_core_pipeline/src/taa/mod.rs index af7aaea58889f..a5a4e8670150b 100644 --- a/crates/bevy_core_pipeline/src/taa/mod.rs +++ b/crates/bevy_core_pipeline/src/taa/mod.rs @@ -357,7 +357,7 @@ impl SpecializedRenderPipeline for TaaPipeline { } fn extract_taa_settings(mut commands: Commands, mut main_world: ResMut) { - let mut cameras_3d = main_world.query_filtered::<( + let mut cameras_3d = main_world.query_state_filtered::<( &RenderEntity, &Camera, &Projection, diff --git a/crates/bevy_ecs/macros/src/query_data.rs b/crates/bevy_ecs/macros/src/query_data.rs index 3f198b1ad1b18..57e3994f81414 100644 --- a/crates/bevy_ecs/macros/src/query_data.rs +++ b/crates/bevy_ecs/macros/src/query_data.rs @@ -325,6 +325,14 @@ pub fn derive_query_data_impl(input: TokenStream) -> TokenStream { #(#named_field_idents: <#field_types as #path::query::WorldQuery>::State,)* } + impl #user_impl_generics ::core::clone::Clone for #state_struct_name #user_ty_generics #user_where_clauses { + fn clone(&self) -> Self { + Self { + #(#named_field_idents: ::core::clone::Clone::clone(&self.#named_field_idents),)* + } + } + } + #mutable_world_query_impl #read_only_impl diff --git a/crates/bevy_ecs/macros/src/query_filter.rs b/crates/bevy_ecs/macros/src/query_filter.rs index 378e26df101a7..dc05d1a4558bf 100644 --- a/crates/bevy_ecs/macros/src/query_filter.rs +++ b/crates/bevy_ecs/macros/src/query_filter.rs @@ -158,6 +158,14 @@ pub fn derive_query_filter_impl(input: TokenStream) -> TokenStream { #(#named_field_idents: <#field_types as #path::query::WorldQuery>::State,)* } + impl #user_impl_generics ::core::clone::Clone for #state_struct_name #user_ty_generics #user_where_clauses { + fn clone(&self) -> Self { + Self { + #(#named_field_idents: ::core::clone::Clone::clone(&self.#named_field_idents),)* + } + } + } + #world_query_impl #filter_impl diff --git a/crates/bevy_ecs/src/change_detection.rs b/crates/bevy_ecs/src/change_detection.rs index 5a3adac96fe20..d9d8c1b212b7d 100644 --- a/crates/bevy_ecs/src/change_detection.rs +++ b/crates/bevy_ecs/src/change_detection.rs @@ -1282,7 +1282,7 @@ mod tests { // Since the world is always ahead, as long as changes can't get older than `u32::MAX` (which we ensure), // the wrapping difference will always be positive, so wraparound doesn't matter. - let mut query = world.query::>(); + let mut query = world.query_state::>(); assert!(query.single(&world).is_changed()); } @@ -1297,7 +1297,7 @@ mod tests { *world.change_tick.get_mut() += MAX_CHANGE_AGE + CHECK_TICK_THRESHOLD; let change_tick = world.change_tick(); - let mut query = world.query::>(); + let mut query = world.query_state::>(); for tracker in query.iter(&world) { let ticks_since_insert = change_tick.relative_to(*tracker.ticks.added).get(); let ticks_since_change = change_tick.relative_to(*tracker.ticks.changed).get(); diff --git a/crates/bevy_ecs/src/component.rs b/crates/bevy_ecs/src/component.rs index d9bdbedc333ad..5a11216ecfcc5 100644 --- a/crates/bevy_ecs/src/component.rs +++ b/crates/bevy_ecs/src/component.rs @@ -448,7 +448,7 @@ pub type ComponentHook = for<'w> fn(DeferredWorld<'w>, Entity, ComponentId); /// world.init_resource::(); /// /// // No entities with `MyTrackedComponent` have been added yet, so we can safely add component hooks -/// let mut tracked_component_query = world.query::<&MyTrackedComponent>(); +/// let mut tracked_component_query = world.query_state::<&MyTrackedComponent>(); /// assert!(tracked_component_query.iter(&world).next().is_none()); /// /// world.register_component_hooks::().on_add(|mut world, entity, _component_id| { diff --git a/crates/bevy_ecs/src/lib.rs b/crates/bevy_ecs/src/lib.rs index 3a15cabe3f529..1a5ca72b269b1 100644 --- a/crates/bevy_ecs/src/lib.rs +++ b/crates/bevy_ecs/src/lib.rs @@ -351,7 +351,7 @@ mod tests { let f = world.spawn((TableStored("def"), A(456))).id(); let ents = world - .query::<(Entity, &A, &TableStored)>() + .query_state::<(Entity, &A, &TableStored)>() .iter(&world) .map(|(e, &i, &s)| (e, i, s)) .collect::>(); @@ -372,7 +372,7 @@ mod tests { let mut results = Vec::new(); world - .query::<(Entity, &A, &TableStored)>() + .query_state::<(Entity, &A, &TableStored)>() .iter(&world) .for_each(|(e, &i, &s)| results.push((e, i, s))); assert_eq!( @@ -390,7 +390,7 @@ mod tests { let e = world.spawn((TableStored("abc"), A(123))).id(); let f = world.spawn((TableStored("def"), A(456), B(1))).id(); let ents = world - .query::<(Entity, &A)>() + .query_state::<(Entity, &A)>() .iter(&world) .map(|(e, &i)| (e, i)) .collect::>(); @@ -402,7 +402,7 @@ mod tests { fn stateful_query_handles_new_archetype() { let mut world = World::new(); let e = world.spawn((TableStored("abc"), A(123))).id(); - let mut query = world.query::<(Entity, &A)>(); + let mut query = world.query_state::<(Entity, &A)>(); let ents = query.iter(&world).map(|(e, &i)| (e, i)).collect::>(); assert_eq!(ents, &[(e, A(123))]); @@ -419,7 +419,7 @@ mod tests { let f = world.spawn((TableStored("def"), A(456), B(1))).id(); let mut results = HashSet::new(); world - .query::<(Entity, &A)>() + .query_state::<(Entity, &A)>() .iter(&world) .for_each(|(e, &i)| { results.insert((e, i)); @@ -439,7 +439,7 @@ mod tests { let e5 = world.spawn((A(5), B(1))).id(); let results = Arc::new(Mutex::new(Vec::new())); world - .query::<(Entity, &A)>() + .query_state::<(Entity, &A)>() .par_iter(&world) .for_each(|(e, &A(i))| { results.lock().unwrap().push((e, i)); @@ -462,7 +462,7 @@ mod tests { let e5 = world.spawn((SparseStored(5), A(1))).id(); let results = Arc::new(Mutex::new(Vec::new())); world - .query::<(Entity, &SparseStored)>() + .query_state::<(Entity, &SparseStored)>() .par_iter(&world) .for_each(|(e, &SparseStored(i))| results.lock().unwrap().push((e, i))); results.lock().unwrap().sort(); @@ -477,7 +477,11 @@ mod tests { let mut world = World::new(); world.spawn((TableStored("abc"), A(123))); world.spawn((TableStored("def"), A(456))); - assert!(world.query::<(&B, &A)>().iter(&world).next().is_none()); + assert!(world + .query_state::<(&B, &A)>() + .iter(&world) + .next() + .is_none()); } #[test] @@ -486,7 +490,7 @@ mod tests { world.spawn((TableStored("abc"), A(123))); let f = world.spawn((TableStored("def"), A(456), B(1))).id(); let ents = world - .query::<(Entity, &B)>() + .query_state::<(Entity, &B)>() .iter(&world) .map(|(e, &b)| (e, b)) .collect::>(); @@ -499,7 +503,7 @@ mod tests { world.spawn((A(123), B(1))); world.spawn(A(456)); let result = world - .query_filtered::<&A, With>() + .query_state_filtered::<&A, With>() .iter(&world) .cloned() .collect::>(); @@ -514,7 +518,7 @@ mod tests { let mut results = Vec::new(); world - .query_filtered::<&A, With>() + .query_state_filtered::<&A, With>() .iter(&world) .for_each(|i| results.push(*i)); assert_eq!(results, vec![A(123)]); @@ -527,7 +531,7 @@ mod tests { world.spawn((A(123), SparseStored(321))); world.spawn(A(456)); let result = world - .query_filtered::<&A, With>() + .query_state_filtered::<&A, With>() .iter(&world) .cloned() .collect::>(); @@ -542,7 +546,7 @@ mod tests { world.spawn(A(456)); let mut results = Vec::new(); world - .query_filtered::<&A, With>() + .query_state_filtered::<&A, With>() .iter(&world) .for_each(|i| results.push(*i)); assert_eq!(results, vec![A(123)]); @@ -554,7 +558,7 @@ mod tests { world.spawn((A(123), B(321))); world.spawn(A(456)); let result = world - .query_filtered::<&A, Without>() + .query_state_filtered::<&A, Without>() .iter(&world) .cloned() .collect::>(); @@ -569,7 +573,7 @@ mod tests { // this should be skipped world.spawn(TableStored("abc")); let ents = world - .query::<(Entity, Option<&B>, &A)>() + .query_state::<(Entity, Option<&B>, &A)>() .iter(&world) .map(|(e, b, &i)| (e, b.copied(), i)) .collect::>(); @@ -588,7 +592,7 @@ mod tests { // this should be skipped // world.spawn(SparseStored(1)); let ents = world - .query::<(Entity, Option<&SparseStored>, &A)>() + .query_state::<(Entity, Option<&SparseStored>, &A)>() .iter(&world) .map(|(e, b, &i)| (e, b.copied(), i)) .collect::>(); @@ -607,7 +611,7 @@ mod tests { // // this should be skipped world.spawn(TableStored("abc")); let ents = world - .query::<(Entity, Option<&SparseStored>, &A)>() + .query_state::<(Entity, Option<&SparseStored>, &A)>() .iter(&world) .map(|(e, b, &i)| (e, b.copied(), i)) .collect::>(); @@ -622,7 +626,7 @@ mod tests { assert_eq!( world - .query::<(Entity, &A, &B)>() + .query_state::<(Entity, &A, &B)>() .iter(&world) .map(|(e, &i, &b)| (e, i, b)) .collect::>(), @@ -631,7 +635,7 @@ mod tests { assert_eq!(world.entity_mut(e1).take::(), Some(A(1))); assert_eq!( world - .query::<(Entity, &A, &B)>() + .query_state::<(Entity, &A, &B)>() .iter(&world) .map(|(e, &i, &b)| (e, i, b)) .collect::>(), @@ -639,7 +643,7 @@ mod tests { ); assert_eq!( world - .query::<(Entity, &B, &TableStored)>() + .query_state::<(Entity, &B, &TableStored)>() .iter(&world) .map(|(e, &B(b), &TableStored(s))| (e, b, s)) .collect::>(), @@ -648,7 +652,7 @@ mod tests { world.entity_mut(e1).insert(A(43)); assert_eq!( world - .query::<(Entity, &A, &B)>() + .query_state::<(Entity, &A, &B)>() .iter(&world) .map(|(e, &i, &b)| (e, i, b)) .collect::>(), @@ -657,7 +661,7 @@ mod tests { world.entity_mut(e1).insert(C); assert_eq!( world - .query::<(Entity, &C)>() + .query_state::<(Entity, &C)>() .iter(&world) .map(|(e, &f)| (e, f)) .collect::>(), @@ -725,7 +729,7 @@ mod tests { let mut world = World::new(); world.spawn_batch((0..100).map(|x| (A(x), TableStored("abc")))); let values = world - .query::<&A>() + .query_state::<&A>() .iter(&world) .map(|v| v.0) .collect::>(); @@ -740,11 +744,11 @@ mod tests { let b = world.spawn((TableStored("def"), A(456))).id(); let c = world.spawn((TableStored("ghi"), A(789), B(1))).id(); - let mut i32_query = world.query::<&A>(); + let mut i32_query = world.query_state::<&A>(); assert_eq!(i32_query.get(&world, a).unwrap().0, 123); assert_eq!(i32_query.get(&world, b).unwrap().0, 456); - let mut i32_bool_query = world.query::<(&A, &B)>(); + let mut i32_bool_query = world.query_state::<(&A, &B)>(); assert!(i32_bool_query.get(&world, a).is_err()); assert_eq!(i32_bool_query.get(&world, c).unwrap(), (&A(789), &B(1))); assert!(world.despawn(a)); @@ -761,7 +765,7 @@ mod tests { .spawn((TableStored("ghi"), SparseStored(789), B(1))) .id(); - let mut query = world.query::<&TableStored>(); + let mut query = world.query_state::<&TableStored>(); assert_eq!(query.get(&world, a).unwrap(), &TableStored("abc")); assert_eq!(query.get(&world, b).unwrap(), &TableStored("def")); assert_eq!(query.get(&world, c).unwrap(), &TableStored("ghi")); @@ -850,47 +854,59 @@ mod tests { let mut world = World::new(); let a = world.spawn(A(123)).id(); - assert_eq!(world.query::<&A>().iter(&world).count(), 1); + assert_eq!(world.query_state::<&A>().iter(&world).count(), 1); assert_eq!( - world.query_filtered::<(), Added>().iter(&world).count(), + world + .query_state_filtered::<(), Added>() + .iter(&world) + .count(), 1 ); - assert_eq!(world.query::<&A>().iter(&world).count(), 1); + assert_eq!(world.query_state::<&A>().iter(&world).count(), 1); assert_eq!( - world.query_filtered::<(), Added>().iter(&world).count(), + world + .query_state_filtered::<(), Added>() + .iter(&world) + .count(), 1 ); - assert!(world.query::<&A>().get(&world, a).is_ok()); + assert!(world.query_state::<&A>().get(&world, a).is_ok()); assert!(world - .query_filtered::<(), Added>() + .query_state_filtered::<(), Added>() .get(&world, a) .is_ok()); - assert!(world.query::<&A>().get(&world, a).is_ok()); + assert!(world.query_state::<&A>().get(&world, a).is_ok()); assert!(world - .query_filtered::<(), Added>() + .query_state_filtered::<(), Added>() .get(&world, a) .is_ok()); world.clear_trackers(); - assert_eq!(world.query::<&A>().iter(&world).count(), 1); + assert_eq!(world.query_state::<&A>().iter(&world).count(), 1); assert_eq!( - world.query_filtered::<(), Added>().iter(&world).count(), + world + .query_state_filtered::<(), Added>() + .iter(&world) + .count(), 0 ); - assert_eq!(world.query::<&A>().iter(&world).count(), 1); + assert_eq!(world.query_state::<&A>().iter(&world).count(), 1); assert_eq!( - world.query_filtered::<(), Added>().iter(&world).count(), + world + .query_state_filtered::<(), Added>() + .iter(&world) + .count(), 0 ); - assert!(world.query::<&A>().get(&world, a).is_ok()); + assert!(world.query_state::<&A>().get(&world, a).is_ok()); assert!(world - .query_filtered::<(), Added>() + .query_state_filtered::<(), Added>() .get(&world, a) .is_err()); - assert!(world.query::<&A>().get(&world, a).is_ok()); + assert!(world.query_state::<&A>().get(&world, a).is_ok()); assert!(world - .query_filtered::<(), Added>() + .query_state_filtered::<(), Added>() .get(&world, a) .is_err()); } @@ -902,7 +918,7 @@ mod tests { fn get_added(world: &mut World) -> Vec { world - .query_filtered::>() + .query_state_filtered::>() .iter(world) .collect::>() } @@ -919,7 +935,7 @@ mod tests { assert_eq!(get_added::(&mut world), vec![e2]); let added = world - .query_filtered::, Added)>() + .query_state_filtered::, Added)>() .iter(&world) .collect::>(); assert_eq!(added, vec![e2]); @@ -935,7 +951,11 @@ mod tests { world.clear_trackers(); - for (i, mut a) in world.query::<&mut A>().iter_mut(&mut world).enumerate() { + for (i, mut a) in world + .query_state::<&mut A>() + .iter_mut(&mut world) + .enumerate() + { if i % 2 == 0 { a.0 += 1; } @@ -943,7 +963,7 @@ mod tests { fn get_filtered(world: &mut World) -> HashSet { world - .query_filtered::() + .query_state_filtered::() .iter(world) .collect::>() } @@ -1023,7 +1043,7 @@ mod tests { world.clear_trackers(); for (i, mut a) in world - .query::<&mut SparseStored>() + .query_state::<&mut SparseStored>() .iter_mut(&mut world) .enumerate() { @@ -1034,7 +1054,7 @@ mod tests { fn get_filtered(world: &mut World) -> HashSet { world - .query_filtered::() + .query_state_filtered::() .iter(world) .collect::>() } @@ -1134,7 +1154,7 @@ mod tests { fn get_changed(world: &mut World) -> Vec { world - .query_filtered::>() + .query_state_filtered::>() .iter(world) .collect::>() } @@ -1283,7 +1303,7 @@ mod tests { let e2 = world.spawn((A(2), B(2), TableStored("2"))).id(); world.spawn((A(3), B(3), TableStored("3"))); - let mut query = world.query::<(&B, &TableStored)>(); + let mut query = world.query_state::<(&B, &TableStored)>(); let results = query .iter(&world) .map(|(a, b)| (a.0, b.0)) @@ -1299,7 +1319,7 @@ mod tests { .collect::>(); assert_eq!(results, HashSet::from([(1, "1"), (3, "3"),])); - let mut a_query = world.query::<&A>(); + let mut a_query = world.query_state::<&A>(); let results = a_query.iter(&world).map(|a| a.0).collect::>(); assert_eq!(results, HashSet::from([1, 3, 2])); @@ -1359,7 +1379,7 @@ mod tests { world.spawn((A(0), B(0), C)); world.spawn(C); - let mut query = world.query::<(&A, &B)>(); + let mut query = world.query_state::<(&A, &B)>(); assert_eq!(query.iter(&world).len(), 3); } @@ -1374,55 +1394,55 @@ mod tests { #[should_panic] fn ref_and_mut_query_panic() { let mut world = World::new(); - world.query::<(&A, &mut A)>(); + world.query_state::<(&A, &mut A)>(); } #[test] #[should_panic] fn entity_ref_and_mut_query_panic() { let mut world = World::new(); - world.query::<(EntityRef, &mut A)>(); + world.query_state::<(EntityRef, &mut A)>(); } #[test] #[should_panic] fn mut_and_ref_query_panic() { let mut world = World::new(); - world.query::<(&mut A, &A)>(); + world.query_state::<(&mut A, &A)>(); } #[test] #[should_panic] fn mut_and_entity_ref_query_panic() { let mut world = World::new(); - world.query::<(&mut A, EntityRef)>(); + world.query_state::<(&mut A, EntityRef)>(); } #[test] #[should_panic] fn entity_ref_and_entity_mut_query_panic() { let mut world = World::new(); - world.query::<(EntityRef, EntityMut)>(); + world.query_state::<(EntityRef, EntityMut)>(); } #[test] #[should_panic] fn entity_mut_and_entity_mut_query_panic() { let mut world = World::new(); - world.query::<(EntityMut, EntityMut)>(); + world.query_state::<(EntityMut, EntityMut)>(); } #[test] fn entity_ref_and_entity_ref_query_no_panic() { let mut world = World::new(); - world.query::<(EntityRef, EntityRef)>(); + world.query_state::<(EntityRef, EntityRef)>(); } #[test] #[should_panic] fn mut_and_mut_query_panic() { let mut world = World::new(); - world.query::<(&mut A, &mut A)>(); + world.query_state::<(&mut A, &mut A)>(); } #[test] @@ -1430,7 +1450,7 @@ mod tests { fn multiple_worlds_same_query_iter() { let mut world_a = World::new(); let world_b = World::new(); - let mut query = world_a.query::<&A>(); + let mut query = world_a.query_state::<&A>(); query.iter(&world_a); query.iter(&world_b); } @@ -1438,13 +1458,13 @@ mod tests { #[test] fn query_filters_dont_collide_with_fetches() { let mut world = World::new(); - world.query_filtered::<&mut A, Changed>(); + world.query_state_filtered::<&mut A, Changed>(); } #[test] fn filtered_query_access() { let mut world = World::new(); - let query = world.query_filtered::<&mut A, Changed>(); + let query = world.query_state_filtered::<&mut A, Changed>(); let mut expected = FilteredAccess::::default(); let a_id = world.components.get_id(TypeId::of::()).unwrap(); @@ -1462,7 +1482,7 @@ mod tests { fn multiple_worlds_same_query_get() { let mut world_a = World::new(); let world_b = World::new(); - let mut query = world_a.query::<&A>(); + let mut query = world_a.query_state::<&A>(); let _ = query.get(&world_a, Entity::from_raw(0)); let _ = query.get(&world_b, Entity::from_raw(0)); } @@ -1472,7 +1492,7 @@ mod tests { fn multiple_worlds_same_query_for_each() { let mut world_a = World::new(); let world_b = World::new(); - let mut query = world_a.query::<&A>(); + let mut query = world_a.query_state::<&A>(); query.iter(&world_a).for_each(|_| {}); query.iter(&world_b).for_each(|_| {}); } @@ -1551,8 +1571,8 @@ mod tests { world.spawn(A(1)); world.spawn(SparseStored(1)); - let mut q1 = world.query::<&A>(); - let mut q2 = world.query::<&SparseStored>(); + let mut q1 = world.query_state::<&A>(); + let mut q2 = world.query_state::<&SparseStored>(); assert_eq!(q1.iter(&world).len(), 1); assert_eq!(q2.iter(&world).len(), 1); @@ -1588,7 +1608,7 @@ mod tests { macro_rules! query_min_size { ($query:ty, $filter:ty) => { world - .query_filtered::<$query, $filter>() + .query_state_filtered::<$query, $filter>() .iter(&world) .size_hint() .0 diff --git a/crates/bevy_ecs/src/query/error.rs b/crates/bevy_ecs/src/query/error.rs index 90df07b6a9308..de7ea5899d6d2 100644 --- a/crates/bevy_ecs/src/query/error.rs +++ b/crates/bevy_ecs/src/query/error.rs @@ -122,7 +122,7 @@ mod test { let entity = world.spawn((Present1, Present2)).id(); let err = world - .query::<&NotPresent>() + .query_state::<&NotPresent>() .get(&world, entity) .unwrap_err(); diff --git a/crates/bevy_ecs/src/query/iter.rs b/crates/bevy_ecs/src/query/iter.rs index bf4c5432546f9..47eab87685e03 100644 --- a/crates/bevy_ecs/src/query/iter.rs +++ b/crates/bevy_ecs/src/query/iter.rs @@ -378,7 +378,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> QueryIter<'w, 's, D, F> { /// /// This uses [`slice::sort`] internally. /// - /// Defining the lens works like [`transmute_lens`](crate::system::Query::transmute_lens). + /// Defining the lens works like [`transmute`](crate::system::Query::transmute). /// This includes the allowed parameter type changes listed under [allowed transmutes]. /// However, the lens uses the filter of the original query when present. /// @@ -540,7 +540,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> QueryIter<'w, 's, D, F> { /// /// This uses [`slice::sort_unstable`] internally. /// - /// Defining the lens works like [`transmute_lens`](crate::system::Query::transmute_lens). + /// Defining the lens works like [`transmute`](crate::system::Query::transmute). /// This includes the allowed parameter type changes listed under [allowed transmutes].. /// However, the lens uses the filter of the original query when present. /// @@ -632,7 +632,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> QueryIter<'w, 's, D, F> { /// /// This uses [`slice::sort_by`] internally. /// - /// Defining the lens works like [`transmute_lens`](crate::system::Query::transmute_lens). + /// Defining the lens works like [`transmute`](crate::system::Query::transmute). /// This includes the allowed parameter type changes listed under [allowed transmutes]. /// However, the lens uses the filter of the original query when present. /// @@ -730,7 +730,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> QueryIter<'w, 's, D, F> { /// /// This uses [`slice::sort_unstable_by`] internally. /// - /// Defining the lens works like [`transmute_lens`](crate::system::Query::transmute_lens). + /// Defining the lens works like [`transmute`](crate::system::Query::transmute). /// This includes the allowed parameter type changes listed under [allowed transmutes]. /// However, the lens uses the filter of the original query when present. /// @@ -796,7 +796,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> QueryIter<'w, 's, D, F> { /// /// This uses [`slice::sort_by_key`] internally. /// - /// Defining the lens works like [`transmute_lens`](crate::system::Query::transmute_lens). + /// Defining the lens works like [`transmute`](crate::system::Query::transmute). /// This includes the allowed parameter type changes listed under [allowed transmutes]. /// However, the lens uses the filter of the original query when present. /// @@ -925,7 +925,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> QueryIter<'w, 's, D, F> { /// /// This uses [`slice::sort_unstable_by_key`] internally. /// - /// Defining the lens works like [`transmute_lens`](crate::system::Query::transmute_lens). + /// Defining the lens works like [`transmute`](crate::system::Query::transmute). /// This includes the allowed parameter type changes listed under [allowed transmutes]. /// However, the lens uses the filter of the original query when present. /// @@ -994,7 +994,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> QueryIter<'w, 's, D, F> { /// /// This uses [`slice::sort_by_cached_key`] internally. /// - /// Defining the lens works like [`transmute_lens`](crate::system::Query::transmute_lens). + /// Defining the lens works like [`transmute`](crate::system::Query::transmute). /// This includes the allowed parameter type changes listed under [allowed transmutes]. /// However, the lens uses the filter of the original query when present. /// @@ -2001,7 +2001,7 @@ mod tests { fn query_sorts() { let mut world = World::new(); - let mut query = world.query::(); + let mut query = world.query_state::(); let sort = query.iter(&world).sort::().collect::>(); @@ -2074,7 +2074,7 @@ mod tests { world.spawn((A(2.22),)); { - let mut query = world.query::<&A>(); + let mut query = world.query_state::<&A>(); let mut iter = query.iter(&world); println!( "archetype_entities: {} table_entities: {} current_len: {} current_row: {}", @@ -2104,7 +2104,7 @@ mod tests { world.spawn((Sparse(33),)); { - let mut query = world.query::<&Sparse>(); + let mut query = world.query_state::<&Sparse>(); let mut iter = query.iter(&world); println!( "before_next_call: archetype_entities: {} table_entities: {} current_len: {} current_row: {}", @@ -2129,7 +2129,7 @@ mod tests { fn empty_query_sort_after_next_does_not_panic() { let mut world = World::new(); { - let mut query = world.query::<(&A, &Sparse)>(); + let mut query = world.query_state::<(&A, &Sparse)>(); let mut iter = query.iter(&world); println!( "before_next_call: archetype_entities: {} table_entities: {} current_len: {} current_row: {}", @@ -2157,7 +2157,7 @@ mod tests { world.spawn((A(1.1), Sparse(22))); world.spawn((A(2.22), Sparse(33))); { - let mut query = world.query::<(&A, &Sparse)>(); + let mut query = world.query_state::<(&A, &Sparse)>(); let mut iter = query.iter(&world); println!( "before_next_call: archetype_entities: {} table_entities: {} current_len: {} current_row: {}", diff --git a/crates/bevy_ecs/src/query/mod.rs b/crates/bevy_ecs/src/query/mod.rs index 0a9f664fb50ba..18b1e039c5215 100644 --- a/crates/bevy_ecs/src/query/mod.rs +++ b/crates/bevy_ecs/src/query/mod.rs @@ -134,19 +134,22 @@ mod tests { let mut world = World::new(); world.spawn((A(1), B(1))); world.spawn(A(2)); - let values = world.query::<&A>().iter(&world).collect::>(); + let values = world + .query_state::<&A>() + .iter(&world) + .collect::>(); assert!(values.contains(&A(1))); assert!(values.contains(&A(2))); - for (_a, mut b) in world.query::<(&A, &mut B)>().iter_mut(&mut world) { + for (_a, mut b) in world.query_state::<(&A, &mut B)>().iter_mut(&mut world) { b.0 = 3; } - let values = world.query::<&B>().iter(&world).collect::>(); + let values = world.query_state::<&B>().iter(&world).collect::>(); assert_eq!(values, vec![&B(3)]); } #[test] - fn query_filtered_exactsizeiterator_len() { + fn query_state_filtered_exactsizeiterator_len() { fn choose(n: usize, k: usize) -> usize { if n == 0 || k == 0 || n < k { return 0; @@ -160,7 +163,7 @@ mod tests { D: ReadOnlyQueryData, F: ArchetypeFilter, { - let mut query = world.query_filtered::(); + let mut query = world.query_state_filtered::(); let query_type = type_name::>(); let iter = query.iter_combinations::(world); assert_all_sizes_iterator_equal(iter, expected_size, 0, query_type); @@ -174,7 +177,7 @@ mod tests { D: ReadOnlyQueryData, F: ArchetypeFilter, { - let mut query = world.query_filtered::(); + let mut query = world.query_state_filtered::(); let query_type = type_name::>(); 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); @@ -304,7 +307,10 @@ mod tests { world.spawn(A(3)); world.spawn(A(4)); - let values: HashSet<[&A; 2]> = world.query::<&A>().iter_combinations(&world).collect(); + let values: HashSet<[&A; 2]> = world + .query_state::<&A>() + .iter_combinations(&world) + .collect(); check_combinations( values, HashSet::from([ @@ -316,7 +322,7 @@ mod tests { [&A(3), &A(4)], ]), ); - let mut a_query = world.query::<&A>(); + let mut a_query = world.query_state::<&A>(); let values: HashSet<[&A; 3]> = a_query.iter_combinations(&world).collect(); check_combinations( @@ -329,7 +335,7 @@ mod tests { ]), ); - let mut b_query = world.query::<&B>(); + let mut b_query = world.query_state::<&B>(); assert_eq!( b_query.iter_combinations::<2>(&world).size_hint(), (0, Some(0)) @@ -339,7 +345,7 @@ mod tests { } #[test] - fn query_filtered_iter_combinations() { + fn query_state_filtered_iter_combinations() { use bevy_ecs::query::{Added, Or, With, Without}; let mut world = World::new(); @@ -349,7 +355,7 @@ mod tests { world.spawn(A(3)); world.spawn(A(4)); - let mut a_wout_b = world.query_filtered::<&A, Without>(); + let mut a_wout_b = world.query_state_filtered::<&A, Without>(); let values: HashSet<[&A; 2]> = a_wout_b.iter_combinations(&world).collect(); check_combinations( values, @@ -359,7 +365,7 @@ mod tests { let values: HashSet<[&A; 3]> = a_wout_b.iter_combinations(&world).collect(); check_combinations(values, HashSet::from([[&A(2), &A(3), &A(4)]])); - let mut query = world.query_filtered::<&A, Or<(With, With)>>(); + let mut query = world.query_state_filtered::<&A, Or<(With, With)>>(); let values: HashSet<[&A; 2]> = query.iter_combinations(&world).collect(); check_combinations( values, @@ -373,7 +379,7 @@ mod tests { ]), ); - let mut query = world.query_filtered::<&mut A, Without>(); + let mut query = world.query_state_filtered::<&mut A, Without>(); let mut combinations = query.iter_combinations_mut(&mut world); while let Some([mut a, mut b, mut c]) = combinations.fetch_next() { a.0 += 10; @@ -392,7 +398,7 @@ mod tests { world.spawn((A(3), B(3))); world.spawn((A(4), B(4))); - let mut query_added = world.query_filtered::<&A, Added>(); + let mut query_added = world.query_state_filtered::<&A, Added>(); world.clear_trackers(); world.spawn(A(5)); @@ -419,8 +425,10 @@ mod tests { world.spawn_batch((1..=4).map(Sparse)); - let values: HashSet<[&Sparse; 3]> = - world.query::<&Sparse>().iter_combinations(&world).collect(); + let values: HashSet<[&Sparse; 3]> = world + .query_state::<&Sparse>() + .iter_combinations(&world) + .collect(); check_combinations( values, HashSet::from([ @@ -440,17 +448,20 @@ mod tests { world.spawn(Sparse(2)); let values = world - .query::<&Sparse>() + .query_state::<&Sparse>() .iter(&world) .collect::>(); assert!(values.contains(&Sparse(1))); assert!(values.contains(&Sparse(2))); - for (_a, mut b) in world.query::<(&Sparse, &mut B)>().iter_mut(&mut world) { + for (_a, mut b) in world + .query_state::<(&Sparse, &mut B)>() + .iter_mut(&mut world) + { b.0 = 3; } - let values = world.query::<&B>().iter(&world).collect::>(); + let values = world.query_state::<&B>().iter(&world).collect::>(); assert_eq!(values, vec![&B(3)]); } @@ -462,8 +473,10 @@ mod tests { world.spawn(A(2)); world.spawn(C(3)); - let values: Vec<(Option<&A>, Option<&B>)> = - world.query::>().iter(&world).collect(); + let values: Vec<(Option<&A>, Option<&B>)> = world + .query_state::>() + .iter(&world) + .collect(); assert_eq!( values, @@ -480,7 +493,8 @@ mod tests { world.spawn((A(3), B(1))); world.spawn(A(4)); - let values: HashSet<(&A, bool)> = world.query::<(&A, Has)>().iter(&world).collect(); + let values: HashSet<(&A, bool)> = + world.query_state::<(&A, Has)>().iter(&world).collect(); assert!(values.contains(&(&A(1), true))); assert!(values.contains(&(&A(2), false))); @@ -499,7 +513,7 @@ mod tests { } let mut world = World::new(); - world.query::(); + world.query_state::(); } #[test] @@ -535,12 +549,12 @@ mod tests { } let custom_param_data = world - .query::() + .query_state::() .iter(&world) .map(|item| (*item.a, *item.b)) .collect::>(); let normal_data = world - .query::<(&A, &B)>() + .query_state::<(&A, &B)>() .iter(&world) .map(|(a, b)| (*a, *b)) .collect::>(); @@ -556,12 +570,12 @@ mod tests { } let custom_param_data = world - .query::() + .query_state::() .iter(&world) .map(|fancy| (fancy.e, *fancy.b, fancy.opt.copied())) .collect::>(); let normal_data = world - .query::<(Entity, &B, Option<&Sparse>)>() + .query_state::<(Entity, &B, Option<&Sparse>)>() .iter(&world) .map(|(e, b, opt)| (e, *b, opt.copied())) .collect::>(); @@ -580,7 +594,7 @@ mod tests { } let custom_param_data = world - .query::() + .query_state::() .iter(&world) .map( |MatchEverythingItem { @@ -595,7 +609,7 @@ mod tests { ) .collect::>(); let normal_data = world - .query::<(AnyOf<(&A, &B, &C)>, Option<(&B, &Sparse)>)>() + .query_state::<(AnyOf<(&A, &B, &C)>, Option<(&B, &Sparse)>)>() .iter(&world) .map(|((a, b, c), bsparse)| { ( @@ -618,11 +632,11 @@ mod tests { } let custom_param_entities = world - .query_filtered::() + .query_state_filtered::() .iter(&world) .collect::>(); let normal_entities = world - .query_filtered::, With)>, Without)>() + .query_state_filtered::, With)>, Without)>() .iter(&world) .collect::>(); assert_eq!(custom_param_entities, normal_entities); @@ -636,11 +650,11 @@ mod tests { } let custom_param_entities = world - .query_filtered::() + .query_state_filtered::() .iter(&world) .collect::>(); let normal_entities = world - .query_filtered::, With)>() + .query_state_filtered::, With)>() .iter(&world) .collect::>(); assert_eq!(custom_param_entities, normal_entities); @@ -655,11 +669,11 @@ mod tests { } let custom_param_entities = world - .query_filtered::() + .query_state_filtered::() .iter(&world) .collect::>(); let normal_entities = world - .query_filtered::, Without, Without)>() + .query_state_filtered::, Without, Without)>() .iter(&world) .collect::>(); assert_eq!(custom_param_entities, normal_entities); @@ -673,12 +687,12 @@ mod tests { } let custom_param_data = world - .query::() + .query_state::() .iter_combinations::<2>(&world) .map(|[item0, item1]| [(*item0.a, *item0.b), (*item1.a, *item1.b)]) .collect::>(); let normal_data = world - .query::<(&A, &B)>() + .query_state::<(&A, &B)>() .iter_combinations(&world) .map(|[(a0, b0), (a1, b1)]| [(*a0, *b0), (*a1, *b1)]) .collect::>(); @@ -736,7 +750,7 @@ mod tests { let e = world.spawn(Foo).id(); // state - let mut q = world.query::<&mut Foo>(); + let mut q = world.query_state::<&mut Foo>(); let _: Option<&Foo> = q.iter(&world).next(); let _: Option<[&Foo; 2]> = q.iter_combinations::<2>(&world).next(); let _: Option<&Foo> = q.iter_manual(&world).next(); @@ -789,7 +803,7 @@ mod tests { schedule.run(&mut world); world.clear_trackers(); - let values = world.query::<&B>().iter(&world).collect::>(); + let values = world.query_state::<&B>().iter(&world).collect::>(); assert_eq!(values, vec![&B(2)]); } } diff --git a/crates/bevy_ecs/src/query/state.rs b/crates/bevy_ecs/src/query/state.rs index 69b67368fe4f3..dec444ca65a6f 100644 --- a/crates/bevy_ecs/src/query/state.rs +++ b/crates/bevy_ecs/src/query/state.rs @@ -8,8 +8,10 @@ use crate::{ Access, DebugCheckedUnwrap, FilteredAccess, QueryCombinationIter, QueryIter, QueryParIter, }, storage::{SparseSetIndex, TableId}, + system::Query, world::{unsafe_world_cell::UnsafeWorldCell, World, WorldId}, }; +use alloc::borrow::Cow; use bevy_utils::tracing::warn; #[cfg(feature = "trace")] use bevy_utils::tracing::Span; @@ -80,6 +82,24 @@ pub struct QueryState { par_iter_span: Span, } +impl Clone for QueryState { + fn clone(&self) -> Self { + Self { + world_id: self.world_id, + archetype_generation: self.archetype_generation, + matched_tables: self.matched_tables.clone(), + matched_archetypes: self.matched_archetypes.clone(), + component_access: self.component_access.clone(), + matched_storage_ids: self.matched_storage_ids.clone(), + is_dense: self.is_dense, + fetch_state: self.fetch_state.clone(), + filter_state: self.filter_state.clone(), + #[cfg(feature = "trace")] + par_iter_span: self.par_iter_span.clone(), + } + } +} + impl fmt::Debug for QueryState { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("QueryState") @@ -95,7 +115,7 @@ impl fmt::Debug for QueryState { impl FromWorld for QueryState { fn from_world(world: &mut World) -> Self { - world.query_filtered() + world.query_state_filtered() } } @@ -136,6 +156,43 @@ impl QueryState { &*ptr::from_ref(self).cast::>() } + /// Converts this `QueryState` into a `QueryState` that does not access anything mutably. + pub fn into_readonly(self) -> QueryState { + // 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.into_transmuted_state::() } + } + + /// Converts this `QueryState` into any other `QueryState` with + /// the same `WorldQuery::State` associated types. + /// + /// Consider using `into_readonly` or `into_nop` instead which are safe functions. + ///s + /// # Safety + /// + /// `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 into_transmuted_state< + NewD: QueryData, + NewF: QueryFilter, + >( + self, + ) -> QueryState { + QueryState { + world_id: self.world_id, + archetype_generation: self.archetype_generation, + matched_tables: self.matched_tables, + matched_archetypes: self.matched_archetypes, + component_access: self.component_access, + matched_storage_ids: self.matched_storage_ids, + is_dense: self.is_dense, + fetch_state: self.fetch_state, + filter_state: self.filter_state, + #[cfg(feature = "trace")] + par_iter_span: self.par_iter_span, + } + } + /// Returns the components accessed by this query. pub fn component_access(&self) -> &FilteredAccess { &self.component_access @@ -251,6 +308,62 @@ impl QueryState { state } + /// Creates a [`Query`] using this state and the given [`World`]. + pub fn as_query<'w>(&mut self, world: &'w mut World) -> Query<'w, '_, D, F> { + let (last_run, this_run) = (world.last_change_tick(), world.change_tick()); + // SAFETY: `&mut World` ensures that we have exclusive access to the world. + unsafe { + Query::new( + world.as_unsafe_world_cell(), + Cow::Borrowed(self), + last_run, + this_run, + ) + } + } + + /// Creates a [`Query`] with read-only access using this state and the given [`World`]. + pub fn as_readonly_query<'w>(&self, world: &'w World) -> Query<'w, '_, D::ReadOnly, F> { + let (last_run, this_run) = (world.last_change_tick(), world.read_change_tick()); + // SAFETY: `&World` ensures that we have read-only access to the world. + unsafe { + Query::new( + world.as_unsafe_world_cell_readonly(), + Cow::Borrowed(self.as_readonly()), + last_run, + this_run, + ) + } + } + + /// Creates a [`Query`] using this state and the given [`World`]. + pub fn into_query(self, world: &mut World) -> Query<'_, 'static, D, F> { + let (last_run, this_run) = (world.last_change_tick(), world.change_tick()); + // SAFETY: `&mut World` ensures that we have exclusive access to the world. + unsafe { + Query::new( + world.as_unsafe_world_cell(), + Cow::Owned(self), + last_run, + this_run, + ) + } + } + + /// Creates a [`Query`] with read-only access using this state and the given [`World`]. + pub fn into_readonly_query(self, world: &World) -> Query<'_, 'static, D::ReadOnly, F> { + let (last_run, this_run) = (world.last_change_tick(), world.read_change_tick()); + // SAFETY: `&World` ensures that we have read-only access to the world. + unsafe { + Query::new( + world.as_unsafe_world_cell_readonly(), + Cow::Owned(self.into_readonly()), + last_run, + this_run, + ) + } + } + /// Checks if the query is empty for the given [`World`], where the last change and current tick are given. /// /// This is equivalent to `self.iter().next().is_none()`, and thus the worst case runtime will be `O(n)` @@ -552,7 +665,7 @@ impl QueryState { /// Use this to transform a [`QueryState`] into a more generic [`QueryState`]. /// This can be useful for passing to another function that might take the more general form. - /// See [`Query::transmute_lens`](crate::system::Query::transmute_lens) for more details. + /// See [`Query::transmute`](crate::system::Query::transmute) for more details. /// /// You should not call [`update_archetypes`](Self::update_archetypes) on the returned [`QueryState`] as the result will be unpredictable. /// You might end up with a mix of archetypes that only matched the original query + archetypes that only match @@ -779,7 +892,7 @@ impl QueryState { /// /// world.spawn(A(73)); /// - /// let mut query_state = world.query::<&A>(); + /// let mut query_state = world.query_state::<&A>(); /// /// let component_values = query_state.get_many(&world, entities).unwrap(); /// @@ -852,7 +965,7 @@ impl QueryState { /// /// world.spawn(A(73)); /// - /// let mut query_state = world.query::<&mut A>(); + /// let mut query_state = world.query_state::<&mut A>(); /// /// let mut mutable_component_values = query_state.get_many_mut(&mut world, entities).unwrap(); /// @@ -1428,7 +1541,7 @@ impl QueryState { /// # let entities: Vec = (0..3).map(|i| world.spawn(A(i)).id()).collect(); /// # let entities: [Entity; 3] = entities.try_into().unwrap(); /// - /// let mut query_state = world.query::<&mut A>(); + /// let mut query_state = world.query_state::<&mut A>(); /// /// query_state.par_iter_mut(&mut world).for_each(|mut a| { /// a.0 += 5; @@ -1716,6 +1829,12 @@ impl From> for QueryState From> for QueryState { + fn from(query: Query<'_, '_, D, F>) -> Self { + query.into_state() + } +} + #[cfg(test)] mod tests { use crate as bevy_ecs; @@ -1729,7 +1848,7 @@ mod tests { let entities: Vec = (0..10).map(|_| world.spawn_empty().id()).collect(); - let query_state = world.query::(); + let query_state = world.query_state::(); // These don't matter for the test let last_change_tick = world.last_change_tick(); @@ -1803,7 +1922,7 @@ mod tests { let mut world_1 = World::new(); let world_2 = World::new(); - let mut query_state = world_1.query::(); + let mut query_state = world_1.query_state::(); let _panics = query_state.get(&world_2, Entity::from_raw(0)); } @@ -1813,7 +1932,7 @@ mod tests { let mut world_1 = World::new(); let world_2 = World::new(); - let mut query_state = world_1.query::(); + let mut query_state = world_1.query_state::(); let _panics = query_state.get_many(&world_2, []); } @@ -1823,7 +1942,7 @@ mod tests { let mut world_1 = World::new(); let mut world_2 = World::new(); - let mut query_state = world_1.query::(); + let mut query_state = world_1.query_state::(); let _panics = query_state.get_many_mut(&mut world_2, []); } @@ -1841,7 +1960,7 @@ mod tests { let mut world = World::new(); world.spawn((A(1), B(0))); - let query_state = world.query::<(&A, &B)>(); + let query_state = world.query_state::<(&A, &B)>(); let mut new_query_state = query_state.transmute::<&A>(&world); assert_eq!(new_query_state.iter(&world).len(), 1); let a = new_query_state.single(&world); @@ -1855,7 +1974,7 @@ mod tests { world.spawn((A(0), B(0))); world.spawn((A(1), B(0), C(0))); - let query_state = world.query_filtered::<(&A, &B), Without>(); + let query_state = world.query_state_filtered::<(&A, &B), Without>(); let mut new_query_state = query_state.transmute::<&A>(&world); // even though we change the query to not have Without, we do not get the component with C. let a = new_query_state.single(&world); @@ -1869,7 +1988,7 @@ mod tests { world.register_component::(); let entity = world.spawn(A(10)).id(); - let q = world.query::<()>(); + let q = world.query_state::<()>(); let mut q = q.transmute::(&world); assert_eq!(q.single(&world), entity); } @@ -1879,11 +1998,11 @@ mod tests { let mut world = World::new(); world.spawn(A(10)); - let q = world.query::<&A>(); + let q = world.query_state::<&A>(); let mut new_q = q.transmute::>(&world); assert!(new_q.single(&world).is_added()); - let q = world.query::>(); + let q = world.query_state::>(); let _ = q.transmute::<&A>(&world); } @@ -1892,7 +2011,7 @@ mod tests { let mut world = World::new(); world.spawn(A(0)); - let q = world.query::<&mut A>(); + let q = world.query_state::<&mut A>(); let _ = q.transmute::>(&world); let _ = q.transmute::<&A>(&world); } @@ -1902,7 +2021,7 @@ mod tests { let mut world = World::new(); world.spawn(A(0)); - let q: QueryState> = world.query::(); + let q: QueryState> = world.query_state::(); let _ = q.transmute::(&world); } @@ -1911,7 +2030,7 @@ mod tests { let mut world = World::new(); world.spawn((A(0), B(0))); - let query_state = world.query::<(Option<&A>, &B)>(); + let query_state = world.query_state::<(Option<&A>, &B)>(); let _ = query_state.transmute::>(&world); let _ = query_state.transmute::<&B>(&world); } @@ -1926,7 +2045,7 @@ mod tests { world.register_component::(); world.spawn(A(0)); - let query_state = world.query::<&A>(); + let query_state = world.query_state::<&A>(); let mut _new_query_state = query_state.transmute::<(&A, &B)>(&world); } @@ -1938,7 +2057,7 @@ mod tests { let mut world = World::new(); world.spawn(A(0)); - let query_state = world.query::<&A>(); + let query_state = world.query_state::<&A>(); let mut _new_query_state = query_state.transmute::<&mut A>(&world); } @@ -1950,7 +2069,7 @@ mod tests { let mut world = World::new(); world.spawn(C(0)); - let query_state = world.query::>(); + let query_state = world.query_state::>(); let mut new_query_state = query_state.transmute::<&A>(&world); let x = new_query_state.single(&world); assert_eq!(x.0, 1234); @@ -1964,7 +2083,7 @@ mod tests { let mut world = World::new(); world.register_component::(); - let q = world.query::(); + let q = world.query_state::(); let _ = q.transmute::<&A>(&world); } @@ -2046,7 +2165,7 @@ mod tests { let mut world2 = World::new(); world2.register_component::(); - world.query::<(&A, &B)>().transmute::<&B>(&world2); + world.query_state::<(&A, &B)>().transmute::<&B>(&world2); } /// Regression test for issue #14528 @@ -2065,7 +2184,7 @@ mod tests { world.spawn((Dense, Sparse)); let mut query = world - .query_filtered::<&Dense, With>() + .query_state_filtered::<&Dense, With>() .transmute::<&Dense>(&world); let matched = query.iter(&world).count(); @@ -2086,7 +2205,7 @@ mod tests { world.spawn((Dense, Sparse)); let mut query = world - .query::<&Dense>() + .query_state::<&Dense>() .transmute_filtered::<&Dense, With>(&world); // Note: `transmute_filtered` is supposed to keep the same matched tables/archetypes, diff --git a/crates/bevy_ecs/src/query/world_query.rs b/crates/bevy_ecs/src/query/world_query.rs index f2da8b3558f26..6e5eab7d0512d 100644 --- a/crates/bevy_ecs/src/query/world_query.rs +++ b/crates/bevy_ecs/src/query/world_query.rs @@ -48,7 +48,7 @@ pub unsafe trait WorldQuery { /// State used to construct a [`Self::Fetch`](WorldQuery::Fetch). This will be cached inside [`QueryState`](crate::query::QueryState), /// so it is best to move as much data / computation here as possible to reduce the cost of /// constructing [`Self::Fetch`](WorldQuery::Fetch). - type State: Send + Sync + Sized; + type State: Clone + Send + Sync + Sized; /// This function manually implements subtyping for the query items. fn shrink<'wlong: 'wshort, 'wshort>(item: Self::Item<'wlong>) -> Self::Item<'wshort>; @@ -104,7 +104,10 @@ pub unsafe trait WorldQuery { /// Sets available accesses for implementors with dynamic access such as [`FilteredEntityRef`](crate::world::FilteredEntityRef) /// or [`FilteredEntityMut`](crate::world::FilteredEntityMut). /// - /// Called when constructing a [`QueryLens`](crate::system::QueryLens) or calling [`QueryState::from_builder`](super::QueryState::from_builder) + /// Called inside [`Query::transmute`], [`Query::join`], and [`QueryState::from_builder`](super::QueryState::from_builder) + /// + /// [`Query::transmute`]: crate::system::Query::transmute + /// [`Query::join`]: crate::system::Query::join fn set_access(_state: &mut Self::State, _access: &FilteredAccess) {} /// Fetch [`Self::Item`](`WorldQuery::Item`) for either the given `entity` in the current [`Table`], diff --git a/crates/bevy_ecs/src/storage/blob_vec.rs b/crates/bevy_ecs/src/storage/blob_vec.rs index d42c63a6f1605..3e692ac6bbb5a 100644 --- a/crates/bevy_ecs/src/storage/blob_vec.rs +++ b/crates/bevy_ecs/src/storage/blob_vec.rs @@ -701,7 +701,7 @@ mod tests { let mut count = 0; - let mut q = world.query::<&Zst>(); + let mut q = world.query_state::<&Zst>(); for zst in q.iter(&world) { // Ensure that the references returned are properly aligned. assert_eq!( diff --git a/crates/bevy_ecs/src/system/commands/mod.rs b/crates/bevy_ecs/src/system/commands/mod.rs index 4e10f88bb36b6..995e659cc115f 100644 --- a/crates/bevy_ecs/src/system/commands/mod.rs +++ b/crates/bevy_ecs/src/system/commands/mod.rs @@ -2034,7 +2034,7 @@ mod tests { command_queue.apply(&mut world); assert_eq!(world.entities().len(), 1); let results = world - .query::<(&W, &W)>() + .query_state::<(&W, &W)>() .iter(&world) .map(|(a, b)| (a.0, b.0)) .collect::>(); @@ -2047,7 +2047,7 @@ mod tests { } command_queue.apply(&mut world); let results2 = world - .query::<(&W, &W)>() + .query_state::<(&W, &W)>() .iter(&world) .map(|(a, b)| (a.0, b.0)) .collect::>(); @@ -2067,7 +2067,7 @@ mod tests { } command_queue.apply(&mut world); let results3 = world - .query::<(&W, &W)>() + .query_state::<(&W, &W)>() .iter(&world) .map(|(a, b)| (a.0, b.0)) .collect::>(); @@ -2094,7 +2094,7 @@ mod tests { command_queue1.apply(&mut world); let results = world - .query::<(&W, &W, &W)>() + .query_state::<(&W, &W, &W)>() .iter(&world) .map(|(a, b, c)| (a.0, b.0, c.0)) .collect::>(); @@ -2128,7 +2128,7 @@ mod tests { .id(); command_queue.apply(&mut world); let results_before = world - .query::<(&W, &W)>() + .query_state::<(&W, &W)>() .iter(&world) .map(|(a, b)| (a.0, b.0)) .collect::>(); @@ -2147,13 +2147,13 @@ mod tests { assert_eq!(sparse_is_dropped.load(Ordering::Relaxed), 1); let results_after = world - .query::<(&W, &W)>() + .query_state::<(&W, &W)>() .iter(&world) .map(|(a, b)| (a.0, b.0)) .collect::>(); assert_eq!(results_after, vec![]); let results_after_u64 = world - .query::<&W>() + .query_state::<&W>() .iter(&world) .map(|v| v.0) .collect::>(); @@ -2174,7 +2174,7 @@ mod tests { .id(); command_queue.apply(&mut world); let results_before = world - .query::<(&W, &W)>() + .query_state::<(&W, &W)>() .iter(&world) .map(|(a, b)| (a.0, b.0)) .collect::>(); @@ -2200,13 +2200,13 @@ mod tests { assert_eq!(sparse_is_dropped.load(Ordering::Relaxed), 1); let results_after = world - .query::<(&W, &W)>() + .query_state::<(&W, &W)>() .iter(&world) .map(|(a, b)| (a.0, b.0)) .collect::>(); assert_eq!(results_after, vec![]); let results_after_u64 = world - .query::<&W>() + .query_state::<&W>() .iter(&world) .map(|v| v.0) .collect::>(); diff --git a/crates/bevy_ecs/src/system/mod.rs b/crates/bevy_ecs/src/system/mod.rs index dd6a950f72a8e..bf43b506970ae 100644 --- a/crates/bevy_ecs/src/system/mod.rs +++ b/crates/bevy_ecs/src/system/mod.rs @@ -1547,12 +1547,12 @@ mod tests { fn query_validates_world_id() { let mut world1 = World::new(); let world2 = World::new(); - let qstate = world1.query::<()>(); + let qstate = world1.query_state::<()>(); // SAFETY: doesnt access anything - let query = unsafe { + let query: Query<'_, '_, _, _> = unsafe { Query::new( world2.as_unsafe_world_cell_readonly(), - &qstate, + alloc::borrow::Cow::Borrowed(&qstate), Tick::new(0), Tick::new(0), ) diff --git a/crates/bevy_ecs/src/system/query.rs b/crates/bevy_ecs/src/system/query.rs index f0116e60da50c..10598556a2ae6 100644 --- a/crates/bevy_ecs/src/system/query.rs +++ b/crates/bevy_ecs/src/system/query.rs @@ -8,6 +8,7 @@ use crate::{ }, world::unsafe_world_cell::UnsafeWorldCell, }; +use alloc::borrow::Cow; use core::{ borrow::Borrow, marker::PhantomData, @@ -362,7 +363,7 @@ use core::{ 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, + state: Cow<'state, QueryState>, last_run: Tick, this_run: Tick, } @@ -393,7 +394,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { #[inline] pub(crate) unsafe fn new( world: UnsafeWorldCell<'w>, - state: &'s QueryState, + state: Cow<'s, QueryState>, last_run: Tick, this_run: Tick, ) -> Self { @@ -412,10 +413,17 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { /// For example, `Query<(&mut D1, &D2, &mut D3), With>` will become `Query<(&D1, &D2, &D3), With>`. /// 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, D::ReadOnly, F> { + pub fn to_readonly(&self) -> Query<'_, '_, D::ReadOnly, F> { let new_state = self.state.as_readonly(); // SAFETY: This is memory safe because it turns the query immutable. - unsafe { Query::new(self.world, new_state, self.last_run, self.this_run) } + unsafe { + Query::new( + self.world, + Cow::Borrowed(new_state), + self.last_run, + self.this_run, + ) + } } /// Returns a new `Query` reborrowing the access from this one. The current query will be unusable @@ -442,10 +450,24 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { /// } /// } /// ``` - pub fn reborrow(&mut self) -> Query<'_, 's, D, F> { + pub fn reborrow(&mut self) -> Query<'_, '_, D, F> { // SAFETY: this query is exclusively borrowed while the new one exists, so // no overlapping access can occur. - unsafe { Query::new(self.world, self.state, self.last_run, self.this_run) } + unsafe { + Query::new( + self.world, + Cow::Borrowed(&self.state), + self.last_run, + self.this_run, + ) + } + } + + /// Returns the backing [`QueryState`] of this query. + /// If the state was borrowed when this query was created, + /// a clone of the state will be returned. + pub fn into_state(self) -> QueryState { + self.state.into_owned() } /// Returns an [`Iterator`] over the read-only query items. @@ -475,7 +497,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { /// /// [`iter_mut`](Self::iter_mut) for mutable query items. #[inline] - pub fn iter(&self) -> QueryIter<'_, 's, D::ReadOnly, F> { + pub fn iter(&self) -> QueryIter<'_, '_, 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. @@ -513,7 +535,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { /// /// [`iter`](Self::iter) for read-only query items. #[inline] - pub fn iter_mut(&mut self) -> QueryIter<'_, 's, D, F> { + pub fn iter_mut(&mut self) -> QueryIter<'_, '_, D, F> { // SAFETY: `self.world` has permission to access the required components. unsafe { self.state @@ -546,7 +568,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { #[inline] pub fn iter_combinations( &self, - ) -> QueryCombinationIter<'_, 's, D::ReadOnly, F, K> { + ) -> QueryCombinationIter<'_, '_, 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. @@ -584,7 +606,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { #[inline] pub fn iter_combinations_mut( &mut self, - ) -> QueryCombinationIter<'_, 's, D, F, K> { + ) -> QueryCombinationIter<'_, '_, D, F, K> { // SAFETY: `self.world` has permission to access the required components. unsafe { self.state @@ -632,7 +654,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { pub fn iter_many>>( &self, entities: EntityList, - ) -> QueryManyIter<'_, 's, D::ReadOnly, F, EntityList::IntoIter> { + ) -> QueryManyIter<'_, '_, D::ReadOnly, F, EntityList::IntoIter> { // 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. @@ -683,7 +705,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { pub fn iter_many_mut>>( &mut self, entities: EntityList, - ) -> QueryManyIter<'_, 's, D, F, EntityList::IntoIter> { + ) -> QueryManyIter<'_, '_, D, F, EntityList::IntoIter> { // SAFETY: `self.world` has permission to access the required components. unsafe { self.state.iter_many_unchecked_manual( @@ -709,7 +731,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { /// /// - [`iter`](Self::iter) and [`iter_mut`](Self::iter_mut) for the safe versions. #[inline] - pub unsafe fn iter_unsafe(&self) -> QueryIter<'_, 's, D, F> { + pub unsafe fn iter_unsafe(&self) -> QueryIter<'_, '_, 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. @@ -735,7 +757,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { #[inline] pub unsafe fn iter_combinations_unsafe( &self, - ) -> QueryCombinationIter<'_, 's, D, F, K> { + ) -> QueryCombinationIter<'_, '_, 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. @@ -762,7 +784,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { pub unsafe fn iter_many_unsafe>>( &self, entities: EntityList, - ) -> QueryManyIter<'_, 's, D, F, EntityList::IntoIter> { + ) -> QueryManyIter<'_, '_, D, F, EntityList::IntoIter> { // SAFETY: // - `self.world` has permission to access the required components. // - The caller ensures that this operation will not result in any aliased mutable accesses. @@ -836,7 +858,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { pub fn par_iter_mut(&mut self) -> QueryParIter<'_, '_, D, F> { QueryParIter { world: self.world, - state: self.state, + state: self.state.as_ref(), last_run: self.last_run, this_run: self.this_run, batching_strategy: BatchingStrategy::new(), @@ -1323,13 +1345,13 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { } } - /// Returns a [`QueryLens`] that can be used to get a query with a more general fetch. + /// Returns a [`Query`] that can be used to get a query with a more general fetch. /// /// For example, this can transform a `Query<(&A, &mut B)>` to a `Query<&B>`. /// This can be useful for passing the query to another function. Note that since /// filter terms are dropped, non-archetypal filters like [`Added`](crate::query::Added) and /// [`Changed`](crate::query::Changed) will not be respected. To maintain or change filter - /// terms see [`Self::transmute_lens_filtered`] + /// terms see [`Self::transmute_filtered`] /// /// ## Panics /// @@ -1339,7 +1361,6 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { /// /// ```rust /// # use bevy_ecs::prelude::*; - /// # use bevy_ecs::system::QueryLens; /// # /// # #[derive(Component)] /// # struct A(usize); @@ -1351,19 +1372,19 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { /// # /// # world.spawn((A(10), B(5))); /// # - /// fn reusable_function(lens: &mut QueryLens<&A>) { - /// assert_eq!(lens.query().single().0, 10); + /// fn reusable_function(lens: &mut Query<&A>) { + /// assert_eq!(lens.single().0, 10); /// } /// /// // We can use the function in a system that takes the exact query. /// fn system_1(mut query: Query<&A>) { - /// reusable_function(&mut query.as_query_lens()); + /// reusable_function(&mut query); /// } /// /// // We can also use it with a query that does not match exactly /// // by transmuting it. /// fn system_2(mut query: Query<(&mut A, &B)>) { - /// let mut lens = query.transmute_lens::<&A>(); + /// let mut lens = query.transmute::<&A>(); /// reusable_function(&mut lens); /// } /// @@ -1388,35 +1409,30 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { /// [`EntityLocation`]: crate::entity::EntityLocation /// [`&Archetype`]: crate::archetype::Archetype #[track_caller] - pub fn transmute_lens(&mut self) -> QueryLens<'_, NewD> { - self.transmute_lens_filtered::() + pub fn transmute(&mut self) -> Query<'_, 'static, NewD> { + self.transmute_filtered::() } - /// Equivalent to [`Self::transmute_lens`] but also includes a [`QueryFilter`] type. + /// Equivalent to [`Self::transmute`] but also includes a [`QueryFilter`] type. /// /// Note that the lens will iterate the same tables and archetypes as the original query. This means that /// additional archetypal query terms like [`With`](crate::query::With) and [`Without`](crate::query::Without) /// will not necessarily be respected and non-archetypal terms like [`Added`](crate::query::Added) and /// [`Changed`](crate::query::Changed) will only be respected if they are in the type signature. #[track_caller] - pub fn transmute_lens_filtered( + pub fn transmute_filtered( &mut self, - ) -> QueryLens<'_, NewD, NewF> { + ) -> Query<'_, 'static, NewD, NewF> { let state = self.state.transmute_filtered::(self.world); - QueryLens { + Query { world: self.world, - state, + state: Cow::Owned(state), last_run: self.last_run, this_run: self.this_run, } } - /// Gets a [`QueryLens`] with the same accesses as the existing query - pub fn as_query_lens(&mut self) -> QueryLens<'_, D> { - self.transmute_lens() - } - - /// Returns a [`QueryLens`] that can be used to get a query with the combined fetch. + /// Returns a [`Query`] that can be used to get a query with the combined fetch. /// /// For example, this can take a `Query<&A>` and a `Query<&B>` and return a `Query<(&A, &B)>`. /// The returned query will only return items with both `A` and `B`. Note that since filters @@ -1427,7 +1443,6 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { /// /// ```rust /// # use bevy_ecs::prelude::*; - /// # use bevy_ecs::system::QueryLens; /// # /// # #[derive(Component)] /// # struct Transform; @@ -1447,13 +1462,13 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { /// mut players: Query<&Player>, /// mut enemies: Query<&Enemy> /// ) { - /// let mut players_transforms: QueryLens<(&Transform, &Player)> = transforms.join(&mut players); - /// for (transform, player) in &players_transforms.query() { + /// let mut players_transforms: Query<(&Transform, &Player)> = transforms.join(&mut players); + /// for (transform, player) in &players_transforms { /// // do something with a and b /// } /// - /// let mut enemies_transforms: QueryLens<(&Transform, &Enemy)> = transforms.join(&mut enemies); - /// for (transform, enemy) in &enemies_transforms.query() { + /// let mut enemies_transforms: Query<(&Transform, &Enemy)> = transforms.join(&mut enemies); + /// for (transform, enemy) in &enemies_transforms { /// // do something with a and b /// } /// } @@ -1468,12 +1483,12 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { /// /// ## Allowed Transmutes /// - /// Like `transmute_lens` the query terms can be changed with some restrictions. - /// See [`Self::transmute_lens`] for more details. + /// Like `transmute` the query terms can be changed with some restrictions. + /// See [`Self::transmute`] for more details. pub fn join( &mut self, other: &mut Query, - ) -> QueryLens<'_, NewD> { + ) -> Query<'_, 'static, NewD> { self.join_filtered(other) } @@ -1492,31 +1507,31 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { >( &mut self, other: &mut Query, - ) -> QueryLens<'_, NewD, NewF> { + ) -> Query<'_, 'static, NewD, NewF> { let state = self .state - .join_filtered::(self.world, other.state); - QueryLens { + .join_filtered::(self.world, other.state.as_ref()); + Query { world: self.world, - state, + state: Cow::Owned(state), last_run: self.last_run, this_run: self.this_run, } } } -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>; +impl<'a, D: QueryData, F: QueryFilter> IntoIterator for &'a Query<'_, '_, D, F> { + type Item = ROQueryItem<'a, D>; + type IntoIter = QueryIter<'a, 'a, D::ReadOnly, F>; fn into_iter(self) -> Self::IntoIter { self.iter() } } -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>; +impl<'a, D: QueryData, F: QueryFilter> IntoIterator for &'a mut Query<'_, '_, D, F> { + type Item = D::Item<'a>; + type IntoIter = QueryIter<'a, 'a, D, F>; fn into_iter(self) -> Self::IntoIter { self.iter_mut() @@ -1594,7 +1609,7 @@ impl<'w, 's, D: ReadOnlyQueryData, F: QueryFilter> Query<'w, 's, D, F> { /// # bevy_ecs::system::assert_is_system(report_names_system); /// ``` #[inline] - pub fn iter_inner(&self) -> QueryIter<'w, 's, D::ReadOnly, F> { + pub fn iter_inner(&self) -> QueryIter<'w, '_, D::ReadOnly, F> { // SAFETY: system runs without conflicts with other systems. // same-system queries have runtime borrow checks when they conflict unsafe { @@ -1605,44 +1620,6 @@ impl<'w, 's, D: ReadOnlyQueryData, F: QueryFilter> Query<'w, 's, D, F> { } } -/// Type returned from [`Query::transmute_lens`] containing the new [`QueryState`]. -/// -/// Call [`query`](QueryLens::query) or [`into`](Into::into) to construct the resulting [`Query`] -pub struct QueryLens<'w, Q: QueryData, F: QueryFilter = ()> { - world: UnsafeWorldCell<'w>, - state: QueryState, - last_run: Tick, - this_run: Tick, -} - -impl<'w, Q: QueryData, F: QueryFilter> QueryLens<'w, Q, F> { - /// Create a [`Query`] from the underlying [`QueryState`]. - pub fn query(&mut self) -> Query<'w, '_, Q, F> { - Query { - world: self.world, - state: &self.state, - last_run: self.last_run, - this_run: self.this_run, - } - } -} - -impl<'w, 's, Q: QueryData, F: QueryFilter> From<&'s mut QueryLens<'w, Q, F>> - for Query<'w, 's, Q, F> -{ - fn from(value: &'s mut QueryLens<'w, Q, F>) -> Query<'w, 's, Q, F> { - value.query() - } -} - -impl<'w, 'q, Q: QueryData, F: QueryFilter> From<&'q mut Query<'w, '_, Q, F>> - for QueryLens<'q, Q, F> -{ - fn from(value: &'q mut Query<'w, '_, Q, F>) -> QueryLens<'q, Q, F> { - value.transmute_lens_filtered() - } -} - /// [System parameter] that provides access to single entity's components, much like [`Query::single`]/[`Query::single_mut`]. /// /// This [`SystemParam`](crate::system::SystemParam) fails validation if zero or more than one matching entity exists. diff --git a/crates/bevy_ecs/src/system/system_param.rs b/crates/bevy_ecs/src/system/system_param.rs index 9d06aec04d9ef..67707f12419df 100644 --- a/crates/bevy_ecs/src/system/system_param.rs +++ b/crates/bevy_ecs/src/system/system_param.rs @@ -16,6 +16,7 @@ use crate::{ FromWorld, World, }, }; +use alloc::borrow::Cow; use bevy_ecs_macros::impl_param_set; pub use bevy_ecs_macros::{Resource, SystemParam}; use bevy_ptr::UnsafeCellDeref; @@ -318,7 +319,14 @@ unsafe impl SystemParam for Qu // SAFETY: We have registered all of the query's world accesses, // so the caller ensures that `world` has permission to access any // world data that the query needs. - unsafe { Query::new(world, state, system_meta.last_run, change_tick) } + unsafe { + Query::new( + world, + Cow::Borrowed(state), + system_meta.last_run, + change_tick, + ) + } } } diff --git a/crates/bevy_ecs/src/world/deferred_world.rs b/crates/bevy_ecs/src/world/deferred_world.rs index 45e7a7cf873ee..2696132b32bb5 100644 --- a/crates/bevy_ecs/src/world/deferred_world.rs +++ b/crates/bevy_ecs/src/world/deferred_world.rs @@ -1,3 +1,4 @@ +use alloc::borrow::Cow; use core::ops::Deref; use crate::{ @@ -260,7 +261,7 @@ impl<'w> DeferredWorld<'w> { let world_cell = self.world; Query::new( world_cell, - state, + Cow::Borrowed(state), world_cell.last_change_tick(), world_cell.change_tick(), ) diff --git a/crates/bevy_ecs/src/world/entity_ref.rs b/crates/bevy_ecs/src/world/entity_ref.rs index 7b8dc9465b57e..d50ce0474cf38 100644 --- a/crates/bevy_ecs/src/world/entity_ref.rs +++ b/crates/bevy_ecs/src/world/entity_ref.rs @@ -1826,11 +1826,11 @@ impl<'w> EntityWorldMut<'w> { /// let mut entity = world.spawn_empty(); /// entity.entry().or_insert_with(|| Comp(4)); /// # let entity_id = entity.id(); - /// assert_eq!(world.query::<&Comp>().single(&world).0, 4); + /// assert_eq!(world.query_state::<&Comp>().single(&world).0, 4); /// /// # let mut entity = world.get_entity_mut(entity_id).unwrap(); /// entity.entry::().and_modify(|mut c| c.0 += 1); - /// assert_eq!(world.query::<&Comp>().single(&world).0, 5); + /// assert_eq!(world.query_state::<&Comp>().single(&world).0, 5); /// ``` pub fn entry<'a, T: Component>(&'a mut self) -> Entry<'w, 'a, T> { if self.contains::() { @@ -1914,7 +1914,7 @@ impl<'w, 'a, T: Component> Entry<'w, 'a, T> { /// let mut entity = world.spawn(Comp(0)); /// /// entity.entry::().and_modify(|mut c| c.0 += 1); - /// assert_eq!(world.query::<&Comp>().single(&world).0, 1); + /// assert_eq!(world.query_state::<&Comp>().single(&world).0, 1); /// ``` #[inline] pub fn and_modify)>(self, f: F) -> Self { @@ -1971,11 +1971,11 @@ impl<'w, 'a, T: Component> Entry<'w, 'a, T> { /// /// entity.entry().or_insert(Comp(4)); /// # let entity_id = entity.id(); - /// assert_eq!(world.query::<&Comp>().single(&world).0, 4); + /// assert_eq!(world.query_state::<&Comp>().single(&world).0, 4); /// /// # let mut entity = world.get_entity_mut(entity_id).unwrap(); /// entity.entry().or_insert(Comp(15)).0 *= 2; - /// assert_eq!(world.query::<&Comp>().single(&world).0, 8); + /// assert_eq!(world.query_state::<&Comp>().single(&world).0, 8); /// ``` #[inline] pub fn or_insert(self, default: T) -> Mut<'a, T> { @@ -1999,7 +1999,7 @@ impl<'w, 'a, T: Component> Entry<'w, 'a, T> { /// let mut entity = world.spawn_empty(); /// /// entity.entry().or_insert_with(|| Comp(4)); - /// assert_eq!(world.query::<&Comp>().single(&world).0, 4); + /// assert_eq!(world.query_state::<&Comp>().single(&world).0, 4); /// ``` #[inline] pub fn or_insert_with T>(self, default: F) -> Mut<'a, T> { @@ -2025,7 +2025,7 @@ impl<'w, 'a, T: Component + Default> Entry<'w, 'a, T> { /// let mut entity = world.spawn_empty(); /// /// entity.entry::().or_default(); - /// assert_eq!(world.query::<&Comp>().single(&world).0, 0); + /// assert_eq!(world.query_state::<&Comp>().single(&world).0, 0); /// ``` #[inline] pub fn or_default(self) -> Mut<'a, T> { @@ -2092,7 +2092,7 @@ impl<'w, 'a, T: Component> OccupiedEntry<'w, 'a, T> { /// o.get_mut().0 += 2 /// } /// - /// assert_eq!(world.query::<&Comp>().single(&world).0, 17); + /// assert_eq!(world.query_state::<&Comp>().single(&world).0, 17); /// ``` #[inline] pub fn get_mut(&mut self) -> Mut<'_, T> { @@ -2121,7 +2121,7 @@ impl<'w, 'a, T: Component> OccupiedEntry<'w, 'a, T> { /// o.into_mut().0 += 10; /// } /// - /// assert_eq!(world.query::<&Comp>().single(&world).0, 15); + /// assert_eq!(world.query_state::<&Comp>().single(&world).0, 15); /// ``` #[inline] pub fn into_mut(self) -> Mut<'a, T> { @@ -2145,7 +2145,7 @@ impl<'w, 'a, T: Component> OccupiedEntry<'w, 'a, T> { /// o.insert(Comp(10)); /// } /// - /// assert_eq!(world.query::<&Comp>().single(&world).0, 10); + /// assert_eq!(world.query_state::<&Comp>().single(&world).0, 10); /// ``` #[inline] pub fn insert(&mut self, component: T) { @@ -2168,7 +2168,7 @@ impl<'w, 'a, T: Component> OccupiedEntry<'w, 'a, T> { /// assert_eq!(o.take(), Comp(5)); /// } /// - /// assert_eq!(world.query::<&Comp>().iter(&world).len(), 0); + /// assert_eq!(world.query_state::<&Comp>().iter(&world).len(), 0); /// ``` #[inline] pub fn take(self) -> T { @@ -2200,7 +2200,7 @@ impl<'w, 'a, T: Component> VacantEntry<'w, 'a, T> { /// v.insert(Comp(10)); /// } /// - /// assert_eq!(world.query::<&Comp>().single(&world).0, 10); + /// assert_eq!(world.query_state::<&Comp>().single(&world).0, 10); /// ``` #[inline] pub fn insert(self, component: T) -> Mut<'a, T> { @@ -2225,7 +2225,7 @@ impl<'w, 'a, T: Component> VacantEntry<'w, 'a, T> { /// v.insert_entry(Comp(10)); /// } /// - /// assert_eq!(world.query::<&Comp>().single(&world).0, 10); + /// assert_eq!(world.query_state::<&Comp>().single(&world).0, 10); /// ``` #[inline] pub fn insert_entry(self, component: T) -> OccupiedEntry<'w, 'a, T> { @@ -3774,7 +3774,7 @@ mod tests { unsafe { entity.insert_by_id(test_component_id, ptr) }; }); - let components: Vec<_> = world.query::<&TestComponent>().iter(&world).collect(); + let components: Vec<_> = world.query_state::<&TestComponent>().iter(&world).collect(); assert_eq!(components, vec![&TestComponent(42)]); @@ -3786,7 +3786,7 @@ mod tests { unsafe { entity.insert_by_ids(&[test_component_id], vec![ptr].into_iter()) }; }); - let components: Vec<_> = world.query::<&TestComponent>().iter(&world).collect(); + let components: Vec<_> = world.query_state::<&TestComponent>().iter(&world).collect(); assert_eq!(components, vec![&TestComponent(42), &TestComponent(84)]); } @@ -3810,7 +3810,7 @@ mod tests { }); let dynamic_components: Vec<_> = world - .query::<(&TestComponent, &TestComponent2)>() + .query_state::<(&TestComponent, &TestComponent2)>() .iter(&world) .collect(); @@ -3824,7 +3824,7 @@ mod tests { static_world.spawn((test_component_value, test_component_2_value)); let static_components: Vec<_> = static_world - .query::<(&TestComponent, &TestComponent2)>() + .query_state::<(&TestComponent, &TestComponent2)>() .iter(&static_world) .collect(); @@ -3839,7 +3839,7 @@ mod tests { let mut entity = world.spawn(TestComponent(42)); entity.remove_by_id(test_component_id); - let components: Vec<_> = world.query::<&TestComponent>().iter(&world).collect(); + let components: Vec<_> = world.query_state::<&TestComponent>().iter(&world).collect(); assert_eq!(components, vec![] as Vec<&TestComponent>); @@ -3856,7 +3856,7 @@ mod tests { world.spawn(TestComponent(0)).insert(TestComponent2(0)); - let mut query = world.query::>(); + let mut query = world.query_state::>(); let mut found = false; for entity_ref in query.iter_mut(&mut world) { @@ -3931,7 +3931,7 @@ mod tests { let mut world = World::new(); world.spawn(TestComponent(0)).insert(TestComponent2(0)); - let mut query = world.query::>(); + let mut query = world.query_state::>(); let mut found = false; for mut entity_mut in query.iter_mut(&mut world) { diff --git a/crates/bevy_ecs/src/world/mod.rs b/crates/bevy_ecs/src/world/mod.rs index 00e175cd77e17..678001e2b6a6e 100644 --- a/crates/bevy_ecs/src/world/mod.rs +++ b/crates/bevy_ecs/src/world/mod.rs @@ -44,7 +44,7 @@ use crate::{ removal_detection::RemovedComponentEvents, schedule::{Schedule, ScheduleLabel, Schedules}, storage::{ResourceData, Storages}, - system::{Commands, Resource}, + system::{Commands, Query, Resource}, world::{ command_queue::RawCommandQueue, error::{EntityFetchError, TryRunScheduleError}, @@ -1579,8 +1579,21 @@ impl World { self.last_change_tick = self.increment_change_tick(); } + /// Returns a [`Query`] for the given [`QueryData`]. + pub fn query(&mut self) -> Query<'_, 'static, D, ()> { + self.query_state_filtered::().into_query(self) + } + + /// Returns a [`Query`] for the given filtered [`QueryData`]. + pub fn query_filtered(&mut self) -> Query<'_, 'static, D, F> { + self.query_state_filtered::().into_query(self) + } + /// Returns [`QueryState`] for the given [`QueryData`], which is used to efficiently /// run queries on the [`World`] by storing and reusing the [`QueryState`]. + /// + /// # Examples + /// /// ``` /// use bevy_ecs::{component::Component, entity::Entity, world::World}; /// @@ -1602,7 +1615,7 @@ impl World { /// (Position { x: 0.0, y: 0.0}, Velocity { x: 0.0, y: 1.0 }), /// ]).collect::>(); /// - /// let mut query = world.query::<(&mut Position, &Velocity)>(); + /// let mut query = world.query_state::<(&mut Position, &Velocity)>(); /// for (mut position, velocity) in query.iter_mut(&mut world) { /// position.x += velocity.x; /// position.y += velocity.y; @@ -1629,7 +1642,7 @@ impl World { /// let a = world.spawn((Order(2), Label("second"))).id(); /// let b = world.spawn((Order(3), Label("third"))).id(); /// let c = world.spawn((Order(1), Label("first"))).id(); - /// let mut entities = world.query::<(Entity, &Order, &Label)>() + /// let mut entities = world.query_state::<(Entity, &Order, &Label)>() /// .iter(&world) /// .collect::>(); /// // Sort the query results by their `Order` component before comparing @@ -1642,12 +1655,15 @@ impl World { /// ]); /// ``` #[inline] - pub fn query(&mut self) -> QueryState { - self.query_filtered::() + pub fn query_state(&mut self) -> QueryState { + self.query_state_filtered::() } /// Returns [`QueryState`] for the given filtered [`QueryData`], which is used to efficiently /// run queries on the [`World`] by storing and reusing the [`QueryState`]. + /// + /// # Examples + /// /// ``` /// use bevy_ecs::{component::Component, entity::Entity, world::World, query::With}; /// @@ -1660,13 +1676,13 @@ impl World { /// let e1 = world.spawn(A).id(); /// let e2 = world.spawn((A, B)).id(); /// - /// let mut query = world.query_filtered::>(); + /// let mut query = world.query_state_filtered::>(); /// let matching_entities = query.iter(&world).collect::>(); /// /// assert_eq!(matching_entities, vec![e2]); /// ``` #[inline] - pub fn query_filtered(&mut self) -> QueryState { + pub fn query_state_filtered(&mut self) -> QueryState { QueryState::new(self) } diff --git a/crates/bevy_hierarchy/src/child_builder.rs b/crates/bevy_hierarchy/src/child_builder.rs index ad5819479d049..65f920acf6044 100644 --- a/crates/bevy_hierarchy/src/child_builder.rs +++ b/crates/bevy_hierarchy/src/child_builder.rs @@ -1271,7 +1271,7 @@ mod tests { .add_children(&[child]) .id(); - let mut query = world.query::<&Children>(); + let mut query = world.query_state::<&Children>(); let children = query.get(&world, parent).unwrap(); assert_eq!(**children, [child]); } @@ -1281,7 +1281,7 @@ mod tests { let mut world = World::new(); let parent = world.spawn_empty().add_children(&[]).id(); - let mut query = world.query::<&Children>(); + let mut query = world.query_state::<&Children>(); let children = query.get(&world, parent); assert!(children.is_err()); } diff --git a/crates/bevy_hierarchy/src/hierarchy.rs b/crates/bevy_hierarchy/src/hierarchy.rs index 4a9d71ace7d13..531e9d1bc760d 100644 --- a/crates/bevy_hierarchy/src/hierarchy.rs +++ b/crates/bevy_hierarchy/src/hierarchy.rs @@ -268,7 +268,7 @@ mod tests { queue.apply(&mut world); let mut results = world - .query::<(&N, &Idx)>() + .query_state::<(&N, &Idx)>() .iter(&world) .map(|(a, b)| (a.clone(), *b)) .collect::>(); diff --git a/crates/bevy_input/src/gamepad.rs b/crates/bevy_input/src/gamepad.rs index 1f7c240c5b4ac..1b5aebc6ee8a9 100644 --- a/crates/bevy_input/src/gamepad.rs +++ b/crates/bevy_input/src/gamepad.rs @@ -2038,7 +2038,7 @@ mod tests { assert_eq!( ctx.app .world_mut() - .query::<&Gamepad>() + .query_state::<&Gamepad>() .iter(ctx.app.world()) .len(), 0 @@ -2048,7 +2048,7 @@ mod tests { assert_eq!( ctx.app .world_mut() - .query::<(&Gamepad, &GamepadSettings)>() + .query_state::<(&Gamepad, &GamepadSettings)>() .iter(ctx.app.world()) .len(), 1 @@ -2061,7 +2061,7 @@ mod tests { assert_eq!( ctx.app .world_mut() - .query::<&Gamepad>() + .query_state::<&Gamepad>() .iter(ctx.app.world()) .len(), 0 @@ -2071,7 +2071,7 @@ mod tests { assert_eq!( ctx.app .world_mut() - .query::<(&Gamepad, &GamepadSettings)>() + .query_state::<(&Gamepad, &GamepadSettings)>() .iter(ctx.app.world()) .len(), 1 @@ -2082,14 +2082,14 @@ mod tests { assert!(ctx .app .world_mut() - .query::<&Gamepad>() + .query_state::<&Gamepad>() .get(ctx.app.world(), entity) .is_err()); // Settings should be kept assert!(ctx .app .world_mut() - .query::<&GamepadSettings>() + .query_state::<&GamepadSettings>() .get(ctx.app.world(), entity) .is_ok()); @@ -2099,13 +2099,13 @@ mod tests { assert!(ctx .app .world_mut() - .query::<&Gamepad>() + .query_state::<&Gamepad>() .get(ctx.app.world(), entity) .is_err()); assert!(ctx .app .world_mut() - .query::<&GamepadSettings>() + .query_state::<&GamepadSettings>() .get(ctx.app.world(), entity) .is_ok()); } @@ -2116,7 +2116,7 @@ mod tests { assert_eq!( ctx.app .world_mut() - .query::<&Gamepad>() + .query_state::<&Gamepad>() .iter(ctx.app.world()) .len(), 0 @@ -2128,14 +2128,14 @@ mod tests { assert!(ctx .app .world_mut() - .query::<&Gamepad>() + .query_state::<&Gamepad>() .get(ctx.app.world(), entity) .is_err()); // Settings should be kept assert!(ctx .app .world_mut() - .query::<&GamepadSettings>() + .query_state::<&GamepadSettings>() .get(ctx.app.world(), entity) .is_ok()); } @@ -2147,7 +2147,7 @@ mod tests { assert_eq!( ctx.app .world_mut() - .query::<&Gamepad>() + .query_state::<&Gamepad>() .iter(ctx.app.world()) .len(), 0 @@ -2157,7 +2157,7 @@ mod tests { let mut settings = ctx .app .world_mut() - .query::<&mut GamepadSettings>() + .query_state::<&mut GamepadSettings>() .get_mut(ctx.app.world_mut(), entity) .expect("be alive"); assert_ne!(settings.default_button_settings, button_settings); @@ -2167,7 +2167,7 @@ mod tests { assert_eq!( ctx.app .world_mut() - .query::<&Gamepad>() + .query_state::<&Gamepad>() .iter(ctx.app.world()) .len(), 0 @@ -2177,7 +2177,7 @@ mod tests { let settings = ctx .app .world_mut() - .query::<&GamepadSettings>() + .query_state::<&GamepadSettings>() .get(ctx.app.world(), entity) .expect("be alive"); assert_eq!(settings.default_button_settings, button_settings); @@ -2189,7 +2189,7 @@ mod tests { assert_eq!( ctx.app .world_mut() - .query::<&Gamepad>() + .query_state::<&Gamepad>() .iter(ctx.app.world()) .len(), 0 @@ -2200,7 +2200,7 @@ mod tests { assert_eq!( ctx.app .world_mut() - .query::<&Gamepad>() + .query_state::<&Gamepad>() .iter(ctx.app.world()) .len(), 0 @@ -2208,7 +2208,7 @@ mod tests { assert!(ctx .app .world_mut() - .query::<(Entity, &GamepadSettings)>() + .query_state::<(Entity, &GamepadSettings)>() .get(ctx.app.world(), entity) .is_ok()); } @@ -2523,7 +2523,7 @@ mod tests { assert!(ctx .app .world_mut() - .query::<&Gamepad>() + .query_state::<&Gamepad>() .get(ctx.app.world(), entity) .unwrap() .pressed(GamepadButton::DPadDown)); @@ -2544,7 +2544,7 @@ mod tests { assert!(ctx .app .world_mut() - .query::<&Gamepad>() + .query_state::<&Gamepad>() .get(ctx.app.world(), entity) .unwrap() .pressed(GamepadButton::DPadDown)); @@ -2569,7 +2569,7 @@ mod tests { assert!(ctx .app .world_mut() - .query::<&Gamepad>() + .query_state::<&Gamepad>() .get(ctx.app.world(), entity) .unwrap() .just_pressed(GamepadButton::DPadDown)); @@ -2579,7 +2579,7 @@ mod tests { assert!(!ctx .app .world_mut() - .query::<&Gamepad>() + .query_state::<&Gamepad>() .get(ctx.app.world(), entity) .unwrap() .just_pressed(GamepadButton::DPadDown)); @@ -2628,7 +2628,7 @@ mod tests { assert!(!ctx .app .world_mut() - .query::<&Gamepad>() + .query_state::<&Gamepad>() .get(ctx.app.world(), entity) .unwrap() .pressed(GamepadButton::DPadDown)); @@ -2673,7 +2673,7 @@ mod tests { assert!(ctx .app .world_mut() - .query::<&Gamepad>() + .query_state::<&Gamepad>() .get(ctx.app.world(), entity) .unwrap() .just_released(GamepadButton::DPadDown)); @@ -2683,7 +2683,7 @@ mod tests { assert!(!ctx .app .world_mut() - .query::<&Gamepad>() + .query_state::<&Gamepad>() .get(ctx.app.world(), entity) .unwrap() .just_released(GamepadButton::DPadDown)); diff --git a/crates/bevy_pbr/src/light/mod.rs b/crates/bevy_pbr/src/light/mod.rs index bdcd3c567e942..fac016b1420d7 100644 --- a/crates/bevy_pbr/src/light/mod.rs +++ b/crates/bevy_pbr/src/light/mod.rs @@ -826,7 +826,7 @@ pub fn check_dir_light_mesh_visibility( // TODO: use resource to avoid unnecessary memory alloc let mut defer_queue = core::mem::take(defer_visible_entities_queue.deref_mut()); commands.queue(move |world: &mut World| { - let mut query = world.query::<&mut ViewVisibility>(); + let mut query = world.query_state::<&mut ViewVisibility>(); for entities in defer_queue.iter_mut() { let mut iter = query.iter_many_mut(world, entities.iter()); while let Some(mut view_visibility) = iter.fetch_next() { diff --git a/crates/bevy_render/src/camera/camera_driver_node.rs b/crates/bevy_render/src/camera/camera_driver_node.rs index f01d781478783..5cf6ec7f3cc84 100644 --- a/crates/bevy_render/src/camera/camera_driver_node.rs +++ b/crates/bevy_render/src/camera/camera_driver_node.rs @@ -15,7 +15,7 @@ pub struct CameraDriverNode { impl CameraDriverNode { pub fn new(world: &mut World) -> Self { Self { - cameras: world.query(), + cameras: world.query_state(), } } } diff --git a/crates/bevy_render/src/render_graph/node.rs b/crates/bevy_render/src/render_graph/node.rs index 1e0243e31cdff..12f922aa034a2 100644 --- a/crates/bevy_render/src/render_graph/node.rs +++ b/crates/bevy_render/src/render_graph/node.rs @@ -372,7 +372,7 @@ pub struct ViewNodeRunner { impl ViewNodeRunner { pub fn new(node: N, world: &mut World) -> Self { Self { - view_query: world.query_filtered(), + view_query: world.query_state_filtered(), node, } } diff --git a/crates/bevy_render/src/render_phase/draw.rs b/crates/bevy_render/src/render_phase/draw.rs index 44356331bc705..b00f87a3f8482 100644 --- a/crates/bevy_render/src/render_phase/draw.rs +++ b/crates/bevy_render/src/render_phase/draw.rs @@ -291,8 +291,8 @@ impl> RenderCommandState { pub fn new(world: &mut World) -> Self { Self { state: SystemState::new(world), - view: world.query(), - entity: world.query(), + view: world.query_state(), + entity: world.query_state(), } } } diff --git a/crates/bevy_render/src/sync_world.rs b/crates/bevy_render/src/sync_world.rs index d32462e56f320..7e7dbb5670392 100644 --- a/crates/bevy_render/src/sync_world.rs +++ b/crates/bevy_render/src/sync_world.rs @@ -277,7 +277,7 @@ mod tests { entity_sync_system(&mut main_world, &mut render_world); - let mut q = render_world.query_filtered::>(); + let mut q = render_world.query_state_filtered::>(); // Only one synchronized entity assert!(q.iter(&render_world).count() == 1); diff --git a/crates/bevy_render/src/view/visibility/mod.rs b/crates/bevy_render/src/view/visibility/mod.rs index 011686a9a4148..0f8d5e3520586 100644 --- a/crates/bevy_render/src/view/visibility/mod.rs +++ b/crates/bevy_render/src/view/visibility/mod.rs @@ -715,7 +715,7 @@ mod test { schedule.run(&mut world); world.clear_trackers(); - let mut q = world.query::>(); + let mut q = world.query_state::>(); assert!(!q.get(&world, id1).unwrap().is_changed()); assert!(!q.get(&world, id2).unwrap().is_changed()); diff --git a/crates/bevy_scene/src/bundle.rs b/crates/bevy_scene/src/bundle.rs index 0024b2f77729b..b823bce020ab6 100644 --- a/crates/bevy_scene/src/bundle.rs +++ b/crates/bevy_scene/src/bundle.rs @@ -163,7 +163,7 @@ mod tests { // make sure that the scene was added as a child of the root entity let (scene_entity, scene_component_a) = app .world_mut() - .query::<(Entity, &ComponentA)>() + .query_state::<(Entity, &ComponentA)>() .single(app.world()); assert_eq!(scene_component_a.x, 3.0); assert_eq!(scene_component_a.y, 4.0); diff --git a/crates/bevy_scene/src/dynamic_scene_builder.rs b/crates/bevy_scene/src/dynamic_scene_builder.rs index 208702dd81b3b..5ce5156abc93b 100644 --- a/crates/bevy_scene/src/dynamic_scene_builder.rs +++ b/crates/bevy_scene/src/dynamic_scene_builder.rs @@ -253,7 +253,7 @@ impl<'w> DynamicSceneBuilder<'w> { /// # let mut world = World::default(); /// # world.init_resource::(); /// # let _entity = world.spawn(MyComponent).id(); - /// let mut query = world.query_filtered::>(); + /// let mut query = world.query_state_filtered::>(); /// /// let scene = DynamicSceneBuilder::from_world(&world) /// .extract_entities(query.iter(&world)) @@ -526,7 +526,7 @@ mod tests { let entity_a = world.spawn(ComponentA).id(); let _entity_b = world.spawn(ComponentB).id(); - let mut query = world.query_filtered::>(); + let mut query = world.query_state_filtered::>(); let scene = DynamicSceneBuilder::from_world(&world) .extract_entities(query.iter(&world)) .build(); diff --git a/crates/bevy_scene/src/scene_spawner.rs b/crates/bevy_scene/src/scene_spawner.rs index e192aa4324be8..63f8346db6372 100644 --- a/crates/bevy_scene/src/scene_spawner.rs +++ b/crates/bevy_scene/src/scene_spawner.rs @@ -503,11 +503,13 @@ mod tests { // start test world.spawn(A(42)); - assert_eq!(world.query::<&A>().iter(&world).len(), 1); + assert_eq!(world.query_state::<&A>().iter(&world).len(), 1); // clone only existing entity let mut scene_spawner = SceneSpawner::default(); - let entity = world.query_filtered::>().single(&world); + let entity = world + .query_state_filtered::>() + .single(&world); let scene = DynamicSceneBuilder::from_world(&world) .extract_entity(entity) .build(); @@ -518,7 +520,7 @@ mod tests { .unwrap(); // verify we spawned exactly one new entity with our expected component - assert_eq!(world.query::<&A>().iter(&world).len(), 2); + assert_eq!(world.query_state::<&A>().iter(&world).len(), 2); // verify that we can get this newly-spawned entity by the instance ID let new_entity = scene_spawner @@ -531,7 +533,7 @@ mod tests { // verify this new entity contains the same data as the original entity let [old_a, new_a] = world - .query::<&A>() + .query_state::<&A>() .get_many(&world, [entity, new_entity]) .unwrap(); assert_eq!(old_a, new_a); diff --git a/crates/bevy_scene/src/serde.rs b/crates/bevy_scene/src/serde.rs index 0cf4efa128fff..da42a8539b638 100644 --- a/crates/bevy_scene/src/serde.rs +++ b/crates/bevy_scene/src/serde.rs @@ -722,9 +722,9 @@ mod tests { let my_resource = my_resource.unwrap(); assert_eq!(my_resource.foo, 123); - assert_eq!(3, dst_world.query::<&Foo>().iter(&dst_world).count()); - assert_eq!(2, dst_world.query::<&Bar>().iter(&dst_world).count()); - assert_eq!(1, dst_world.query::<&Baz>().iter(&dst_world).count()); + assert_eq!(3, dst_world.query_state::<&Foo>().iter(&dst_world).count()); + assert_eq!(2, dst_world.query_state::<&Bar>().iter(&dst_world).count()); + assert_eq!(1, dst_world.query_state::<&Baz>().iter(&dst_world).count()); } fn roundtrip_ron(world: &World) -> (DynamicScene, DynamicScene) { @@ -762,18 +762,18 @@ mod tests { assert_scene_eq(&scene, &deserialized_scene); let bar_to_foo = dst_world - .query_filtered::<&MyEntityRef, Without>() + .query_state_filtered::<&MyEntityRef, Without>() .get_single(&dst_world) .cloned() .unwrap(); let foo = dst_world - .query_filtered::>() + .query_state_filtered::>() .get_single(&dst_world) .unwrap(); assert_eq!(foo, bar_to_foo.0); assert!(dst_world - .query_filtered::<&MyEntityRef, With>() + .query_state_filtered::<&MyEntityRef, With>() .iter(&dst_world) .all(|r| world.get_entity(r.0).is_err())); } @@ -793,7 +793,7 @@ mod tests { deserialized_scene .write_to_world(&mut world, &mut EntityHashMap::default()) .unwrap(); - assert_eq!(&qux, world.query::<&Qux>().single(&world)); + assert_eq!(&qux, world.query_state::<&Qux>().single(&world)); } #[test] diff --git a/crates/bevy_transform/src/systems.rs b/crates/bevy_transform/src/systems.rs index 4935d05f8ffed..ea984a95557f5 100644 --- a/crates/bevy_transform/src/systems.rs +++ b/crates/bevy_transform/src/systems.rs @@ -422,7 +422,7 @@ mod test { // Note that at this point, the `GlobalTransform`s will not have updated yet, due to `Commands` delay app.update(); - let mut state = app.world_mut().query::<&GlobalTransform>(); + let mut state = app.world_mut().query_state::<&GlobalTransform>(); for global in state.iter(app.world()) { assert_eq!(global, &GlobalTransform::from_translation(translation)); } diff --git a/crates/bevy_ui/src/layout/mod.rs b/crates/bevy_ui/src/layout/mod.rs index 477affba93fa4..d7b4c72e1909a 100644 --- a/crates/bevy_ui/src/layout/mod.rs +++ b/crates/bevy_ui/src/layout/mod.rs @@ -632,7 +632,7 @@ mod tests { // despawn all cameras so we can reset ui_surface back to a fresh state let camera_entities = world - .query_filtered::>() + .query_state_filtered::>() .iter(&world) .collect::>(); for camera_entity in camera_entities { @@ -849,7 +849,7 @@ mod tests { ui_schedule.run(&mut world); let overlap_check = world - .query_filtered::<(Entity, &Node, &GlobalTransform), Without>() + .query_state_filtered::<(Entity, &Node, &GlobalTransform), Without>() .iter(&world) .fold( Option::<(Rect, bool)>::None, @@ -950,7 +950,7 @@ mod tests { world.run_system_once_with(new_pos, move_ui_node).unwrap(); ui_schedule.run(world); let (ui_node_entity, TargetCamera(target_camera_entity)) = world - .query_filtered::<(Entity, &TargetCamera), With>() + .query_state_filtered::<(Entity, &TargetCamera), With>() .get_single(world) .expect("missing MovingUiNode"); assert_eq!(expected_camera_entity, target_camera_entity); @@ -994,7 +994,7 @@ mod tests { ui_schedule.run(&mut world); let pos_inc = Vec2::splat(1.); - let total_cameras = world.query::<&Camera>().iter(&world).len(); + let total_cameras = world.query_state::<&Camera>().iter(&world).len(); // add total cameras - 1 (the assumed default) to get an idea for how many nodes we should expect let expected_max_taffy_node_count = get_taffy_node_count(&world) + total_cameras - 1; @@ -1003,7 +1003,7 @@ mod tests { ui_schedule.run(&mut world); let viewport_rects = world - .query::<(Entity, &Camera)>() + .query_state::<(Entity, &Camera)>() .iter(&world) .map(|(e, c)| (e, c.logical_viewport_rect().expect("missing viewport"))) .collect::>(); diff --git a/crates/bevy_ui/src/render/render_pass.rs b/crates/bevy_ui/src/render/render_pass.rs index 08ee870668fcf..1ec628c844251 100644 --- a/crates/bevy_ui/src/render/render_pass.rs +++ b/crates/bevy_ui/src/render/render_pass.rs @@ -25,8 +25,8 @@ pub struct UiPassNode { impl UiPassNode { pub fn new(world: &mut World) -> Self { Self { - ui_view_query: world.query_filtered(), - default_camera_view_query: world.query(), + ui_view_query: world.query_state_filtered(), + default_camera_view_query: world.query_state(), } } } diff --git a/crates/bevy_ui/src/stack.rs b/crates/bevy_ui/src/stack.rs index a8d535fa2ff27..c3a2e51f5403f 100644 --- a/crates/bevy_ui/src/stack.rs +++ b/crates/bevy_ui/src/stack.rs @@ -227,7 +227,7 @@ mod tests { schedule.add_systems(ui_stack_system); schedule.run(&mut world); - let mut query = world.query::<&Label>(); + let mut query = world.query_state::<&Label>(); let ui_stack = world.resource::(); let actual_result = ui_stack .uinodes @@ -283,7 +283,7 @@ mod tests { schedule.add_systems(ui_stack_system); schedule.run(&mut world); - let mut query = world.query::<&Label>(); + let mut query = world.query_state::<&Label>(); let ui_stack = world.resource::(); let actual_result = ui_stack .uinodes diff --git a/crates/bevy_winit/src/state.rs b/crates/bevy_winit/src/state.rs index b9c9bdfb40ed1..12cac42e28dc9 100644 --- a/crates/bevy_winit/src/state.rs +++ b/crates/bevy_winit/src/state.rs @@ -415,7 +415,9 @@ impl ApplicationHandler for WinitAppRunnerState { _ => {} } - let mut windows = self.world_mut().query::<(&mut Window, &mut CachedWindow)>(); + let mut windows = self + .world_mut() + .query_state::<(&mut Window, &mut CachedWindow)>(); if let Ok((window_component, mut cache)) = windows.get_mut(self.world_mut(), window) { if window_component.is_changed() { cache.window = window_component.clone(); @@ -482,7 +484,7 @@ impl ApplicationHandler for WinitAppRunnerState { // This will trigger the surface destruction. let mut query = self .world_mut() - .query_filtered::>(); + .query_state_filtered::>(); let entity = query.single(&self.world()); self.world_mut() .entity_mut(entity) @@ -502,7 +504,7 @@ impl ApplicationHandler for WinitAppRunnerState { // Get windows that are cached but without raw handles. Those window were already created, but got their // handle wrapper removed when the app was suspended. let mut query = self.world_mut() - .query_filtered::<(Entity, &Window), (With, Without)>(); + .query_state_filtered::<(Entity, &Window), (With, Without)>(); if let Ok((entity, window)) = query.get_single(&self.world()) { let window = window.clone(); diff --git a/examples/tools/scene_viewer/scene_viewer_plugin.rs b/examples/tools/scene_viewer/scene_viewer_plugin.rs index f77508ab8263d..2d983d7fa8ecd 100644 --- a/examples/tools/scene_viewer/scene_viewer_plugin.rs +++ b/examples/tools/scene_viewer/scene_viewer_plugin.rs @@ -115,7 +115,7 @@ fn scene_load_check( let mut query = scene .world - .query::<(Option<&DirectionalLight>, Option<&PointLight>)>(); + .query_state::<(Option<&DirectionalLight>, Option<&PointLight>)>(); scene_handle.has_light = query .iter(&scene.world) diff --git a/tests/how_to_test_systems.rs b/tests/how_to_test_systems.rs index ac4fc2f732336..e414b92d98f3c 100644 --- a/tests/how_to_test_systems.rs +++ b/tests/how_to_test_systems.rs @@ -133,7 +133,13 @@ fn spawn_enemy_using_input_resource() { app.update(); // Check resulting changes, one entity has been spawned with `Enemy` component - assert_eq!(app.world_mut().query::<&Enemy>().iter(app.world()).len(), 1); + assert_eq!( + app.world_mut() + .query_state::<&Enemy>() + .iter(app.world()) + .len(), + 1 + ); // Clear the `just_pressed` status for all `KeyCode`s app.world_mut() @@ -144,7 +150,13 @@ fn spawn_enemy_using_input_resource() { app.update(); // Check resulting changes, no new entity has been spawned - assert_eq!(app.world_mut().query::<&Enemy>().iter(app.world()).len(), 1); + assert_eq!( + app.world_mut() + .query_state::<&Enemy>() + .iter(app.world()) + .len(), + 1 + ); } #[test]