Skip to content

Commit 0b8c3ed

Browse files
Frizicart
andcommitted
Add a method iter_combinations on query to iterate over combinations of query results (#1763)
Related to [discussion on discord](https://discord.com/channels/691052431525675048/742569353878437978/824731187724681289) With const generics, it is now possible to write generic iterator over multiple entities at once. This enables patterns of query iterations like ```rust for [e1, e2, e3] in query.iter_combinations() { // do something with relation of all three entities } ``` The compiler is able to infer the correct iterator for given size of array, so either of those work ```rust for [e1, e2] in query.iter_combinations() { ... } for [e1, e2, e3] in query.iter_combinations() { ... } ``` This feature can be very useful for systems like collision detection. When you ask for permutations of size K of N entities: - if K == N, you get one result of all entities - if K < N, you get all possible subsets of N with size K, without repetition - if K > N, the result set is empty (no permutation of size K exist) Co-authored-by: Carter Anderson <[email protected]>
1 parent cb98d31 commit 0b8c3ed

File tree

7 files changed

+793
-9
lines changed

7 files changed

+793
-9
lines changed

Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,10 @@ path = "examples/ecs/fixed_timestep.rs"
267267
name = "hierarchy"
268268
path = "examples/ecs/hierarchy.rs"
269269

270+
[[example]]
271+
name = "iter_combinations"
272+
path = "examples/ecs/iter_combinations.rs"
273+
270274
[[example]]
271275
name = "parallel_query"
272276
path = "examples/ecs/parallel_query.rs"

crates/bevy_ecs/src/query/fetch.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,18 @@ pub struct ReadFetch<T> {
279279
sparse_set: *const ComponentSparseSet,
280280
}
281281

282+
impl<T> Clone for ReadFetch<T> {
283+
fn clone(&self) -> Self {
284+
Self {
285+
storage_type: self.storage_type,
286+
table_components: self.table_components,
287+
entity_table_rows: self.entity_table_rows,
288+
entities: self.entities,
289+
sparse_set: self.sparse_set,
290+
}
291+
}
292+
}
293+
282294
/// SAFETY: access is read only
283295
unsafe impl<T> ReadOnlyFetch for ReadFetch<T> {}
284296

@@ -382,6 +394,21 @@ pub struct WriteFetch<T> {
382394
change_tick: u32,
383395
}
384396

397+
impl<T> Clone for WriteFetch<T> {
398+
fn clone(&self) -> Self {
399+
Self {
400+
storage_type: self.storage_type,
401+
table_components: self.table_components,
402+
table_ticks: self.table_ticks,
403+
entities: self.entities,
404+
entity_table_rows: self.entity_table_rows,
405+
sparse_set: self.sparse_set,
406+
last_change_tick: self.last_change_tick,
407+
change_tick: self.change_tick,
408+
}
409+
}
410+
}
411+
385412
/// The [`FetchState`] of `&mut T`.
386413
pub struct WriteState<T> {
387414
component_id: ComponentId,

0 commit comments

Comments
 (0)