1
1
use crate :: {
2
2
archetype:: { Archetype , ArchetypeEntity , Archetypes } ,
3
3
component:: Tick ,
4
- entity:: { Entities , Entity } ,
4
+ entity:: { Entities , Entity , EntityHashSet } ,
5
5
query:: { ArchetypeFilter , DebugCheckedUnwrap , QueryState , StorageId } ,
6
6
storage:: { Table , TableRow , Tables } ,
7
7
world:: unsafe_world_cell:: UnsafeWorldCell ,
@@ -13,6 +13,7 @@ use std::{
13
13
iter:: FusedIterator ,
14
14
mem:: MaybeUninit ,
15
15
ops:: Range ,
16
+ vec:: IntoIter ,
16
17
} ;
17
18
18
19
use super :: { QueryData , QueryFilter , ReadOnlyQueryData } ;
@@ -1123,6 +1124,83 @@ where
1123
1124
// of any previously returned unique references first, thus preventing aliasing.
1124
1125
unsafe { self . fetch_next_aliased_unchecked ( ) . map ( D :: shrink) }
1125
1126
}
1127
+
1128
+ /// Checks for uniqueness in the `Entity` iterator `I`, returning a new Iterator on success.
1129
+ /// Return `self` on failure.
1130
+ /// This new iterator allows for mutable iteration without `fetch_next`.
1131
+ /// # Example
1132
+ /// ```
1133
+ /// # use bevy_ecs::prelude::*;
1134
+ /// # use std::ops::{Deref, DerefMut};
1135
+ /// #
1136
+ /// # #[derive(Component, Clone, Copy)]
1137
+ /// # struct PartValue(usize);
1138
+ /// #
1139
+ /// # impl Deref for PartValue {
1140
+ /// # type Target = usize;
1141
+ /// #
1142
+ /// # fn deref(&self) -> &Self::Target {
1143
+ /// # &self.0
1144
+ /// # }
1145
+ /// # }
1146
+ /// #
1147
+ /// # impl DerefMut for PartValue {
1148
+ /// # fn deref_mut(&mut self) -> &mut Self::Target {
1149
+ /// # &mut self.0
1150
+ /// # }
1151
+ /// # }
1152
+ /// #
1153
+ /// # let mut world = World::new();
1154
+ /// #
1155
+ /// // Mutable `Iterator` trait iteration.
1156
+ /// fn system(mut query: Query<&mut PartValue>) {
1157
+ /// # let entity_list: Vec<Entity> = Vec::new();
1158
+ /// #
1159
+ /// let mut unique_iter = query.iter_many_mut(entity_list)
1160
+ /// .entities_all_unique()
1161
+ /// .expect("the entity_list only contains unique entities");
1162
+ ///
1163
+ /// for mut part_value in unique_iter {
1164
+ /// **part_value += 1;
1165
+ /// }
1166
+ /// }
1167
+ /// #
1168
+ /// # let mut schedule = Schedule::default();
1169
+ /// # schedule.add_systems((system));
1170
+ /// # schedule.run(&mut world);
1171
+ /// ```
1172
+ #[ inline( always) ]
1173
+ pub fn entities_all_unique (
1174
+ self ,
1175
+ ) -> Result <
1176
+ QueryManyUniqueIter < ' w , ' s , D , F , IntoIter < I :: Item > > ,
1177
+ QueryManyIter < ' w , ' s , D , F , IntoIter < I :: Item > > ,
1178
+ > {
1179
+ let mut used = EntityHashSet :: default ( ) ;
1180
+ let entities: Vec < _ > = self . entity_iter . collect ( ) ;
1181
+
1182
+ if entities. iter ( ) . all ( move |e| used. insert ( * e. borrow ( ) ) ) {
1183
+ return Ok ( QueryManyUniqueIter {
1184
+ entity_iter : entities. into_iter ( ) ,
1185
+ entities : self . entities ,
1186
+ tables : self . tables ,
1187
+ archetypes : self . archetypes ,
1188
+ fetch : self . fetch ,
1189
+ filter : self . filter ,
1190
+ query_state : self . query_state ,
1191
+ } ) ;
1192
+ }
1193
+
1194
+ Err ( QueryManyIter {
1195
+ entity_iter : entities. into_iter ( ) ,
1196
+ entities : self . entities ,
1197
+ tables : self . tables ,
1198
+ archetypes : self . archetypes ,
1199
+ fetch : self . fetch ,
1200
+ filter : self . filter ,
1201
+ query_state : self . query_state ,
1202
+ } )
1203
+ }
1126
1204
}
1127
1205
1128
1206
impl < ' w , ' s , D : ReadOnlyQueryData , F : QueryFilter , I : Iterator > Iterator
@@ -1161,6 +1239,118 @@ where
1161
1239
}
1162
1240
}
1163
1241
1242
+ /// An [`Iterator`] over the query items generated from an iterator of unique [`Entity`]s.
1243
+ ///
1244
+ /// Items are returned in the order of the provided iterator.
1245
+ /// Entities that don't match the query are skipped.
1246
+ ///
1247
+ /// In contrast with `QueryManyIter`, this allows for mutable iteration without a `fetch_next` method.
1248
+ ///
1249
+ /// This struct is created by the [`QueryManyIter::entities_all_unique`] method.
1250
+ pub struct QueryManyUniqueIter < ' w , ' s , D : QueryData , F : QueryFilter , I : Iterator >
1251
+ where
1252
+ I :: Item : Borrow < Entity > ,
1253
+ {
1254
+ entity_iter : I ,
1255
+ entities : & ' w Entities ,
1256
+ tables : & ' w Tables ,
1257
+ archetypes : & ' w Archetypes ,
1258
+ fetch : D :: Fetch < ' w > ,
1259
+ filter : F :: Fetch < ' w > ,
1260
+ query_state : & ' s QueryState < D , F > ,
1261
+ }
1262
+
1263
+ impl < ' w , ' s , D : QueryData , F : QueryFilter , I : Iterator > QueryManyUniqueIter < ' w , ' s , D , F , I >
1264
+ where
1265
+ I :: Item : Borrow < Entity > ,
1266
+ {
1267
+ // Entities are guaranteed to be unique, so no lifetime shrinking needed for mutable iteration.
1268
+ #[ inline( always) ]
1269
+ fn fetch_next ( & mut self ) -> Option < D :: Item < ' w > > {
1270
+ for entity in self . entity_iter . by_ref ( ) {
1271
+ let entity = * entity. borrow ( ) ;
1272
+ let Some ( location) = self . entities . get ( entity) else {
1273
+ continue ;
1274
+ } ;
1275
+
1276
+ if !self
1277
+ . query_state
1278
+ . matched_archetypes
1279
+ . contains ( location. archetype_id . index ( ) )
1280
+ {
1281
+ continue ;
1282
+ }
1283
+ let ( archetype, table) ;
1284
+ // SAFETY:
1285
+ // `tables` and `archetypes` belong to the same world that the [`QueryIter`]
1286
+ // was initialized for.
1287
+ unsafe {
1288
+ archetype = self
1289
+ . archetypes
1290
+ . get ( location. archetype_id )
1291
+ . debug_checked_unwrap ( ) ;
1292
+ table = self . tables . get ( location. table_id ) . debug_checked_unwrap ( ) ;
1293
+ }
1294
+ // SAFETY: `archetype` is from the world that `fetch/filter` were created for,
1295
+ // `fetch_state`/`filter_state` are the states that `fetch/filter` were initialized with
1296
+ unsafe {
1297
+ D :: set_archetype (
1298
+ & mut self . fetch ,
1299
+ & self . query_state . fetch_state ,
1300
+ archetype,
1301
+ table,
1302
+ ) ;
1303
+ }
1304
+ // SAFETY: `table` is from the world that `fetch/filter` were created for,
1305
+ // `fetch_state`/`filter_state` are the states that `fetch/filter` were initialized with
1306
+ unsafe {
1307
+ F :: set_archetype (
1308
+ & mut self . filter ,
1309
+ & self . query_state . filter_state ,
1310
+ archetype,
1311
+ table,
1312
+ ) ;
1313
+ }
1314
+
1315
+ // SAFETY: set_archetype was called prior.
1316
+ // `location.archetype_row` is an archetype index row in range of the current archetype, because if it was not, the match above would have `continue`d
1317
+ if unsafe { F :: filter_fetch ( & mut self . filter , entity, location. table_row ) } {
1318
+ // SAFETY:
1319
+ // - set_archetype was called prior, `location.archetype_row` is an archetype index in range of the current archetype
1320
+ // - fetch is only called once for each entity.
1321
+ return Some ( unsafe { D :: fetch ( & mut self . fetch , entity, location. table_row ) } ) ;
1322
+ }
1323
+ }
1324
+ None
1325
+ }
1326
+ }
1327
+
1328
+ impl < ' w , ' s , D : QueryData , F : QueryFilter , I : Iterator > Iterator
1329
+ for QueryManyUniqueIter < ' w , ' s , D , F , I >
1330
+ where
1331
+ I :: Item : Borrow < Entity > ,
1332
+ {
1333
+ type Item = D :: Item < ' w > ;
1334
+
1335
+ #[ inline( always) ]
1336
+ fn next ( & mut self ) -> Option < Self :: Item > {
1337
+ self . fetch_next ( )
1338
+ }
1339
+
1340
+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
1341
+ let ( _, max_size) = self . entity_iter . size_hint ( ) ;
1342
+ ( 0 , max_size)
1343
+ }
1344
+ }
1345
+
1346
+ // This is correct as [`QueryManyIter`] always returns `None` once exhausted.
1347
+ impl < ' w , ' s , D : QueryData , F : QueryFilter , I : Iterator > FusedIterator
1348
+ for QueryManyUniqueIter < ' w , ' s , D , F , I >
1349
+ where
1350
+ I :: Item : Borrow < Entity > ,
1351
+ {
1352
+ }
1353
+
1164
1354
/// An iterator over `K`-sized combinations of query items without repetition.
1165
1355
///
1166
1356
/// A combination is an arrangement of a collection of items where order does not matter.
0 commit comments