1use core::marker::PhantomData;
2
3use crate::{
4 component::{ComponentId, StorageType},
5 prelude::*,
6};
7
8use super::{FilteredAccess, QueryData, QueryFilter};
9
10pub struct QueryBuilder<'w, D: QueryData = (), F: QueryFilter = ()> {
39 access: FilteredAccess,
40 world: &'w mut World,
41 or: bool,
42 first: bool,
43 _marker: PhantomData<(D, F)>,
44}
45
46impl<'w, D: QueryData, F: QueryFilter> QueryBuilder<'w, D, F> {
47 pub fn new(world: &'w mut World) -> Self {
49 let fetch_state = D::init_state(world);
50 let filter_state = F::init_state(world);
51
52 let mut access = FilteredAccess::default();
53 D::update_component_access(&fetch_state, &mut access);
54
55 let mut filter_access = FilteredAccess::default();
59 F::update_component_access(&filter_state, &mut filter_access);
60
61 access.extend(&filter_access);
64
65 Self {
66 access,
67 world,
68 or: false,
69 first: false,
70 _marker: PhantomData,
71 }
72 }
73
74 pub(super) fn is_dense(&self) -> bool {
75 let is_dense = |component_id| {
78 self.world()
79 .components()
80 .get_info(component_id)
81 .is_some_and(|info| info.storage_type() == StorageType::Table)
82 };
83
84 D::IS_DENSE
94 && F::IS_DENSE
95 && self.access.with_filters().all(is_dense)
96 && self.access.without_filters().all(is_dense)
97 }
98
99 pub fn world(&self) -> &World {
101 self.world
102 }
103
104 pub fn world_mut(&mut self) -> &mut World {
106 self.world
107 }
108
109 pub fn extend_access(&mut self, mut access: FilteredAccess) {
111 if self.or {
112 if self.first {
113 access.required.clear();
114 self.access.extend(&access);
115 self.first = false;
116 } else {
117 self.access.append_or(&access);
118 }
119 } else {
120 self.access.extend(&access);
121 }
122 }
123
124 pub fn data<T: QueryData>(&mut self) -> &mut Self {
126 let state = T::init_state(self.world);
127 let mut access = FilteredAccess::default();
128 T::update_component_access(&state, &mut access);
129 self.extend_access(access);
130 self
131 }
132
133 pub fn filter<T: QueryFilter>(&mut self) -> &mut Self {
135 let state = T::init_state(self.world);
136 let mut access = FilteredAccess::default();
137 T::update_component_access(&state, &mut access);
138 self.extend_access(access);
139 self
140 }
141
142 pub fn with<T: Component>(&mut self) -> &mut Self {
144 self.filter::<With<T>>();
145 self
146 }
147
148 pub fn with_id(&mut self, id: ComponentId) -> &mut Self {
150 let mut access = FilteredAccess::default();
151 access.and_with(id);
152 self.extend_access(access);
153 self
154 }
155
156 pub fn without<T: Component>(&mut self) -> &mut Self {
158 self.filter::<Without<T>>();
159 self
160 }
161
162 pub fn without_id(&mut self, id: ComponentId) -> &mut Self {
164 let mut access = FilteredAccess::default();
165 access.and_without(id);
166 self.extend_access(access);
167 self
168 }
169
170 pub fn ref_id(&mut self, id: ComponentId) -> &mut Self {
172 self.with_id(id);
173 self.access.add_component_read(id);
174 self
175 }
176
177 pub fn mut_id(&mut self, id: ComponentId) -> &mut Self {
179 self.with_id(id);
180 self.access.add_component_write(id);
181 self
182 }
183
184 pub fn optional(&mut self, f: impl Fn(&mut QueryBuilder)) -> &mut Self {
187 let mut builder = QueryBuilder::new(self.world);
188 f(&mut builder);
189 self.access.extend_access(builder.access());
190 self
191 }
192
193 pub fn and(&mut self, f: impl Fn(&mut QueryBuilder)) -> &mut Self {
198 let mut builder = QueryBuilder::new(self.world);
199 f(&mut builder);
200 let access = builder.access().clone();
201 self.extend_access(access);
202 self
203 }
204
205 pub fn or(&mut self, f: impl Fn(&mut QueryBuilder)) -> &mut Self {
227 let mut builder = QueryBuilder::new(self.world);
228 builder.or = true;
229 builder.first = true;
230 f(&mut builder);
231 self.access.extend(builder.access());
232 self
233 }
234
235 pub fn access(&self) -> &FilteredAccess {
237 &self.access
238 }
239
240 pub fn transmute<NewD: QueryData>(&mut self) -> &mut QueryBuilder<'w, NewD> {
245 self.transmute_filtered::<NewD, ()>()
246 }
247
248 pub fn transmute_filtered<NewD: QueryData, NewF: QueryFilter>(
251 &mut self,
252 ) -> &mut QueryBuilder<'w, NewD, NewF> {
253 let fetch_state = NewD::init_state(self.world);
254 let filter_state = NewF::init_state(self.world);
255
256 let mut access = FilteredAccess::default();
257 NewD::update_component_access(&fetch_state, &mut access);
258 NewF::update_component_access(&filter_state, &mut access);
259
260 self.extend_access(access);
261 unsafe { core::mem::transmute(self) }
265 }
266
267 pub fn build(&mut self) -> QueryState<D, F> {
272 QueryState::<D, F>::from_builder(self)
273 }
274}
275
276#[cfg(test)]
277mod tests {
278 use crate::{
279 prelude::*,
280 world::{EntityMutExcept, EntityRefExcept, FilteredEntityMut, FilteredEntityRef},
281 };
282 use std::dbg;
283
284 #[derive(Component, PartialEq, Debug)]
285 struct A(usize);
286
287 #[derive(Component, PartialEq, Debug)]
288 struct B(usize);
289
290 #[derive(Component, PartialEq, Debug)]
291 struct C(usize);
292
293 #[derive(Component)]
294 struct D;
295
296 #[test]
297 fn builder_with_without_static() {
298 let mut world = World::new();
299 let entity_a = world.spawn((A(0), B(0))).id();
300 let entity_b = world.spawn((A(0), C(0))).id();
301
302 let mut query_a = QueryBuilder::<Entity>::new(&mut world)
303 .with::<A>()
304 .without::<C>()
305 .build();
306 assert_eq!(entity_a, query_a.single(&world).unwrap());
307
308 let mut query_b = QueryBuilder::<Entity>::new(&mut world)
309 .with::<A>()
310 .without::<B>()
311 .build();
312 assert_eq!(entity_b, query_b.single(&world).unwrap());
313 }
314
315 #[test]
316 fn builder_with_without_dynamic() {
317 let mut world = World::new();
318 let entity_a = world.spawn((A(0), B(0))).id();
319 let entity_b = world.spawn((A(0), C(0))).id();
320 let component_id_a = world.register_component::<A>();
321 let component_id_b = world.register_component::<B>();
322 let component_id_c = world.register_component::<C>();
323
324 let mut query_a = QueryBuilder::<Entity>::new(&mut world)
325 .with_id(component_id_a)
326 .without_id(component_id_c)
327 .build();
328 assert_eq!(entity_a, query_a.single(&world).unwrap());
329
330 let mut query_b = QueryBuilder::<Entity>::new(&mut world)
331 .with_id(component_id_a)
332 .without_id(component_id_b)
333 .build();
334 assert_eq!(entity_b, query_b.single(&world).unwrap());
335 }
336
337 #[test]
338 fn builder_or() {
339 let mut world = World::new();
340 world.spawn((A(0), B(0), D));
341 world.spawn((B(0), D));
342 world.spawn((C(0), D));
343
344 let mut query_a = QueryBuilder::<&D>::new(&mut world)
345 .or(|builder| {
346 builder.with::<A>();
347 builder.with::<B>();
348 })
349 .build();
350 assert_eq!(2, query_a.iter(&world).count());
351
352 let mut query_b = QueryBuilder::<&D>::new(&mut world)
353 .or(|builder| {
354 builder.with::<A>();
355 builder.without::<B>();
356 })
357 .build();
358 dbg!(&query_b.component_access);
359 assert_eq!(2, query_b.iter(&world).count());
360
361 let mut query_c = QueryBuilder::<&D>::new(&mut world)
362 .or(|builder| {
363 builder.with::<A>();
364 builder.with::<B>();
365 builder.with::<C>();
366 })
367 .build();
368 assert_eq!(3, query_c.iter(&world).count());
369 }
370
371 #[test]
372 fn builder_transmute() {
373 let mut world = World::new();
374 world.spawn(A(0));
375 world.spawn((A(1), B(0)));
376 let mut query = QueryBuilder::<()>::new(&mut world)
377 .with::<B>()
378 .transmute::<&A>()
379 .build();
380
381 query.iter(&world).for_each(|a| assert_eq!(a.0, 1));
382 }
383
384 #[test]
385 fn builder_static_components() {
386 let mut world = World::new();
387 let entity = world.spawn((A(0), B(1))).id();
388
389 let mut query = QueryBuilder::<FilteredEntityRef>::new(&mut world)
390 .data::<&A>()
391 .data::<&B>()
392 .build();
393
394 let entity_ref = query.single(&world).unwrap();
395
396 assert_eq!(entity, entity_ref.id());
397
398 let a = entity_ref.get::<A>().unwrap();
399 let b = entity_ref.get::<B>().unwrap();
400
401 assert_eq!(0, a.0);
402 assert_eq!(1, b.0);
403 }
404
405 #[test]
406 fn builder_dynamic_components() {
407 let mut world = World::new();
408 let entity = world.spawn((A(0), B(1))).id();
409 let component_id_a = world.register_component::<A>();
410 let component_id_b = world.register_component::<B>();
411
412 let mut query = QueryBuilder::<FilteredEntityRef>::new(&mut world)
413 .ref_id(component_id_a)
414 .ref_id(component_id_b)
415 .build();
416
417 let entity_ref = query.single(&world).unwrap();
418
419 assert_eq!(entity, entity_ref.id());
420
421 let a = entity_ref.get_by_id(component_id_a).unwrap();
422 let b = entity_ref.get_by_id(component_id_b).unwrap();
423
424 unsafe {
426 assert_eq!(0, a.deref::<A>().0);
427 assert_eq!(1, b.deref::<B>().0);
428 }
429 }
430
431 #[test]
432 fn builder_provide_access() {
433 let mut world = World::new();
434 world.spawn((A(0), B(1), D));
435
436 let mut query =
437 QueryBuilder::<(Entity, FilteredEntityRef, FilteredEntityMut), With<D>>::new(
438 &mut world,
439 )
440 .data::<&mut A>()
441 .data::<&B>()
442 .build();
443
444 let (_entity, entity_ref_1, mut entity_ref_2) = query.single_mut(&mut world).unwrap();
446 assert!(entity_ref_1.get::<A>().is_some());
447 assert!(entity_ref_1.get::<B>().is_some());
448 assert!(entity_ref_2.get::<A>().is_some());
449 assert!(entity_ref_2.get_mut::<A>().is_none());
450 assert!(entity_ref_2.get::<B>().is_some());
451 assert!(entity_ref_2.get_mut::<B>().is_none());
452
453 let mut query =
454 QueryBuilder::<(Entity, FilteredEntityMut, FilteredEntityMut), With<D>>::new(
455 &mut world,
456 )
457 .data::<&mut A>()
458 .data::<&B>()
459 .build();
460
461 let (_entity, mut entity_ref_1, mut entity_ref_2) = query.single_mut(&mut world).unwrap();
463 assert!(entity_ref_1.get::<A>().is_some());
464 assert!(entity_ref_1.get_mut::<A>().is_some());
465 assert!(entity_ref_1.get::<B>().is_some());
466 assert!(entity_ref_1.get_mut::<B>().is_none());
467 assert!(entity_ref_2.get::<A>().is_none());
468 assert!(entity_ref_2.get_mut::<A>().is_none());
469 assert!(entity_ref_2.get::<B>().is_some());
470 assert!(entity_ref_2.get_mut::<B>().is_none());
471
472 let mut query = QueryBuilder::<(FilteredEntityMut, &mut A, &B), With<D>>::new(&mut world)
473 .data::<&mut A>()
474 .data::<&mut B>()
475 .build();
476
477 let (mut entity_ref, _a, _b) = query.single_mut(&mut world).unwrap();
479 assert!(entity_ref.get::<A>().is_none());
480 assert!(entity_ref.get_mut::<A>().is_none());
481 assert!(entity_ref.get::<B>().is_some());
482 assert!(entity_ref.get_mut::<B>().is_none());
483
484 let mut query = QueryBuilder::<(FilteredEntityMut, &mut A, &B), With<D>>::new(&mut world)
485 .data::<EntityMut>()
486 .build();
487
488 let (mut entity_ref, _a, _b) = query.single_mut(&mut world).unwrap();
490 assert!(entity_ref.get::<A>().is_none());
491 assert!(entity_ref.get_mut::<A>().is_none());
492 assert!(entity_ref.get::<B>().is_some());
493 assert!(entity_ref.get_mut::<B>().is_none());
494
495 let mut query =
496 QueryBuilder::<(FilteredEntityMut, EntityMutExcept<A>), With<D>>::new(&mut world)
497 .data::<EntityMut>()
498 .build();
499
500 let (mut entity_ref_1, _entity_ref_2) = query.single_mut(&mut world).unwrap();
502 assert!(entity_ref_1.get::<A>().is_some());
503 assert!(entity_ref_1.get_mut::<A>().is_some());
504 assert!(entity_ref_1.get::<B>().is_none());
505 assert!(entity_ref_1.get_mut::<B>().is_none());
506
507 let mut query =
508 QueryBuilder::<(FilteredEntityMut, EntityRefExcept<A>), With<D>>::new(&mut world)
509 .data::<EntityMut>()
510 .build();
511
512 let (mut entity_ref_1, _entity_ref_2) = query.single_mut(&mut world).unwrap();
514 assert!(entity_ref_1.get::<A>().is_some());
515 assert!(entity_ref_1.get_mut::<A>().is_some());
516 assert!(entity_ref_1.get::<B>().is_some());
517 assert!(entity_ref_1.get_mut::<B>().is_none());
518 }
519
520 #[test]
522 fn builder_static_dense_dynamic_sparse() {
523 #[derive(Component)]
524 struct Dense;
525
526 #[derive(Component)]
527 #[component(storage = "SparseSet")]
528 struct Sparse;
529
530 let mut world = World::new();
531
532 world.spawn(Dense);
533 world.spawn((Dense, Sparse));
534
535 let mut query = QueryBuilder::<&Dense>::new(&mut world)
536 .with::<Sparse>()
537 .build();
538
539 let matched = query.iter(&world).count();
540 assert_eq!(matched, 1);
541 }
542
543 #[test]
544 fn builder_dynamic_can_be_dense() {
545 #[derive(Component)]
546 #[component(storage = "SparseSet")]
547 struct Sparse;
548
549 let mut world = World::new();
550
551 let query = QueryBuilder::<FilteredEntityRef>::new(&mut world).build();
553 assert!(query.is_dense);
554
555 let query = QueryBuilder::<FilteredEntityMut>::new(&mut world).build();
556 assert!(query.is_dense);
557
558 let query = QueryBuilder::<FilteredEntityRef>::new(&mut world)
560 .data::<&Sparse>()
561 .build();
562 assert!(!query.is_dense);
563
564 let query = QueryBuilder::<FilteredEntityRef>::new(&mut world)
566 .data::<Option<&Sparse>>()
567 .build();
568 assert!(query.is_dense);
569 }
570}