1mod access;
4mod builder;
5mod error;
6mod fetch;
7mod filter;
8mod iter;
9mod par_iter;
10mod state;
11mod world_query;
12
13pub use access::*;
14pub use bevy_ecs_macros::{QueryData, QueryFilter};
15pub use builder::*;
16pub use error::*;
17pub use fetch::*;
18pub use filter::*;
19pub use iter::*;
20pub use par_iter::*;
21pub use state::*;
22pub use world_query::*;
23
24pub(crate) trait DebugCheckedUnwrap {
29 type Item;
30 unsafe fn debug_checked_unwrap(self) -> Self::Item;
37}
38
39#[cfg(debug_assertions)]
42impl<T> DebugCheckedUnwrap for Option<T> {
43 type Item = T;
44
45 #[inline(always)]
46 #[track_caller]
47 unsafe fn debug_checked_unwrap(self) -> Self::Item {
48 if let Some(inner) = self {
49 inner
50 } else {
51 unreachable!()
52 }
53 }
54}
55
56#[cfg(not(debug_assertions))]
57impl<T> DebugCheckedUnwrap for Option<T> {
58 type Item = T;
59
60 #[inline(always)]
61 unsafe fn debug_checked_unwrap(self) -> Self::Item {
62 if let Some(inner) = self {
63 inner
64 } else {
65 std::hint::unreachable_unchecked()
66 }
67 }
68}
69
70#[cfg(test)]
71mod tests {
72 use bevy_ecs_macros::{QueryData, QueryFilter};
73
74 use crate::prelude::{AnyOf, Changed, Entity, Or, QueryState, With, Without};
75 use crate::query::{ArchetypeFilter, Has, QueryCombinationIter, ReadOnlyQueryData};
76 use crate::schedule::{IntoSystemConfigs, Schedule};
77 use crate::system::{IntoSystem, Query, System, SystemState};
78 use crate::{self as bevy_ecs, component::Component, world::World};
79 use std::any::type_name;
80 use std::collections::HashSet;
81
82 #[derive(Component, Debug, Hash, Eq, PartialEq, Clone, Copy)]
83 struct A(usize);
84 #[derive(Component, Debug, Eq, PartialEq, Clone, Copy)]
85 struct B(usize);
86 #[derive(Component, Debug, Eq, PartialEq, Clone, Copy)]
87 struct C(usize);
88 #[derive(Component, Debug, Eq, PartialEq, Clone, Copy)]
89 struct D(usize);
90
91 #[derive(Component, Debug, Eq, PartialEq, Clone, Copy)]
92 #[component(storage = "SparseSet")]
93 struct Sparse(usize);
94
95 #[test]
96 fn query() {
97 let mut world = World::new();
98 world.spawn((A(1), B(1)));
99 world.spawn(A(2));
100 let values = world.query::<&A>().iter(&world).collect::<Vec<&A>>();
101 assert_eq!(values, vec![&A(1), &A(2)]);
102
103 for (_a, mut b) in world.query::<(&A, &mut B)>().iter_mut(&mut world) {
104 b.0 = 3;
105 }
106 let values = world.query::<&B>().iter(&world).collect::<Vec<&B>>();
107 assert_eq!(values, vec![&B(3)]);
108 }
109
110 #[test]
111 fn query_filtered_exactsizeiterator_len() {
112 fn choose(n: usize, k: usize) -> usize {
113 if n == 0 || k == 0 || n < k {
114 return 0;
115 }
116 let ks = 1..=k;
117 let ns = (n - k + 1..=n).rev();
118 ks.zip(ns).fold(1, |acc, (k, n)| acc * n / k)
119 }
120 fn assert_combination<D, F, const K: usize>(world: &mut World, expected_size: usize)
121 where
122 D: ReadOnlyQueryData,
123 F: ArchetypeFilter,
124 {
125 let mut query = world.query_filtered::<D, F>();
126 let query_type = type_name::<QueryCombinationIter<D, F, K>>();
127 let iter = query.iter_combinations::<K>(world);
128 assert_all_sizes_iterator_equal(iter, expected_size, 0, query_type);
129 let iter = query.iter_combinations::<K>(world);
130 assert_all_sizes_iterator_equal(iter, expected_size, 1, query_type);
131 let iter = query.iter_combinations::<K>(world);
132 assert_all_sizes_iterator_equal(iter, expected_size, 5, query_type);
133 }
134 fn assert_all_sizes_equal<D, F>(world: &mut World, expected_size: usize)
135 where
136 D: ReadOnlyQueryData,
137 F: ArchetypeFilter,
138 {
139 let mut query = world.query_filtered::<D, F>();
140 let query_type = type_name::<QueryState<D, F>>();
141 assert_all_exact_sizes_iterator_equal(query.iter(world), expected_size, 0, query_type);
142 assert_all_exact_sizes_iterator_equal(query.iter(world), expected_size, 1, query_type);
143 assert_all_exact_sizes_iterator_equal(query.iter(world), expected_size, 5, query_type);
144
145 let expected = expected_size;
146 assert_combination::<D, F, 0>(world, choose(expected, 0));
147 assert_combination::<D, F, 1>(world, choose(expected, 1));
148 assert_combination::<D, F, 2>(world, choose(expected, 2));
149 assert_combination::<D, F, 5>(world, choose(expected, 5));
150 assert_combination::<D, F, 43>(world, choose(expected, 43));
151 assert_combination::<D, F, 64>(world, choose(expected, 64));
152 }
153 fn assert_all_exact_sizes_iterator_equal(
154 iterator: impl ExactSizeIterator,
155 expected_size: usize,
156 skip: usize,
157 query_type: &'static str,
158 ) {
159 let len = iterator.len();
160 println!("len: {len}");
161 assert_all_sizes_iterator_equal(iterator, expected_size, skip, query_type);
162 assert_eq!(len, expected_size);
163 }
164 fn assert_all_sizes_iterator_equal(
165 mut iterator: impl Iterator,
166 expected_size: usize,
167 skip: usize,
168 query_type: &'static str,
169 ) {
170 let expected_size = expected_size.saturating_sub(skip);
171 for _ in 0..skip {
172 iterator.next();
173 }
174 let size_hint_0 = iterator.size_hint().0;
175 let size_hint_1 = iterator.size_hint().1;
176 let count = iterator.count();
179 println!(
181 "query declared sizes: \n\
182 for query: {query_type} \n\
183 expected: {expected_size} \n\
184 size_hint().0: {size_hint_0} \n\
185 size_hint().1: {size_hint_1:?} \n\
186 count(): {count}"
187 );
188 assert_eq!(size_hint_0, expected_size);
189 assert_eq!(size_hint_1, Some(expected_size));
190 assert_eq!(count, expected_size);
191 }
192
193 let mut world = World::new();
194 world.spawn((A(1), B(1)));
195 world.spawn(A(2));
196 world.spawn(A(3));
197
198 assert_all_sizes_equal::<&A, With<B>>(&mut world, 1);
199 assert_all_sizes_equal::<&A, Without<B>>(&mut world, 2);
200
201 let mut world = World::new();
202 world.spawn((A(1), B(1), C(1)));
203 world.spawn((A(2), B(2)));
204 world.spawn((A(3), B(3)));
205 world.spawn((A(4), C(4)));
206 world.spawn((A(5), C(5)));
207 world.spawn((A(6), C(6)));
208 world.spawn(A(7));
209 world.spawn(A(8));
210 world.spawn(A(9));
211 world.spawn(A(10));
212
213 assert_all_sizes_equal::<&A, With<B>>(&mut world, 3);
215 assert_all_sizes_equal::<&A, With<C>>(&mut world, 4);
216 assert_all_sizes_equal::<&A, Without<B>>(&mut world, 7);
217 assert_all_sizes_equal::<&A, Without<C>>(&mut world, 6);
218
219 assert_all_sizes_equal::<&A, (With<B>, With<C>)>(&mut world, 1);
221 assert_all_sizes_equal::<&A, (With<B>, Without<C>)>(&mut world, 2);
222 assert_all_sizes_equal::<&A, (Without<B>, With<C>)>(&mut world, 3);
223 assert_all_sizes_equal::<&A, (Without<B>, Without<C>)>(&mut world, 4);
224
225 assert_all_sizes_equal::<&A, Or<(With<B>, With<C>)>>(&mut world, 6);
227 assert_all_sizes_equal::<&A, Or<(With<B>, Without<C>)>>(&mut world, 7);
228 assert_all_sizes_equal::<&A, Or<(Without<B>, With<C>)>>(&mut world, 8);
229 assert_all_sizes_equal::<&A, Or<(Without<B>, Without<C>)>>(&mut world, 9);
230 assert_all_sizes_equal::<&A, (Or<(With<B>,)>, Or<(With<C>,)>)>(&mut world, 1);
231 assert_all_sizes_equal::<&A, Or<(Or<(With<B>, With<C>)>, With<D>)>>(&mut world, 6);
232
233 for i in 11..14 {
234 world.spawn((A(i), D(i)));
235 }
236
237 assert_all_sizes_equal::<&A, Or<(Or<(With<B>, With<C>)>, With<D>)>>(&mut world, 9);
238 assert_all_sizes_equal::<&A, Or<(Or<(With<B>, With<C>)>, Without<D>)>>(&mut world, 10);
239
240 for i in 14..20 {
242 world.spawn((C(i), D(i)));
243 }
244 assert_all_sizes_equal::<Entity, (With<C>, With<D>)>(&mut world, 6);
245 }
246
247 #[test]
248 fn query_iter_combinations() {
249 let mut world = World::new();
250
251 world.spawn((A(1), B(1)));
252 world.spawn(A(2));
253 world.spawn(A(3));
254 world.spawn(A(4));
255
256 let values: Vec<[&A; 2]> = world.query::<&A>().iter_combinations(&world).collect();
257 assert_eq!(
258 values,
259 vec![
260 [&A(1), &A(2)],
261 [&A(1), &A(3)],
262 [&A(1), &A(4)],
263 [&A(2), &A(3)],
264 [&A(2), &A(4)],
265 [&A(3), &A(4)],
266 ]
267 );
268 let mut a_query = world.query::<&A>();
269 let values: Vec<[&A; 3]> = a_query.iter_combinations(&world).collect();
270 assert_eq!(
271 values,
272 vec![
273 [&A(1), &A(2), &A(3)],
274 [&A(1), &A(2), &A(4)],
275 [&A(1), &A(3), &A(4)],
276 [&A(2), &A(3), &A(4)],
277 ]
278 );
279
280 let mut query = world.query::<&mut A>();
281 let mut combinations = query.iter_combinations_mut(&mut world);
282 while let Some([mut a, mut b, mut c]) = combinations.fetch_next() {
283 a.0 += 10;
284 b.0 += 100;
285 c.0 += 1000;
286 }
287
288 let values: Vec<[&A; 3]> = a_query.iter_combinations(&world).collect();
289 assert_eq!(
290 values,
291 vec![
292 [&A(31), &A(212), &A(1203)],
293 [&A(31), &A(212), &A(3004)],
294 [&A(31), &A(1203), &A(3004)],
295 [&A(212), &A(1203), &A(3004)]
296 ]
297 );
298
299 let mut b_query = world.query::<&B>();
300 assert_eq!(
301 b_query.iter_combinations::<2>(&world).size_hint(),
302 (0, Some(0))
303 );
304 let values: Vec<[&B; 2]> = b_query.iter_combinations(&world).collect();
305 assert_eq!(values, Vec::<[&B; 2]>::new());
306 }
307
308 #[test]
309 fn query_filtered_iter_combinations() {
310 use bevy_ecs::query::{Added, Changed, Or, With, Without};
311
312 let mut world = World::new();
313
314 world.spawn((A(1), B(1)));
315 world.spawn(A(2));
316 world.spawn(A(3));
317 world.spawn(A(4));
318
319 let mut a_wout_b = world.query_filtered::<&A, Without<B>>();
320 let values: HashSet<[&A; 2]> = a_wout_b.iter_combinations(&world).collect();
321 assert_eq!(
322 values,
323 [[&A(2), &A(3)], [&A(2), &A(4)], [&A(3), &A(4)]]
324 .into_iter()
325 .collect::<HashSet<_>>()
326 );
327
328 let values: HashSet<[&A; 3]> = a_wout_b.iter_combinations(&world).collect();
329 assert_eq!(
330 values,
331 [[&A(2), &A(3), &A(4)],].into_iter().collect::<HashSet<_>>()
332 );
333
334 let mut query = world.query_filtered::<&A, Or<(With<A>, With<B>)>>();
335 let values: HashSet<[&A; 2]> = query.iter_combinations(&world).collect();
336 assert_eq!(
337 values,
338 [
339 [&A(1), &A(2)],
340 [&A(1), &A(3)],
341 [&A(1), &A(4)],
342 [&A(2), &A(3)],
343 [&A(2), &A(4)],
344 [&A(3), &A(4)],
345 ]
346 .into_iter()
347 .collect::<HashSet<_>>()
348 );
349
350 let mut query = world.query_filtered::<&mut A, Without<B>>();
351 let mut combinations = query.iter_combinations_mut(&mut world);
352 while let Some([mut a, mut b, mut c]) = combinations.fetch_next() {
353 a.0 += 10;
354 b.0 += 100;
355 c.0 += 1000;
356 }
357
358 let values: HashSet<[&A; 3]> = a_wout_b.iter_combinations(&world).collect();
359 assert_eq!(
360 values,
361 [[&A(12), &A(103), &A(1004)],]
362 .into_iter()
363 .collect::<HashSet<_>>()
364 );
365
366 let mut world = World::new();
368
369 world.spawn((A(1), B(1)));
370 world.spawn((A(2), B(2)));
371 world.spawn((A(3), B(3)));
372 world.spawn((A(4), B(4)));
373
374 let mut query_added = world.query_filtered::<&A, Added<A>>();
375
376 world.clear_trackers();
377 world.spawn(A(5));
378
379 assert_eq!(query_added.iter_combinations::<2>(&world).count(), 0);
380
381 world.clear_trackers();
382 world.spawn(A(6));
383 world.spawn(A(7));
384
385 assert_eq!(query_added.iter_combinations::<2>(&world).count(), 1);
386
387 world.clear_trackers();
388 world.spawn(A(8));
389 world.spawn(A(9));
390 world.spawn(A(10));
391
392 assert_eq!(query_added.iter_combinations::<2>(&world).count(), 3);
393
394 world.clear_trackers();
395
396 let mut query_changed = world.query_filtered::<&A, Changed<A>>();
397
398 let mut query = world.query_filtered::<&mut A, With<B>>();
399 let mut combinations = query.iter_combinations_mut(&mut world);
400 while let Some([mut a, mut b, mut c]) = combinations.fetch_next() {
401 a.0 += 10;
402 b.0 += 100;
403 c.0 += 1000;
404 }
405
406 let values: HashSet<[&A; 3]> = query_changed.iter_combinations(&world).collect();
407 assert_eq!(
408 values,
409 [
410 [&A(31), &A(212), &A(1203)],
411 [&A(31), &A(212), &A(3004)],
412 [&A(31), &A(1203), &A(3004)],
413 [&A(212), &A(1203), &A(3004)]
414 ]
415 .into_iter()
416 .collect::<HashSet<_>>()
417 );
418 }
419
420 #[test]
421 fn query_iter_combinations_sparse() {
422 let mut world = World::new();
423
424 world.spawn_batch((1..=4).map(Sparse));
425
426 let mut query = world.query::<&mut Sparse>();
427 let mut combinations = query.iter_combinations_mut(&mut world);
428 while let Some([mut a, mut b, mut c]) = combinations.fetch_next() {
429 a.0 += 10;
430 b.0 += 100;
431 c.0 += 1000;
432 }
433
434 let mut query = world.query::<&Sparse>();
435 let values: Vec<[&Sparse; 3]> = query.iter_combinations(&world).collect();
436 assert_eq!(
437 values,
438 vec![
439 [&Sparse(31), &Sparse(212), &Sparse(1203)],
440 [&Sparse(31), &Sparse(212), &Sparse(3004)],
441 [&Sparse(31), &Sparse(1203), &Sparse(3004)],
442 [&Sparse(212), &Sparse(1203), &Sparse(3004)]
443 ]
444 );
445 }
446
447 #[test]
448 fn multi_storage_query() {
449 let mut world = World::new();
450
451 world.spawn((Sparse(1), B(2)));
452 world.spawn(Sparse(2));
453
454 let values = world
455 .query::<&Sparse>()
456 .iter(&world)
457 .collect::<Vec<&Sparse>>();
458 assert_eq!(values, vec![&Sparse(1), &Sparse(2)]);
459
460 for (_a, mut b) in world.query::<(&Sparse, &mut B)>().iter_mut(&mut world) {
461 b.0 = 3;
462 }
463
464 let values = world.query::<&B>().iter(&world).collect::<Vec<&B>>();
465 assert_eq!(values, vec![&B(3)]);
466 }
467
468 #[test]
469 fn any_query() {
470 let mut world = World::new();
471
472 world.spawn((A(1), B(2)));
473 world.spawn(A(2));
474 world.spawn(C(3));
475
476 let values: Vec<(Option<&A>, Option<&B>)> =
477 world.query::<AnyOf<(&A, &B)>>().iter(&world).collect();
478
479 assert_eq!(
480 values,
481 vec![(Some(&A(1)), Some(&B(2))), (Some(&A(2)), None),]
482 );
483 }
484
485 #[test]
486 fn has_query() {
487 let mut world = World::new();
488
489 world.spawn((A(1), B(1)));
490 world.spawn(A(2));
491 world.spawn((A(3), B(1)));
492 world.spawn(A(4));
493
494 let values: Vec<(&A, bool)> = world.query::<(&A, Has<B>)>().iter(&world).collect();
495
496 assert_eq!(
498 values,
499 vec![(&A(1), true), (&A(3), true), (&A(2), false), (&A(4), false),]
500 );
501 }
502
503 #[test]
504 #[should_panic = "&mut bevy_ecs::query::tests::A conflicts with a previous access in this query."]
505 fn self_conflicting_worldquery() {
506 #[derive(QueryData)]
507 #[query_data(mutable)]
508 struct SelfConflicting {
509 a: &'static mut A,
510 b: &'static mut A,
511 }
512
513 let mut world = World::new();
514 world.query::<SelfConflicting>();
515 }
516
517 #[test]
518 fn derived_worldqueries() {
519 let mut world = World::new();
520
521 world.spawn((A(10), B(18), C(3), Sparse(4)));
522
523 world.spawn((A(101), B(148), C(13)));
524 world.spawn((A(51), B(46), Sparse(72)));
525 world.spawn((A(398), C(6), Sparse(9)));
526 world.spawn((B(11), C(28), Sparse(92)));
527
528 world.spawn((C(18348), Sparse(101)));
529 world.spawn((B(839), Sparse(5)));
530 world.spawn((B(6721), C(122)));
531 world.spawn((A(220), Sparse(63)));
532 world.spawn((A(1092), C(382)));
533 world.spawn((A(2058), B(3019)));
534
535 world.spawn((B(38), C(8), Sparse(100)));
536 world.spawn((A(111), C(52), Sparse(1)));
537 world.spawn((A(599), B(39), Sparse(13)));
538 world.spawn((A(55), B(66), C(77)));
539
540 world.spawn_empty();
541
542 {
543 #[derive(QueryData)]
544 struct CustomAB {
545 a: &'static A,
546 b: &'static B,
547 }
548
549 let custom_param_data = world
550 .query::<CustomAB>()
551 .iter(&world)
552 .map(|item| (*item.a, *item.b))
553 .collect::<Vec<_>>();
554 let normal_data = world
555 .query::<(&A, &B)>()
556 .iter(&world)
557 .map(|(a, b)| (*a, *b))
558 .collect::<Vec<_>>();
559 assert_eq!(custom_param_data, normal_data);
560 }
561
562 {
563 #[derive(QueryData)]
564 struct FancyParam {
565 e: Entity,
566 b: &'static B,
567 opt: Option<&'static Sparse>,
568 }
569
570 let custom_param_data = world
571 .query::<FancyParam>()
572 .iter(&world)
573 .map(|fancy| (fancy.e, *fancy.b, fancy.opt.copied()))
574 .collect::<Vec<_>>();
575 let normal_data = world
576 .query::<(Entity, &B, Option<&Sparse>)>()
577 .iter(&world)
578 .map(|(e, b, opt)| (e, *b, opt.copied()))
579 .collect::<Vec<_>>();
580 assert_eq!(custom_param_data, normal_data);
581 }
582
583 {
584 #[derive(QueryData)]
585 struct MaybeBSparse {
586 blah: Option<(&'static B, &'static Sparse)>,
587 }
588 #[derive(QueryData)]
589 struct MatchEverything {
590 abcs: AnyOf<(&'static A, &'static B, &'static C)>,
591 opt_bsparse: MaybeBSparse,
592 }
593
594 let custom_param_data = world
595 .query::<MatchEverything>()
596 .iter(&world)
597 .map(
598 |MatchEverythingItem {
599 abcs: (a, b, c),
600 opt_bsparse: MaybeBSparseItem { blah: bsparse },
601 }| {
602 (
603 (a.copied(), b.copied(), c.copied()),
604 bsparse.map(|(b, sparse)| (*b, *sparse)),
605 )
606 },
607 )
608 .collect::<Vec<_>>();
609 let normal_data = world
610 .query::<(AnyOf<(&A, &B, &C)>, Option<(&B, &Sparse)>)>()
611 .iter(&world)
612 .map(|((a, b, c), bsparse)| {
613 (
614 (a.copied(), b.copied(), c.copied()),
615 bsparse.map(|(b, sparse)| (*b, *sparse)),
616 )
617 })
618 .collect::<Vec<_>>();
619 assert_eq!(custom_param_data, normal_data);
620 }
621
622 {
623 #[derive(QueryFilter)]
624 struct AOrBFilter {
625 a: Or<(With<A>, With<B>)>,
626 }
627 #[derive(QueryFilter)]
628 struct NoSparseThatsSlow {
629 no: Without<Sparse>,
630 }
631
632 let custom_param_entities = world
633 .query_filtered::<Entity, (AOrBFilter, NoSparseThatsSlow)>()
634 .iter(&world)
635 .collect::<Vec<_>>();
636 let normal_entities = world
637 .query_filtered::<Entity, (Or<(With<A>, With<B>)>, Without<Sparse>)>()
638 .iter(&world)
639 .collect::<Vec<_>>();
640 assert_eq!(custom_param_entities, normal_entities);
641 }
642
643 {
644 #[derive(QueryFilter)]
645 struct CSparseFilter {
646 tuple_structs_pls: With<C>,
647 ugh: With<Sparse>,
648 }
649
650 let custom_param_entities = world
651 .query_filtered::<Entity, CSparseFilter>()
652 .iter(&world)
653 .collect::<Vec<_>>();
654 let normal_entities = world
655 .query_filtered::<Entity, (With<C>, With<Sparse>)>()
656 .iter(&world)
657 .collect::<Vec<_>>();
658 assert_eq!(custom_param_entities, normal_entities);
659 }
660
661 {
662 #[derive(QueryFilter)]
663 struct WithoutComps {
664 _1: Without<A>,
665 _2: Without<B>,
666 _3: Without<C>,
667 }
668
669 let custom_param_entities = world
670 .query_filtered::<Entity, WithoutComps>()
671 .iter(&world)
672 .collect::<Vec<_>>();
673 let normal_entities = world
674 .query_filtered::<Entity, (Without<A>, Without<B>, Without<C>)>()
675 .iter(&world)
676 .collect::<Vec<_>>();
677 assert_eq!(custom_param_entities, normal_entities);
678 }
679
680 {
681 #[derive(QueryData)]
682 struct IterCombAB {
683 a: &'static A,
684 b: &'static B,
685 }
686
687 let custom_param_data = world
688 .query::<IterCombAB>()
689 .iter_combinations::<2>(&world)
690 .map(|[item0, item1]| [(*item0.a, *item0.b), (*item1.a, *item1.b)])
691 .collect::<Vec<_>>();
692 let normal_data = world
693 .query::<(&A, &B)>()
694 .iter_combinations(&world)
695 .map(|[(a0, b0), (a1, b1)]| [(*a0, *b0), (*a1, *b1)])
696 .collect::<Vec<_>>();
697 assert_eq!(custom_param_data, normal_data);
698 }
699 }
700
701 #[test]
702 fn many_entities() {
703 let mut world = World::new();
704 world.spawn((A(0), B(0)));
705 world.spawn((A(0), B(0)));
706 world.spawn(A(0));
707 world.spawn(B(0));
708 {
709 fn system(has_a: Query<Entity, With<A>>, has_a_and_b: Query<(&A, &B)>) {
710 assert_eq!(has_a_and_b.iter_many(&has_a).count(), 2);
711 }
712 let mut system = IntoSystem::into_system(system);
713 system.initialize(&mut world);
714 system.run((), &mut world);
715 }
716 {
717 fn system(has_a: Query<Entity, With<A>>, mut b_query: Query<&mut B>) {
718 let mut iter = b_query.iter_many_mut(&has_a);
719 while let Some(mut b) = iter.fetch_next() {
720 b.0 = 1;
721 }
722 }
723 let mut system = IntoSystem::into_system(system);
724 system.initialize(&mut world);
725 system.run((), &mut world);
726 }
727 {
728 fn system(query: Query<(Option<&A>, &B)>) {
729 for (maybe_a, b) in &query {
730 match maybe_a {
731 Some(_) => assert_eq!(b.0, 1),
732 None => assert_eq!(b.0, 0),
733 }
734 }
735 }
736 let mut system = IntoSystem::into_system(system);
737 system.initialize(&mut world);
738 system.run((), &mut world);
739 }
740 }
741
742 #[test]
743 fn mut_to_immut_query_methods_have_immut_item() {
744 #[derive(Component)]
745 struct Foo;
746
747 let mut world = World::new();
748 let e = world.spawn(Foo).id();
749
750 let mut q = world.query::<&mut Foo>();
752 let _: Option<&Foo> = q.iter(&world).next();
753 let _: Option<[&Foo; 2]> = q.iter_combinations::<2>(&world).next();
754 let _: Option<&Foo> = q.iter_manual(&world).next();
755 let _: Option<&Foo> = q.iter_many(&world, [e]).next();
756 q.iter(&world).for_each(|_: &Foo| ());
757
758 let _: Option<&Foo> = q.get(&world, e).ok();
759 let _: Option<&Foo> = q.get_manual(&world, e).ok();
760 let _: Option<[&Foo; 1]> = q.get_many(&world, [e]).ok();
761 let _: Option<&Foo> = q.get_single(&world).ok();
762 let _: &Foo = q.single(&world);
763
764 let mut q = SystemState::<Query<&mut Foo>>::new(&mut world);
766 let q = q.get_mut(&mut world);
767 let _: Option<&Foo> = q.iter().next();
768 let _: Option<[&Foo; 2]> = q.iter_combinations::<2>().next();
769 let _: Option<&Foo> = q.iter_many([e]).next();
770 q.iter().for_each(|_: &Foo| ());
771
772 let _: Option<&Foo> = q.get(e).ok();
773 let _: Option<[&Foo; 1]> = q.get_many([e]).ok();
774 let _: Option<&Foo> = q.get_single().ok();
775 let _: [&Foo; 1] = q.many([e]);
776 let _: &Foo = q.single();
777 }
778
779 #[test]
781 fn par_iter_mut_change_detection() {
782 let mut world = World::new();
783 world.spawn((A(1), B(1)));
784
785 fn propagate_system(mut query: Query<(&A, &mut B), Changed<A>>) {
786 query.par_iter_mut().for_each(|(a, mut b)| {
787 b.0 = a.0;
788 });
789 }
790
791 fn modify_system(mut query: Query<&mut A>) {
792 for mut a in &mut query {
793 a.0 = 2;
794 }
795 }
796
797 let mut schedule = Schedule::default();
798 schedule.add_systems((propagate_system, modify_system).chain());
799 schedule.run(&mut world);
800 world.clear_trackers();
801 schedule.run(&mut world);
802 world.clear_trackers();
803
804 let values = world.query::<&B>().iter(&world).collect::<Vec<&B>>();
805 assert_eq!(values, vec![&B(2)]);
806 }
807}