diff --git a/benches/benches/bevy_ecs/world/mod.rs b/benches/benches/bevy_ecs/world/mod.rs index e35dc999c2eb8..2b1b948d9f2c3 100644 --- a/benches/benches/bevy_ecs/world/mod.rs +++ b/benches/benches/bevy_ecs/world/mod.rs @@ -31,8 +31,8 @@ criterion_group!( world_despawn, world_despawn_recursive, query_get, - query_get_many::<2>, - query_get_many::<5>, - query_get_many::<10>, + query_many::<2>, + query_many::<5>, + query_many::<10>, entity_set_build_and_lookup, ); diff --git a/benches/benches/bevy_ecs/world/world_get.rs b/benches/benches/bevy_ecs/world/world_get.rs index 283b984186150..2f594e7a02ebd 100644 --- a/benches/benches/bevy_ecs/world/world_get.rs +++ b/benches/benches/bevy_ecs/world/world_get.rs @@ -307,8 +307,8 @@ pub fn query_get(criterion: &mut Criterion) { group.finish(); } -pub fn query_get_many(criterion: &mut Criterion) { - let mut group = criterion.benchmark_group(format!("query_get_many_{N}")); +pub fn query_many(criterion: &mut Criterion) { + let mut group = criterion.benchmark_group(format!("query_many_{N}")); group.warm_up_time(core::time::Duration::from_millis(500)); group.measurement_time(core::time::Duration::from_secs(2 * N as u64)); @@ -325,10 +325,7 @@ pub fn query_get_many(criterion: &mut Criterion) { bencher.iter(|| { let mut count = 0; - for comp in entity_groups - .iter() - .filter_map(|&ids| query.get_many(ids).ok()) - { + for comp in entity_groups.iter().filter_map(|&ids| query.many(ids).ok()) { black_box(comp); count += 1; black_box(count); @@ -348,10 +345,7 @@ pub fn query_get_many(criterion: &mut Criterion) { bencher.iter(|| { let mut count = 0; - for comp in entity_groups - .iter() - .filter_map(|&ids| query.get_many(ids).ok()) - { + for comp in entity_groups.iter().filter_map(|&ids| query.many(ids).ok()) { black_box(comp); count += 1; black_box(count); diff --git a/crates/bevy_ecs/compile_fail/tests/ui/system_query_get_many_lifetime_safety.rs b/crates/bevy_ecs/compile_fail/tests/ui/system_query_many_lifetime_safety.rs similarity index 82% rename from crates/bevy_ecs/compile_fail/tests/ui/system_query_get_many_lifetime_safety.rs rename to crates/bevy_ecs/compile_fail/tests/ui/system_query_many_lifetime_safety.rs index 522d4628f65f1..e2ac17a2c6fa6 100644 --- a/crates/bevy_ecs/compile_fail/tests/ui/system_query_get_many_lifetime_safety.rs +++ b/crates/bevy_ecs/compile_fail/tests/ui/system_query_many_lifetime_safety.rs @@ -4,7 +4,7 @@ use bevy_ecs::prelude::*; struct A(usize); fn system(mut query: Query<&mut A>, e: Entity) { - let a1 = query.get_many([e, e]).unwrap(); + let a1 = query.many([e, e]).unwrap(); let a2 = query.get_mut(e).unwrap(); //~^ E0502 println!("{} {}", a1[0].0, a2.0); diff --git a/crates/bevy_ecs/compile_fail/tests/ui/system_query_get_many_lifetime_safety.stderr b/crates/bevy_ecs/compile_fail/tests/ui/system_query_many_lifetime_safety.stderr similarity index 80% rename from crates/bevy_ecs/compile_fail/tests/ui/system_query_get_many_lifetime_safety.stderr rename to crates/bevy_ecs/compile_fail/tests/ui/system_query_many_lifetime_safety.stderr index 91e8b81509e05..84ac10aada624 100644 --- a/crates/bevy_ecs/compile_fail/tests/ui/system_query_get_many_lifetime_safety.stderr +++ b/crates/bevy_ecs/compile_fail/tests/ui/system_query_many_lifetime_safety.stderr @@ -1,7 +1,7 @@ error[E0502]: cannot borrow `query` as mutable because it is also borrowed as immutable - --> tests/ui/system_query_get_many_lifetime_safety.rs:8:14 + --> tests/ui/system_query_many_lifetime_safety.rs:8:14 | -7 | let a1 = query.get_many([e, e]).unwrap(); +7 | let a1 = query.many([e, e]).unwrap(); | ----- immutable borrow occurs here 8 | let a2 = query.get_mut(e).unwrap(); | ^^^^^^^^^^^^^^^^ mutable borrow occurs here diff --git a/crates/bevy_ecs/compile_fail/tests/ui/system_query_get_many_mut_lifetime_safety.rs b/crates/bevy_ecs/compile_fail/tests/ui/system_query_many_mut_lifetime_safety.rs similarity index 80% rename from crates/bevy_ecs/compile_fail/tests/ui/system_query_get_many_mut_lifetime_safety.rs rename to crates/bevy_ecs/compile_fail/tests/ui/system_query_many_mut_lifetime_safety.rs index 5a45ffd65e062..7e732b52c924b 100644 --- a/crates/bevy_ecs/compile_fail/tests/ui/system_query_get_many_mut_lifetime_safety.rs +++ b/crates/bevy_ecs/compile_fail/tests/ui/system_query_many_mut_lifetime_safety.rs @@ -4,7 +4,7 @@ use bevy_ecs::prelude::*; struct A(usize); fn system(mut query: Query<&mut A>, e: Entity) { - let a1 = query.get_many_mut([e, e]).unwrap(); + let a1 = query.many_mut([e, e]).unwrap(); let a2 = query.get_mut(e).unwrap(); //~^ E0499 println!("{} {}", a1[0].0, a2.0); diff --git a/crates/bevy_ecs/compile_fail/tests/ui/system_query_get_many_mut_lifetime_safety.stderr b/crates/bevy_ecs/compile_fail/tests/ui/system_query_many_mut_lifetime_safety.stderr similarity index 79% rename from crates/bevy_ecs/compile_fail/tests/ui/system_query_get_many_mut_lifetime_safety.stderr rename to crates/bevy_ecs/compile_fail/tests/ui/system_query_many_mut_lifetime_safety.stderr index 567a1da1a683e..49789f594d38f 100644 --- a/crates/bevy_ecs/compile_fail/tests/ui/system_query_get_many_mut_lifetime_safety.stderr +++ b/crates/bevy_ecs/compile_fail/tests/ui/system_query_many_mut_lifetime_safety.stderr @@ -1,7 +1,7 @@ error[E0499]: cannot borrow `query` as mutable more than once at a time - --> tests/ui/system_query_get_many_mut_lifetime_safety.rs:8:14 + --> tests/ui/system_query_many_mut_lifetime_safety.rs:8:14 | -7 | let a1 = query.get_many_mut([e, e]).unwrap(); +7 | let a1 = query.many_mut([e, e]).unwrap(); | ----- first mutable borrow occurs here 8 | let a2 = query.get_mut(e).unwrap(); | ^^^^^ second mutable borrow occurs here diff --git a/crates/bevy_ecs/src/lib.rs b/crates/bevy_ecs/src/lib.rs index 8d415d7469183..13e61de82feac 100644 --- a/crates/bevy_ecs/src/lib.rs +++ b/crates/bevy_ecs/src/lib.rs @@ -1820,7 +1820,7 @@ mod tests { world.insert_batch(values); let mut query = world.query::<(Option<&A>, &B, &C)>(); - let component_values = query.get_many(&world, [e0, e1, e2]).unwrap(); + let component_values = query.many(&world, [e0, e1, e2]).unwrap(); assert_eq!( component_values, diff --git a/crates/bevy_ecs/src/query/error.rs b/crates/bevy_ecs/src/query/error.rs index 4b5544998cc0e..609040ebea1c9 100644 --- a/crates/bevy_ecs/src/query/error.rs +++ b/crates/bevy_ecs/src/query/error.rs @@ -17,7 +17,7 @@ pub enum QueryEntityError<'w> { EntityDoesNotExist(EntityDoesNotExistError), /// The [`Entity`] was requested mutably more than once. /// - /// See [`Query::get_many_mut`](crate::system::Query::get_many_mut) for an example. + /// See [`Query::many_mut`](crate::system::Query::many_mut) for an example. AliasedMutability(Entity), } diff --git a/crates/bevy_ecs/src/query/mod.rs b/crates/bevy_ecs/src/query/mod.rs index 9c8e2323c23b0..f0d1a57301fb9 100644 --- a/crates/bevy_ecs/src/query/mod.rs +++ b/crates/bevy_ecs/src/query/mod.rs @@ -438,14 +438,14 @@ mod tests { } #[test] - fn get_many_only_mut_checks_duplicates() { + fn many_only_mut_checks_duplicates() { let mut world = World::new(); let id = world.spawn(A(10)).id(); let mut query_state = world.query::<&mut A>(); let mut query = query_state.query_mut(&mut world); - let result = query.get_many([id, id]); + let result = query.many([id, id]); assert_eq!(result, Ok([&A(10), &A(10)])); - let mut_result = query.get_many_mut([id, id]); + let mut_result = query.many_mut([id, id]); assert!(mut_result.is_err()); } @@ -762,9 +762,8 @@ mod tests { let _: Option<&Foo> = q.get(&world, e).ok(); let _: Option<&Foo> = q.get_manual(&world, e).ok(); - let _: Option<[&Foo; 1]> = q.get_many(&world, [e]).ok(); + let _: Option<[&Foo; 1]> = q.many(&world, [e]).ok(); let _: Option<&Foo> = q.single(&world).ok(); - let _: &Foo = q.single(&world).unwrap(); // system param let mut q = SystemState::>::new(&mut world); @@ -775,10 +774,8 @@ mod tests { q.iter().for_each(|_: &Foo| ()); let _: Option<&Foo> = q.get(e).ok(); - let _: Option<[&Foo; 1]> = q.get_many([e]).ok(); + let _: Option<[&Foo; 1]> = q.many([e]).ok(); let _: Option<&Foo> = q.single().ok(); - let _: [&Foo; 1] = q.many([e]); - let _: &Foo = q.single().unwrap(); } // regression test for https://github.com/bevyengine/bevy/pull/8029 diff --git a/crates/bevy_ecs/src/query/state.rs b/crates/bevy_ecs/src/query/state.rs index ce58ee9cf4296..28301bf83bbae 100644 --- a/crates/bevy_ecs/src/query/state.rs +++ b/crates/bevy_ecs/src/query/state.rs @@ -919,12 +919,25 @@ impl QueryState { self.query(world).get_inner(entity) } + /// Returns the read-only query results for the given array of [`Entity`]. + /// + /// Deprecated alias for [`Self::many`]. + #[inline] + #[deprecated(note = "Use `many` instead, which now returns a Result.")] + pub fn get_many<'w, const N: usize>( + &mut self, + world: &'w World, + entities: [Entity; N], + ) -> Result<[ROQueryItem<'w, D>; N], QueryEntityError<'w>> { + self.query(world).many_inner(entities) + } + /// Returns the read-only query results for the given array of [`Entity`]. /// /// In case of a nonexisting entity or mismatched component, a [`QueryEntityError`] is /// returned instead. /// - /// Note that the unlike [`QueryState::get_many_mut`], the entities passed in do not need to be unique. + /// Note that the unlike [`QueryState::many_mut`], the entities passed in do not need to be unique. /// /// # Examples /// @@ -943,21 +956,21 @@ impl QueryState { /// /// let mut query_state = world.query::<&A>(); /// - /// let component_values = query_state.get_many(&world, entities).unwrap(); + /// let component_values = query_state.many(&world, entities).unwrap(); /// /// assert_eq!(component_values, [&A(0), &A(1), &A(2)]); /// /// let wrong_entity = Entity::from_raw(365); /// - /// assert_eq!(match query_state.get_many(&mut world, [wrong_entity]).unwrap_err() {QueryEntityError::EntityDoesNotExist(error) => error.entity, _ => panic!()}, wrong_entity); + /// assert_eq!(match query_state.many(&mut world, [wrong_entity]).unwrap_err() {QueryEntityError::EntityDoesNotExist(error) => error.entity, _ => panic!()}, wrong_entity); /// ``` #[inline] - pub fn get_many<'w, const N: usize>( + pub fn many<'w, const N: usize>( &mut self, world: &'w World, entities: [Entity; N], ) -> Result<[ROQueryItem<'w, D>; N], QueryEntityError<'w>> { - self.query(world).get_many_inner(entities) + self.query(world).many_inner(entities) } /// Gets the query result for the given [`World`] and [`Entity`]. @@ -972,6 +985,19 @@ impl QueryState { self.query_mut(world).get_inner(entity) } + /// Returns the query results for the given array of [`Entity`]. + /// + /// Deprecated alias for [`Self::many_mut`]. + #[inline] + #[deprecated(note = "Use `many_mut` instead, which now returns a Result.")] + pub fn get_many_mut<'w, const N: usize>( + &mut self, + world: &'w mut World, + entities: [Entity; N], + ) -> Result<[D::Item<'w>; N], QueryEntityError<'w>> { + self.query_mut(world).many_inner(entities) + } + /// Returns the query results for the given array of [`Entity`]. /// /// In case of a nonexisting entity or mismatched component, a [`QueryEntityError`] is @@ -993,30 +1019,30 @@ impl QueryState { /// /// let mut query_state = world.query::<&mut A>(); /// - /// let mut mutable_component_values = query_state.get_many_mut(&mut world, entities).unwrap(); + /// let mut mutable_component_values = query_state.many_mut(&mut world, entities).unwrap(); /// /// for mut a in &mut mutable_component_values { /// a.0 += 5; /// } /// - /// let component_values = query_state.get_many(&world, entities).unwrap(); + /// let component_values = query_state.many(&world, entities).unwrap(); /// /// assert_eq!(component_values, [&A(5), &A(6), &A(7)]); /// /// let wrong_entity = Entity::from_raw(57); /// let invalid_entity = world.spawn_empty().id(); /// - /// assert_eq!(match query_state.get_many(&mut world, [wrong_entity]).unwrap_err() {QueryEntityError::EntityDoesNotExist(error) => error.entity, _ => panic!()}, wrong_entity); - /// assert_eq!(match query_state.get_many_mut(&mut world, [invalid_entity]).unwrap_err() {QueryEntityError::QueryDoesNotMatch(entity, _) => entity, _ => panic!()}, invalid_entity); - /// assert_eq!(query_state.get_many_mut(&mut world, [entities[0], entities[0]]).unwrap_err(), QueryEntityError::AliasedMutability(entities[0])); + /// assert_eq!(match query_state.many(&mut world, [wrong_entity]).unwrap_err() {QueryEntityError::EntityDoesNotExist(error) => error.entity, _ => panic!()}, wrong_entity); + /// assert_eq!(match query_state.many_mut(&mut world, [invalid_entity]).unwrap_err() {QueryEntityError::QueryDoesNotMatch(entity, _) => entity, _ => panic!()}, invalid_entity); + /// assert_eq!(query_state.many_mut(&mut world, [entities[0], entities[0]]).unwrap_err(), QueryEntityError::AliasedMutability(entities[0])); /// ``` #[inline] - pub fn get_many_mut<'w, const N: usize>( + pub fn many_mut<'w, const N: usize>( &mut self, world: &'w mut World, entities: [Entity; N], ) -> Result<[D::Item<'w>; N], QueryEntityError<'w>> { - self.query_mut(world).get_many_inner(entities) + self.query_mut(world).many_inner(entities) } /// Gets the query result for the given [`World`] and [`Entity`]. @@ -1328,16 +1354,16 @@ impl QueryState { /// a.0 += 5; /// }); /// - /// # let component_values = query_state.get_many(&world, entities).unwrap(); + /// # let component_values = query_state.many(&world, entities).unwrap(); /// /// # assert_eq!(component_values, [&A(5), &A(6), &A(7)]); /// /// # let wrong_entity = Entity::from_raw(57); /// # let invalid_entity = world.spawn_empty().id(); /// - /// # assert_eq!(match query_state.get_many(&mut world, [wrong_entity]).unwrap_err() {QueryEntityError::EntityDoesNotExist(error) => error.entity, _ => panic!()}, wrong_entity); - /// assert_eq!(match query_state.get_many_mut(&mut world, [invalid_entity]).unwrap_err() {QueryEntityError::QueryDoesNotMatch(entity, _) => entity, _ => panic!()}, invalid_entity); - /// # assert_eq!(query_state.get_many_mut(&mut world, [entities[0], entities[0]]).unwrap_err(), QueryEntityError::AliasedMutability(entities[0])); + /// # assert_eq!(match query_state.many(&mut world, [wrong_entity]).unwrap_err() {QueryEntityError::EntityDoesNotExist(error) => error.entity, _ => panic!()}, wrong_entity); + /// assert_eq!(match query_state.many_mut(&mut world, [invalid_entity]).unwrap_err() {QueryEntityError::QueryDoesNotMatch(entity, _) => entity, _ => panic!()}, invalid_entity); + /// # assert_eq!(query_state.many_mut(&mut world, [entities[0], entities[0]]).unwrap_err(), QueryEntityError::AliasedMutability(entities[0])); /// ``` /// /// # Panics @@ -1776,22 +1802,22 @@ mod tests { #[test] #[should_panic] - fn right_world_get_many() { + fn right_world_many() { let mut world_1 = World::new(); let world_2 = World::new(); let mut query_state = world_1.query::(); - let _panics = query_state.get_many(&world_2, []); + let _panics = query_state.many(&world_2, []); } #[test] #[should_panic] - fn right_world_get_many_mut() { + fn right_world_many_mut() { let mut world_1 = World::new(); let mut world_2 = World::new(); let mut query_state = world_1.query::(); - let _panics = query_state.get_many_mut(&mut world_2, []); + let _panics = query_state.many_mut(&mut world_2, []); } #[derive(Component, PartialEq, Debug)] diff --git a/crates/bevy_ecs/src/system/mod.rs b/crates/bevy_ecs/src/system/mod.rs index a8a3404537671..9c0fa5b0905e1 100644 --- a/crates/bevy_ecs/src/system/mod.rs +++ b/crates/bevy_ecs/src/system/mod.rs @@ -396,7 +396,7 @@ mod tests { } #[test] - fn get_many_is_ordered() { + fn many_is_ordered() { use crate::resource::Resource; const ENTITIES_COUNT: usize = 1000; @@ -411,7 +411,7 @@ mod tests { let entities_array: [Entity; ENTITIES_COUNT] = entities_array.0.clone().try_into().unwrap(); - for (i, w) in (0..ENTITIES_COUNT).zip(q.get_many(entities_array).unwrap()) { + for (i, w) in (0..ENTITIES_COUNT).zip(q.many(entities_array).unwrap()) { assert_eq!(i, w.0); } @@ -426,7 +426,7 @@ mod tests { let entities_array: [Entity; ENTITIES_COUNT] = entities_array.0.clone().try_into().unwrap(); - for (i, w) in (0..ENTITIES_COUNT).zip(q.get_many_mut(entities_array).unwrap()) { + for (i, w) in (0..ENTITIES_COUNT).zip(q.many_mut(entities_array).unwrap()) { assert_eq!(i, w.0); } diff --git a/crates/bevy_ecs/src/system/query.rs b/crates/bevy_ecs/src/system/query.rs index fff2a91b2f429..ccebbc184d79e 100644 --- a/crates/bevy_ecs/src/system/query.rs +++ b/crates/bevy_ecs/src/system/query.rs @@ -183,6 +183,7 @@ use core::{ /// # #[derive(Component)] /// # struct Health; /// # #[derive(Component)] + /// # struct Player; /// # #[derive(Component)] /// # struct Enemy; @@ -269,7 +270,7 @@ use core::{ /// |[`iter_many`]\[[`_mut`][`iter_many_mut`]]|Iterates or runs a specified function over query items generated by a list of entities.| /// |[`iter_combinations`]\[[`_mut`][`iter_combinations_mut`]]|Returns an iterator over all combinations of a specified number of query items.| /// |[`get`]\[[`_mut`][`get_mut`]]|Returns the query item for the specified entity.| -/// |[`many`]\[[`_mut`][`many_mut`]],
[`get_many`]\[[`_mut`][`get_many_mut`]]|Returns the query items for the specified entities.| +/// |[`many`]\[[`_mut`][`many_mut`]]|Returns the query items for the specified entities.| /// |[`single`]\[[`_mut`][`single_mut`]],
[`single`]\[[`_mut`][`single_mut`]]|Returns the query item while verifying that there aren't others.| /// /// There are two methods for each type of query operation: immutable and mutable (ending with `_mut`). @@ -305,8 +306,8 @@ use core::{ /// |[`iter_many`]\[[`_mut`][`iter_many_mut`]]|O(k)| /// |[`iter_combinations`]\[[`_mut`][`iter_combinations_mut`]]|O(nCr)| /// |[`get`]\[[`_mut`][`get_mut`]]|O(1)| -/// |([`get_`][`get_many`])[`many`]|O(k)| -/// |([`get_`][`get_many_mut`])[`many_mut`]|O(k2)| +/// |[`many`]|O(k)| +/// |[`many_mut`]|O(k2)| /// |[`single`]\[[`_mut`][`single_mut`]],
[`single`]\[[`_mut`][`single_mut`]]|O(a)| /// |Archetype based filtering ([`With`], [`Without`], [`Or`])|O(a)| /// |Change detection filtering ([`Added`], [`Changed`])|O(a + n)| @@ -348,8 +349,6 @@ use core::{ /// [`EntityRef`]: crate::world::EntityRef /// [`for_each`]: #iterator-for-each /// [`get`]: Self::get -/// [`get_many`]: Self::get_many -/// [`get_many_mut`]: Self::get_many_mut /// [`get_mut`]: Self::get_mut /// [`single`]: Self::single /// [`single_mut`]: Self::single_mut @@ -1278,11 +1277,25 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { self.as_readonly().get_inner(entity) } + /// Returns the read-only query items for the given array of [`Entity`]. + /// + /// Deprecated alias for [`many`](Self::many). + #[inline] + #[deprecated(note = "Use `many` instead, which now returns a Result.")] + pub fn get_many( + &self, + entities: [Entity; N], + ) -> Result<[ROQueryItem<'_, D>; N], QueryEntityError> { + // Note that this calls `many_readonly` instead of `many_inner` + // since we don't need to check for duplicates. + self.as_readonly().many_readonly(entities) + } + /// Returns the read-only query items for the given array of [`Entity`]. /// /// The returned query items are in the same order as the input. /// In case of a nonexisting entity or mismatched component, a [`QueryEntityError`] is returned instead. - /// The elements of the array do not need to be unique, unlike `get_many_mut`. + /// The elements of the array do not need to be unique, unlike `many_mut`. /// /// # Examples /// @@ -1302,14 +1315,14 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { /// let mut query_state = world.query::<&A>(); /// let query = query_state.query(&world); /// - /// let component_values = query.get_many(entities).unwrap(); + /// let component_values = query.many(entities).unwrap(); /// /// assert_eq!(component_values, [&A(0), &A(1), &A(2)]); /// /// let wrong_entity = Entity::from_raw(365); /// /// assert_eq!( - /// match query.get_many([wrong_entity]).unwrap_err() { + /// match query.many([wrong_entity]).unwrap_err() { /// QueryEntityError::EntityDoesNotExist(error) => error.entity, /// _ => panic!(), /// }, @@ -1319,66 +1332,15 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { /// /// # See also /// - /// - [`get_many_mut`](Self::get_many_mut) to get mutable query items. - /// - [`many`](Self::many) for the panicking version. + /// - [`many_mut`](Self::many_mut) to get mutable query items. #[inline] - pub fn get_many( + pub fn many( &self, entities: [Entity; N], ) -> Result<[ROQueryItem<'_, D>; N], QueryEntityError> { - // Note that this calls `get_many_readonly` instead of `get_many_inner` + // Note that this calls `many_readonly` instead of `many_inner` // since we don't need to check for duplicates. - self.as_readonly().get_many_readonly(entities) - } - - /// Returns the read-only query items for the given array of [`Entity`]. - /// - /// # Panics - /// - /// This method panics if there is a query mismatch or a non-existing entity. - /// - /// # Examples - /// ``` no_run - /// use bevy_ecs::prelude::*; - /// - /// #[derive(Component)] - /// struct Targets([Entity; 3]); - /// - /// #[derive(Component)] - /// struct Position{ - /// x: i8, - /// y: i8 - /// }; - /// - /// impl Position { - /// fn distance(&self, other: &Position) -> i8 { - /// // Manhattan distance is way easier to compute! - /// (self.x - other.x).abs() + (self.y - other.y).abs() - /// } - /// } - /// - /// fn check_all_targets_in_range(targeting_query: Query<(Entity, &Targets, &Position)>, targets_query: Query<&Position>){ - /// for (targeting_entity, targets, origin) in &targeting_query { - /// // We can use "destructuring" to unpack the results nicely - /// let [target_1, target_2, target_3] = targets_query.many(targets.0); - /// - /// assert!(target_1.distance(origin) <= 5); - /// assert!(target_2.distance(origin) <= 5); - /// assert!(target_3.distance(origin) <= 5); - /// } - /// } - /// ``` - /// - /// # See also - /// - /// - [`get_many`](Self::get_many) for the non-panicking version. - #[inline] - #[track_caller] - pub fn many(&self, entities: [Entity; N]) -> [ROQueryItem<'_, D>; N] { - match self.get_many(entities) { - Ok(items) => items, - Err(error) => panic!("Cannot get query results: {error}"), - } + self.as_readonly().many_readonly(entities) } /// Returns the query item for the given [`Entity`]. @@ -1477,6 +1439,18 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { } } + /// Returns the query items for the given array of [`Entity`]. + /// + /// Deprecated alias for [`many_mut`](Self::many_mut). + #[inline] + #[deprecated(note = "Use `many_mut` instead, which now returns a Result.")] + pub fn get_many_mut( + &mut self, + entities: [Entity; N], + ) -> Result<[D::Item<'_>; N], QueryEntityError> { + self.reborrow().many_inner(entities) + } + /// Returns the query items for the given array of [`Entity`]. /// /// The returned query items are in the same order as the input. @@ -1504,19 +1478,19 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { /// let mut query_state = world.query::<&mut A>(); /// let mut query = query_state.query_mut(&mut world); /// - /// let mut mutable_component_values = query.get_many_mut(entities).unwrap(); + /// let mut mutable_component_values = query.many_mut(entities).unwrap(); /// /// for mut a in &mut mutable_component_values { /// a.0 += 5; /// } /// - /// let component_values = query.get_many(entities).unwrap(); + /// let component_values = query.many(entities).unwrap(); /// /// assert_eq!(component_values, [&A(5), &A(6), &A(7)]); /// /// assert_eq!( /// match query - /// .get_many_mut([wrong_entity]) + /// .many_mut([wrong_entity]) /// .unwrap_err() /// { /// QueryEntityError::EntityDoesNotExist(error) => error.entity, @@ -1526,7 +1500,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { /// ); /// assert_eq!( /// match query - /// .get_many_mut([invalid_entity]) + /// .many_mut([invalid_entity]) /// .unwrap_err() /// { /// QueryEntityError::QueryDoesNotMatch(entity, _) => entity, @@ -1536,21 +1510,43 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { /// ); /// assert_eq!( /// query - /// .get_many_mut([entities[0], entities[0]]) + /// .many_mut([entities[0], entities[0]]) /// .unwrap_err(), /// QueryEntityError::AliasedMutability(entities[0]) /// ); /// ``` /// # See also /// - /// - [`get_many`](Self::get_many) to get read-only query items without checking for duplicate entities. - /// - [`many_mut`](Self::many_mut) for the panicking version. + /// - [`many`](Self::many) to get read-only query items without checking for duplicate entities. #[inline] - pub fn get_many_mut( + pub fn many_mut( &mut self, entities: [Entity; N], ) -> Result<[D::Item<'_>; N], QueryEntityError> { - self.reborrow().get_many_inner(entities) + self.reborrow().many_inner(entities) + } + + /// Returns the query items for the given array of [`Entity`]. + /// This consumes the [`Query`] to return results with the actual "inner" world lifetime. + /// + /// Deprecated alias for [`many_inner`](Self::many_inner). + #[inline] + #[deprecated(note = "Use `many_inner` instead, which now returns a Result.")] + pub fn get_many_inner( + self, + entities: [Entity; N], + ) -> Result<[D::Item<'w>; N], QueryEntityError<'w>> { + // Verify that all entities are unique + for i in 0..N { + for j in 0..i { + if entities[i] == entities[j] { + return Err(QueryEntityError::AliasedMutability(entities[i])); + } + } + } + + // SAFETY: All entities are unique, so the results don't alias. + unsafe { self.many_impl(entities) } } /// Returns the query items for the given array of [`Entity`]. @@ -1561,12 +1557,12 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { /// /// # See also /// - /// - [`get_many`](Self::get_many) to get read-only query items without checking for duplicate entities. - /// - [`get_many_mut`](Self::get_many_mut) to get items using a mutable reference. - /// - [`get_many_readonly`](Self::get_many_readonly) to get read-only query items without checking for duplicate entities + /// - [`many`](Self::many) to get read-only query items without checking for duplicate entities. + /// - [`many_mut`](Self::many_mut) to get items using a mutable reference. + /// - [`many_readonly`](Self::many_readonly) to get read-only query items without checking for duplicate entities /// with the actual "inner" world lifetime. #[inline] - pub fn get_many_inner( + pub fn many_inner( self, entities: [Entity; N], ) -> Result<[D::Item<'w>; N], QueryEntityError<'w>> { @@ -1580,7 +1576,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { } // SAFETY: All entities are unique, so the results don't alias. - unsafe { self.get_many_impl(entities) } + unsafe { self.many_impl(entities) } } /// Returns the query items for the given array of [`Entity`]. @@ -1591,10 +1587,27 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { /// /// # See also /// - /// - [`get_many`](Self::get_many) to get read-only query items without checking for duplicate entities. - /// - [`get_many_mut`](Self::get_many_mut) to get items using a mutable reference. - /// - [`get_many_inner`](Self::get_many_readonly) to get mutable query items with the actual "inner" world lifetime. + /// - [`many`](Self::many) to get read-only query items without checking for duplicate entities. + /// - [`many_mut`](Self::many_mut) to get items using a mutable reference. + /// - [`many_inner`](Self::many_readonly) to get mutable query items with the actual "inner" world lifetime. + #[inline] + pub fn many_readonly( + self, + entities: [Entity; N], + ) -> Result<[D::Item<'w>; N], QueryEntityError<'w>> + where + D: ReadOnlyQueryData, + { + // SAFETY: The query results are read-only, so they don't conflict if there are duplicate entities. + unsafe { self.many_impl(entities) } + } + + /// Returns the query items for the given array of [`Entity`]. + /// This consumes the [`Query`] to return results with the actual "inner" world lifetime. + /// + /// Deprecated alias for [`many_readonly`](Self::many_readonly). #[inline] + #[deprecated(note = "Use `many_readonly` instead, which now returns a Result.")] pub fn get_many_readonly( self, entities: [Entity; N], @@ -1603,7 +1616,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { D: ReadOnlyQueryData, { // SAFETY: The query results are read-only, so they don't conflict if there are duplicate entities. - unsafe { self.get_many_impl(entities) } + unsafe { self.many_impl(entities) } } /// Returns the query items for the given array of [`Entity`]. @@ -1613,7 +1626,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { /// /// The caller must ensure that the query data returned for the entities does not conflict, /// either because they are all unique or because the data is read-only. - unsafe fn get_many_impl( + unsafe fn many_impl( self, entities: [Entity; N], ) -> Result<[D::Item<'w>; N], QueryEntityError<'w>> { @@ -1629,63 +1642,6 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { Ok(values.map(|x| unsafe { x.assume_init() })) } - /// Returns the query items for the given array of [`Entity`]. - /// - /// # Panics - /// - /// This method panics if there is a query mismatch, a non-existing entity, or the same `Entity` is included more than once in the array. - /// - /// # Examples - /// - /// ``` no_run - /// use bevy_ecs::prelude::*; - /// - /// #[derive(Component)] - /// struct Spring{ - /// connected_entities: [Entity; 2], - /// strength: f32, - /// } - /// - /// #[derive(Component)] - /// struct Position { - /// x: f32, - /// y: f32, - /// } - /// - /// #[derive(Component)] - /// struct Force { - /// x: f32, - /// y: f32, - /// } - /// - /// fn spring_forces(spring_query: Query<&Spring>, mut mass_query: Query<(&Position, &mut Force)>){ - /// for spring in &spring_query { - /// // We can use "destructuring" to unpack our query items nicely - /// let [(position_1, mut force_1), (position_2, mut force_2)] = mass_query.many_mut(spring.connected_entities); - /// - /// force_1.x += spring.strength * (position_1.x - position_2.x); - /// force_1.y += spring.strength * (position_1.y - position_2.y); - /// - /// // Silence borrow-checker: I have split your mutable borrow! - /// force_2.x += spring.strength * (position_2.x - position_1.x); - /// force_2.y += spring.strength * (position_2.y - position_1.y); - /// } - /// } - /// ``` - /// - /// # See also - /// - /// - [`get_many_mut`](Self::get_many_mut) for the non panicking version. - /// - [`many`](Self::many) to get read-only query items. - #[inline] - #[track_caller] - pub fn many_mut(&mut self, entities: [Entity; N]) -> [D::Item<'_>; N] { - match self.get_many_mut(entities) { - Ok(items) => items, - Err(error) => panic!("Cannot get query result: {error}"), - } - } - /// Returns the query item for the given [`Entity`]. /// /// In case of a nonexisting entity or mismatched component, a [`QueryEntityError`] is returned instead. @@ -2499,26 +2455,26 @@ mod tests { use alloc::vec::Vec; #[test] - fn get_many_uniqueness() { + fn many_uniqueness() { let mut world = World::new(); let entities: Vec = (0..10).map(|_| world.spawn_empty().id()).collect(); let mut query_state = world.query::(); - // It's best to test get_many_inner directly, as it is shared + // It's best to test many_inner directly, as it is shared // We don't care about aliased mutability for the read-only equivalent // SAFETY: Query does not access world data. assert!(query_state .query_mut(&mut world) - .get_many_inner::<10>(entities.clone().try_into().unwrap()) + .many_inner::<10>(entities.clone().try_into().unwrap()) .is_ok()); assert_eq!( query_state .query_mut(&mut world) - .get_many_inner([entities[0], entities[0]]) + .many_inner([entities[0], entities[0]]) .unwrap_err(), QueryEntityError::AliasedMutability(entities[0]) ); @@ -2526,7 +2482,7 @@ mod tests { assert_eq!( query_state .query_mut(&mut world) - .get_many_inner([entities[0], entities[1], entities[0]]) + .many_inner([entities[0], entities[1], entities[0]]) .unwrap_err(), QueryEntityError::AliasedMutability(entities[0]) ); @@ -2534,7 +2490,7 @@ mod tests { assert_eq!( query_state .query_mut(&mut world) - .get_many_inner([entities[9], entities[9]]) + .many_inner([entities[9], entities[9]]) .unwrap_err(), QueryEntityError::AliasedMutability(entities[9]) ); diff --git a/crates/bevy_ecs/src/world/entity_ref.rs b/crates/bevy_ecs/src/world/entity_ref.rs index ab4b9dd4de931..d0712d5b85fff 100644 --- a/crates/bevy_ecs/src/world/entity_ref.rs +++ b/crates/bevy_ecs/src/world/entity_ref.rs @@ -806,7 +806,7 @@ impl<'w> EntityMut<'w> { /// let mut entity_mut = world.entity_mut(entity); /// let mut ptrs = entity_mut.get_mut_by_id(&HashSet::from_iter([x_id, y_id])) /// # .unwrap(); - /// # let [Some(mut x_ptr), Some(mut y_ptr)] = ptrs.get_many_mut([&x_id, &y_id]) else { unreachable!() }; + /// # let [Some(mut x_ptr), Some(mut y_ptr)] = ptrs.many_mut([&x_id, &y_id]) else { unreachable!() }; /// # assert_eq!((unsafe { x_ptr.as_mut().deref_mut::() }, unsafe { y_ptr.as_mut().deref_mut::() }), (&mut X(42), &mut Y(10))); /// ``` #[inline] diff --git a/crates/bevy_scene/src/scene_spawner.rs b/crates/bevy_scene/src/scene_spawner.rs index aa725ccf6b06b..b677ecd398600 100644 --- a/crates/bevy_scene/src/scene_spawner.rs +++ b/crates/bevy_scene/src/scene_spawner.rs @@ -660,7 +660,7 @@ mod tests { // verify this new entity contains the same data as the original entity let [old_a, new_a] = world .query::<&A>() - .get_many(&world, [entity, new_entity]) + .many(&world, [entity, new_entity]) .unwrap(); assert_eq!(old_a, new_a); }