11use crate :: {
22 batching:: BatchingStrategy ,
33 component:: Tick ,
4- entity:: { Entity , EntityBorrow , EntityDoesNotExistError , EntitySet } ,
4+ entity:: {
5+ unique_array:: UniqueEntityArray , Entity , EntityBorrow , EntityDoesNotExistError , EntitySet ,
6+ } ,
57 query:: {
68 DebugCheckedUnwrap , NopWorldQuery , QueryCombinationIter , QueryData , QueryEntityError ,
79 QueryFilter , QueryIter , QueryManyIter , QueryManyUniqueIter , QueryParIter , QueryParManyIter ,
@@ -1323,15 +1325,65 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> {
13231325 /// # See also
13241326 ///
13251327 /// - [`get_many_mut`](Self::get_many_mut) to get mutable query items.
1328+ /// - [`get_many_unique`](Self::get_many_unique) to only handle unique inputs.
13261329 /// - [`many`](Self::many) for the panicking version.
13271330 #[ inline]
13281331 pub fn get_many < const N : usize > (
13291332 & self ,
13301333 entities : [ Entity ; N ] ,
13311334 ) -> Result < [ ROQueryItem < ' _ , D > ; N ] , QueryEntityError > {
1332- // Note that this calls `get_many_readonly` instead of `get_many_inner`
1333- // since we don't need to check for duplicates.
1334- self . as_readonly ( ) . get_many_readonly ( entities)
1335+ // Note that we call a separate `*_inner` method from `get_many_mut`
1336+ // because we don't need to check for duplicates.
1337+ self . as_readonly ( ) . get_many_inner ( entities)
1338+ }
1339+
1340+ /// Returns the read-only query items for the given [`UniqueEntityArray`].
1341+ ///
1342+ /// The returned query items are in the same order as the input.
1343+ /// In case of a nonexisting entity or mismatched component, a [`QueryEntityError`] is returned instead.
1344+ ///
1345+ /// # Examples
1346+ ///
1347+ /// ```
1348+ /// use bevy_ecs::{prelude::*, query::QueryEntityError, entity::{EntitySetIterator, unique_array::UniqueEntityArray, unique_vec::UniqueEntityVec}};
1349+ ///
1350+ /// #[derive(Component, PartialEq, Debug)]
1351+ /// struct A(usize);
1352+ ///
1353+ /// let mut world = World::new();
1354+ /// let entity_set: UniqueEntityVec = world.spawn_batch((0..3).map(A)).collect_set();
1355+ /// let entity_set: UniqueEntityArray<3> = entity_set.try_into().unwrap();
1356+ ///
1357+ /// world.spawn(A(73));
1358+ ///
1359+ /// let mut query_state = world.query::<&A>();
1360+ /// let query = query_state.query(&world);
1361+ ///
1362+ /// let component_values = query.get_many_unique(entity_set).unwrap();
1363+ ///
1364+ /// assert_eq!(component_values, [&A(0), &A(1), &A(2)]);
1365+ ///
1366+ /// let wrong_entity = Entity::from_raw(365);
1367+ ///
1368+ /// assert_eq!(
1369+ /// match query.get_many_unique(UniqueEntityArray::from([wrong_entity])).unwrap_err() {
1370+ /// QueryEntityError::EntityDoesNotExist(error) => error.entity,
1371+ /// _ => panic!(),
1372+ /// },
1373+ /// wrong_entity
1374+ /// );
1375+ /// ```
1376+ ///
1377+ /// # See also
1378+ ///
1379+ /// - [`get_many_unique_mut`](Self::get_many_mut) to get mutable query items.
1380+ /// - [`get_many`](Self::get_many) to handle inputs with duplicates.
1381+ #[ inline]
1382+ pub fn get_many_unique < const N : usize > (
1383+ & self ,
1384+ entities : UniqueEntityArray < N > ,
1385+ ) -> Result < [ ROQueryItem < ' _ , D > ; N ] , QueryEntityError > {
1386+ self . as_readonly ( ) . get_many_unique_inner ( entities)
13351387 }
13361388
13371389 /// Returns the read-only query items for the given array of [`Entity`].
@@ -1560,7 +1612,75 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> {
15601612 & mut self ,
15611613 entities : [ Entity ; N ] ,
15621614 ) -> Result < [ D :: Item < ' _ > ; N ] , QueryEntityError > {
1563- self . reborrow ( ) . get_many_inner ( entities)
1615+ self . reborrow ( ) . get_many_mut_inner ( entities)
1616+ }
1617+
1618+ /// Returns the query items for the given [`UniqueEntityArray`].
1619+ ///
1620+ /// The returned query items are in the same order as the input.
1621+ /// In case of a nonexisting entity or mismatched component, a [`QueryEntityError`] is returned instead.
1622+ ///
1623+ /// # Examples
1624+ ///
1625+ /// ```
1626+ /// use bevy_ecs::{prelude::*, query::QueryEntityError, entity::{EntitySetIterator, unique_array::UniqueEntityArray, unique_vec::UniqueEntityVec}};
1627+ ///
1628+ /// #[derive(Component, PartialEq, Debug)]
1629+ /// struct A(usize);
1630+ ///
1631+ /// let mut world = World::new();
1632+ ///
1633+ /// let entity_set: UniqueEntityVec<_> = world.spawn_batch((0..3).map(A)).collect_set();
1634+ /// let entity_set: UniqueEntityArray<3> = entity_set.try_into().unwrap();
1635+ ///
1636+ /// world.spawn(A(73));
1637+ /// let wrong_entity = Entity::from_raw(57);
1638+ /// let invalid_entity = world.spawn_empty().id();
1639+ ///
1640+ ///
1641+ /// let mut query_state = world.query::<&mut A>();
1642+ /// let mut query = query_state.query_mut(&mut world);
1643+ ///
1644+ /// let mut mutable_component_values = query.get_many_unique_mut(entity_set).unwrap();
1645+ ///
1646+ /// for mut a in &mut mutable_component_values {
1647+ /// a.0 += 5;
1648+ /// }
1649+ ///
1650+ /// let component_values = query.get_many_unique(entity_set).unwrap();
1651+ ///
1652+ /// assert_eq!(component_values, [&A(5), &A(6), &A(7)]);
1653+ ///
1654+ /// assert_eq!(
1655+ /// match query
1656+ /// .get_many_unique_mut(UniqueEntityArray::from([wrong_entity]))
1657+ /// .unwrap_err()
1658+ /// {
1659+ /// QueryEntityError::EntityDoesNotExist(error) => error.entity,
1660+ /// _ => panic!(),
1661+ /// },
1662+ /// wrong_entity
1663+ /// );
1664+ /// assert_eq!(
1665+ /// match query
1666+ /// .get_many_unique_mut(UniqueEntityArray::from([invalid_entity]))
1667+ /// .unwrap_err()
1668+ /// {
1669+ /// QueryEntityError::QueryDoesNotMatch(entity, _) => entity,
1670+ /// _ => panic!(),
1671+ /// },
1672+ /// invalid_entity
1673+ /// );
1674+ /// ```
1675+ /// # See also
1676+ ///
1677+ /// - [`get_many_unique`](Self::get_many) to get read-only query items.
1678+ #[ inline]
1679+ pub fn get_many_unique_mut < const N : usize > (
1680+ & mut self ,
1681+ entities : UniqueEntityArray < N > ,
1682+ ) -> Result < [ D :: Item < ' _ > ; N ] , QueryEntityError > {
1683+ self . reborrow ( ) . get_many_unique_inner ( entities)
15641684 }
15651685
15661686 /// Returns the query items for the given array of [`Entity`].
@@ -1573,10 +1693,9 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> {
15731693 ///
15741694 /// - [`get_many`](Self::get_many) to get read-only query items without checking for duplicate entities.
15751695 /// - [`get_many_mut`](Self::get_many_mut) to get items using a mutable reference.
1576- /// - [`get_many_readonly`](Self::get_many_readonly) to get read-only query items without checking for duplicate entities
1577- /// with the actual "inner" world lifetime.
1696+ /// - [`get_many_inner`](Self::get_many_mut_inner) to get read-only query items with the actual "inner" world lifetime.
15781697 #[ inline]
1579- pub fn get_many_inner < const N : usize > (
1698+ pub fn get_many_mut_inner < const N : usize > (
15801699 self ,
15811700 entities : [ Entity ; N ] ,
15821701 ) -> Result < [ D :: Item < ' w > ; N ] , QueryEntityError > {
@@ -1588,7 +1707,6 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> {
15881707 }
15891708 }
15901709 }
1591-
15921710 // SAFETY: All entities are unique, so the results don't alias.
15931711 unsafe { self . get_many_impl ( entities) }
15941712 }
@@ -1603,9 +1721,9 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> {
16031721 ///
16041722 /// - [`get_many`](Self::get_many) to get read-only query items without checking for duplicate entities.
16051723 /// - [`get_many_mut`](Self::get_many_mut) to get items using a mutable reference.
1606- /// - [`get_many_inner `](Self::get_many_readonly ) to get mutable query items with the actual "inner" world lifetime.
1724+ /// - [`get_many_mut_inner `](Self::get_many_mut_inner ) to get mutable query items with the actual "inner" world lifetime.
16071725 #[ inline]
1608- pub fn get_many_readonly < const N : usize > (
1726+ pub fn get_many_inner < const N : usize > (
16091727 self ,
16101728 entities : [ Entity ; N ] ,
16111729 ) -> Result < [ D :: Item < ' w > ; N ] , QueryEntityError >
@@ -1616,6 +1734,25 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> {
16161734 unsafe { self . get_many_impl ( entities) }
16171735 }
16181736
1737+ /// Returns the query items for the given [`UniqueEntityArray`].
1738+ /// This consumes the [`Query`] to return results with the actual "inner" world lifetime.
1739+ ///
1740+ /// The returned query items are in the same order as the input.
1741+ /// In case of a nonexisting entity, duplicate entities or mismatched component, a [`QueryEntityError`] is returned instead.
1742+ ///
1743+ /// # See also
1744+ ///
1745+ /// - [`get_many_unique`](Self::get_many_unique) to get read-only query items without checking for duplicate entities.
1746+ /// - [`get_many_unique_mut`](Self::get_many_unique_mut) to get items using a mutable reference.
1747+ #[ inline]
1748+ pub fn get_many_unique_inner < const N : usize > (
1749+ self ,
1750+ entities : UniqueEntityArray < N > ,
1751+ ) -> Result < [ D :: Item < ' w > ; N ] , QueryEntityError > {
1752+ // SAFETY: All entities are unique, so the results don't alias.
1753+ unsafe { self . get_many_impl ( entities. into_inner ( ) ) }
1754+ }
1755+
16191756 /// Returns the query items for the given array of [`Entity`].
16201757 /// This consumes the [`Query`] to return results with the actual "inner" world lifetime.
16211758 ///
@@ -2518,35 +2655,35 @@ mod tests {
25182655
25192656 let mut query_state = world. query :: < Entity > ( ) ;
25202657
2521- // It's best to test get_many_inner directly, as it is shared
2658+ // It's best to test get_many_mut_inner directly, as it is shared
25222659 // We don't care about aliased mutability for the read-only equivalent
25232660
25242661 // SAFETY: Query does not access world data.
25252662 assert ! ( query_state
25262663 . query_mut( & mut world)
2527- . get_many_inner :: <10 >( entities. clone( ) . try_into( ) . unwrap( ) )
2664+ . get_many_mut_inner :: <10 >( entities. clone( ) . try_into( ) . unwrap( ) )
25282665 . is_ok( ) ) ;
25292666
25302667 assert_eq ! (
25312668 query_state
25322669 . query_mut( & mut world)
2533- . get_many_inner ( [ entities[ 0 ] , entities[ 0 ] ] )
2670+ . get_many_mut_inner ( [ entities[ 0 ] , entities[ 0 ] ] )
25342671 . unwrap_err( ) ,
25352672 QueryEntityError :: AliasedMutability ( entities[ 0 ] )
25362673 ) ;
25372674
25382675 assert_eq ! (
25392676 query_state
25402677 . query_mut( & mut world)
2541- . get_many_inner ( [ entities[ 0 ] , entities[ 1 ] , entities[ 0 ] ] )
2678+ . get_many_mut_inner ( [ entities[ 0 ] , entities[ 1 ] , entities[ 0 ] ] )
25422679 . unwrap_err( ) ,
25432680 QueryEntityError :: AliasedMutability ( entities[ 0 ] )
25442681 ) ;
25452682
25462683 assert_eq ! (
25472684 query_state
25482685 . query_mut( & mut world)
2549- . get_many_inner ( [ entities[ 9 ] , entities[ 9 ] ] )
2686+ . get_many_mut_inner ( [ entities[ 9 ] , entities[ 9 ] ] )
25502687 . unwrap_err( ) ,
25512688 QueryEntityError :: AliasedMutability ( entities[ 9 ] )
25522689 ) ;
0 commit comments