docs/bevy/release-content/migration-guides/query_many_iter_results.md 3.5 K · 121 lines · raw · history

1 ---
2 title: Query iterators from "many" entities now iterate over `Result` instead of `QueryData::Item`.
3 pull_requests: [25200]
4 ---
5
6 The following iterators now return `Result<QueryData::Item<'w, 's>, QueryEntityError>`
7 instead of `QueryData::Item<'w, 's>` as the `Iterator::Item`.
8
9 - `QueryManyIter`
10 - `QueryManyUniqueIter`
11 - `QuerySortedManyIter`
12
13 These iterators are created by the following methods.
14
15 - `Query::iter_many`
16 - `Query::iter_many_mut`
17 - `Query::iter_many_unique`
18 - `Query::iter_many_unique_mut`
19 - `QueryManyIter::sort*`
20
21 Likewise, the following parallel iterator methods now have `Result<QueryData::Item<'w, 's>, QueryEntityError>`
22 instead of `QueryData::Item<'w, 's>` as the closure argument.
23
24 - `QueryParManyIter::for_each`
25 - `QueryParManyIter::for_each_init`,
26 - `QueryParManyUniqueIter::for_each`
27 - `QueryParManyUniqueIter::for_each_init`,
28
29 These parallel iterators are created by the following methods.
30
31 - `Query::par_iter_many`
32 - `Query::par_iter_many_unique`
33 - `Query::par_iter_many_unique_mut`
34
35 These changes were made to allow for full flexibility in handling not matched or not spawned entities.
36 This allows easier debugging by making these errors visible through a panic or logging
37 instead of only giving the option to silently ignore these errors.
38
39 For `QueryManyIter` and `QueryManyUniqueIter` users can migrate using
40
41 - `QueryManyIter::matched`
42 - `QueryManyUniqueIter::matched`
43
44 which provide the same behavior as before.
45
46 ```rust
47 // 0.19
48 fn my_system(entity_list: Res<MyEntityList>, my_component_query: Query<&MyComponent>) {
49 for my_component in my_component_query.iter_many(entity_list.iter()) {
50 // ...
51 }
52 }
53
54 // 0.20
55 fn my_system(entity_list: Res<MyEntityList>, my_component_query: Query<&MyComponent>) {
56 for my_component in my_component_query.iter_many(entity_list.iter()).matched() {
57 // ...
58 }
59 }
60
61 // 0.19
62 fn my_mutation_system(entity_list: Res<MyEntityList>, mut my_component_query: Query<&mut MyComponent>) {
63 let mut iter = my_component_query.iter_many_mut(entity_list.iter());
64 while let Some(my_component) in iter.fetch_next() {
65 // ...
66 }
67 }
68
69 // 0.20
70 fn my_mutation_system(entity_list: Res<MyEntityList>, mut my_component_query: Query<&mut MyComponent>) {
71 let mut iter = my_component_query.iter_many_mut(entity_list.iter()).matched();
72 while let Some(my_component) in iter.fetch_next() {
73 // ...
74 }
75 }
76 ```
77
78 For `QuerySortedManyIter` you can only use `.flat_map(Result::ok)`.
79
80 ```rust
81 // 0.19
82 fn my_system(entity_list: Res<MyEntityList>, my_component_query: Query<&MyComponent>) {
83 for my_component in my_component_query.iter_many(entity_list.iter())
84 .sort::<&MyComponent>()
85 {
86 // ...
87 }
88 }
89
90 // 0.20
91 fn my_system(entity_list: Res<MyEntityList>, my_component_query: Query<&MyComponent>) {
92 for my_component in my_component_query.iter_many(entity_list.iter())
93 .sort::<&MyComponent>()
94 .flat_map(Result::ok)
95 {
96 // ...
97 }
98 }
99 ```
100
101 For `QueryParManyIter` and `QueryParManyUniqueIter` you need to return early when there is an error
102 to get the same `matched` behavior as before.
103
104 ```rust
105 // 0.19
106 fn my_system(entity_list: Res<MyEntityList>, my_component_query: Query<&MyComponent>) {
107 my_component_query.par_iter_many(entity_list.iter()).for_each(|my_component| {
108 // ...
109 });
110 }
111
112 // 0.20
113 fn my_system(entity_list: Res<MyEntityList>, my_component_query: Query<&MyComponent>) {
114 my_component_query.par_iter_many(entity_list.iter()).for_each(|my_component| {
115 let Ok(my_component) = my_component else {
116 return;
117 };
118 // ...
119 });
120 }
121 ```