@@ -1103,7 +1103,120 @@ macro_rules! impl_tuple_fetch {
1103
1103
} ;
1104
1104
}
1105
1105
1106
+ /// The `AnyOf` query parameter fetches entities with any of the component types included in T.
1107
+ ///
1108
+ /// `Query<AnyOf<(&A, &B, &mut C)>>` is equivalent to `Query<(Option<&A>, Option<&B>, Option<&mut C>), (Or(With<A>, With<B>, With<C>)>`.
1109
+ /// Each of the components in `T` is returned as an `Option`, as with `Option<A>` queries.
1110
+ /// Entities are guaranteed to have at least one of the components in `T`.
1111
+ pub struct AnyOf < T > ( T ) ;
1112
+
1113
+ macro_rules! impl_anytuple_fetch {
1114
+ ( $( ( $name: ident, $state: ident) ) ,* ) => {
1115
+ #[ allow( non_snake_case) ]
1116
+ impl <' w, ' s, $( $name: Fetch <' w, ' s>) ,* > Fetch <' w, ' s> for AnyOf <( $( ( $name, bool ) , ) * ) > {
1117
+ type Item = ( $( Option <$name:: Item >, ) * ) ;
1118
+ type State = AnyOf <( $( $name:: State , ) * ) >;
1119
+
1120
+ #[ allow( clippy:: unused_unit) ]
1121
+ unsafe fn init( _world: & World , state: & Self :: State , _last_change_tick: u32 , _change_tick: u32 ) -> Self {
1122
+ let ( $( $name, ) * ) = & state. 0 ;
1123
+ AnyOf ( ( $( ( $name:: init( _world, $name, _last_change_tick, _change_tick) , false ) , ) * ) )
1124
+ }
1125
+
1126
+
1127
+ const IS_DENSE : bool = true $( && $name:: IS_DENSE ) * ;
1128
+
1129
+ #[ inline]
1130
+ unsafe fn set_archetype( & mut self , _state: & Self :: State , _archetype: & Archetype , _tables: & Tables ) {
1131
+ let ( $( $name, ) * ) = & mut self . 0 ;
1132
+ let ( $( $state, ) * ) = & _state. 0 ;
1133
+ $(
1134
+ $name. 1 = $state. matches_archetype( _archetype) ;
1135
+ if $name. 1 {
1136
+ $name. 0 . set_archetype( $state, _archetype, _tables) ;
1137
+ }
1138
+ ) *
1139
+ }
1140
+
1141
+ #[ inline]
1142
+ unsafe fn set_table( & mut self , _state: & Self :: State , _table: & Table ) {
1143
+ let ( $( $name, ) * ) = & mut self . 0 ;
1144
+ let ( $( $state, ) * ) = & _state. 0 ;
1145
+ $(
1146
+ $name. 1 = $state. matches_table( _table) ;
1147
+ if $name. 1 {
1148
+ $name. 0 . set_table( $state, _table) ;
1149
+ }
1150
+ ) *
1151
+ }
1152
+
1153
+ #[ inline]
1154
+ #[ allow( clippy:: unused_unit) ]
1155
+ unsafe fn table_fetch( & mut self , _table_row: usize ) -> Self :: Item {
1156
+ let ( $( $name, ) * ) = & mut self . 0 ;
1157
+ ( $(
1158
+ $name. 1 . then( || $name. 0 . table_fetch( _table_row) ) ,
1159
+ ) * )
1160
+ }
1161
+
1162
+ #[ inline]
1163
+ #[ allow( clippy:: unused_unit) ]
1164
+ unsafe fn archetype_fetch( & mut self , _archetype_index: usize ) -> Self :: Item {
1165
+ let ( $( $name, ) * ) = & mut self . 0 ;
1166
+ ( $(
1167
+ $name. 1 . then( || $name. 0 . archetype_fetch( _archetype_index) ) ,
1168
+ ) * )
1169
+ }
1170
+ }
1171
+
1172
+ // SAFETY: update_component_access and update_archetype_component_access are called for each item in the tuple
1173
+ #[ allow( non_snake_case) ]
1174
+ #[ allow( clippy:: unused_unit) ]
1175
+ unsafe impl <$( $name: FetchState ) ,* > FetchState for AnyOf <( $( $name, ) * ) > {
1176
+ fn init( _world: & mut World ) -> Self {
1177
+ AnyOf ( ( $( $name:: init( _world) , ) * ) )
1178
+ }
1179
+
1180
+ fn update_component_access( & self , _access: & mut FilteredAccess <ComponentId >) {
1181
+ let ( $( $name, ) * ) = & self . 0 ;
1182
+ $( $name. update_component_access( _access) ; ) *
1183
+ }
1184
+
1185
+ fn update_archetype_component_access( & self , _archetype: & Archetype , _access: & mut Access <ArchetypeComponentId >) {
1186
+ let ( $( $name, ) * ) = & self . 0 ;
1187
+ $(
1188
+ if $name. matches_archetype( _archetype) {
1189
+ $name. update_archetype_component_access( _archetype, _access) ;
1190
+ }
1191
+ ) *
1192
+ }
1193
+
1194
+ fn matches_archetype( & self , _archetype: & Archetype ) -> bool {
1195
+ let ( $( $name, ) * ) = & self . 0 ;
1196
+ false $( || $name. matches_archetype( _archetype) ) *
1197
+ }
1198
+
1199
+ fn matches_table( & self , _table: & Table ) -> bool {
1200
+ let ( $( $name, ) * ) = & self . 0 ;
1201
+ false $( || $name. matches_table( _table) ) *
1202
+ }
1203
+ }
1204
+
1205
+ impl <$( $name: WorldQuery ) ,* > WorldQuery for AnyOf <( $( $name, ) * ) > {
1206
+ type Fetch = AnyOf <( $( ( $name:: Fetch , bool ) , ) * ) >;
1207
+ type ReadOnlyFetch = AnyOf <( $( ( $name:: ReadOnlyFetch , bool ) , ) * ) >;
1208
+
1209
+ type State = AnyOf <( $( $name:: State , ) * ) >;
1210
+ }
1211
+
1212
+ /// SAFETY: each item in the tuple is read only
1213
+ unsafe impl <$( $name: ReadOnlyFetch ) ,* > ReadOnlyFetch for AnyOf <( $( ( $name, bool ) , ) * ) > { }
1214
+
1215
+ } ;
1216
+ }
1217
+
1106
1218
all_tuples ! ( impl_tuple_fetch, 0 , 15 , F , S ) ;
1219
+ all_tuples ! ( impl_anytuple_fetch, 0 , 15 , F , S ) ;
1107
1220
1108
1221
/// [`Fetch`] that does not actually fetch anything
1109
1222
///
0 commit comments