1use crate::{
2 archetype::{Archetype, Archetypes},
3 bundle::Bundle,
4 change_detection::{MaybeLocation, Ticks, TicksMut},
5 component::{Component, ComponentId, Components, Mutable, StorageType, Tick},
6 entity::{Entities, Entity, EntityLocation},
7 query::{Access, DebugCheckedUnwrap, FilteredAccess, WorldQuery},
8 storage::{ComponentSparseSet, Table, TableRow},
9 world::{
10 unsafe_world_cell::UnsafeWorldCell, EntityMut, EntityMutExcept, EntityRef, EntityRefExcept,
11 FilteredEntityMut, FilteredEntityRef, Mut, Ref, World,
12 },
13};
14use bevy_ptr::{ThinSlicePtr, UnsafeCellDeref};
15use core::{cell::UnsafeCell, marker::PhantomData, panic::Location};
16use smallvec::SmallVec;
17use variadics_please::all_tuples;
18
19#[diagnostic::on_unimplemented(
275 message = "`{Self}` is not valid to request as data in a `Query`",
276 label = "invalid `Query` data",
277 note = "if `{Self}` is a component type, try using `&{Self}` or `&mut {Self}`"
278)]
279pub unsafe trait QueryData: WorldQuery {
280 const IS_READ_ONLY: bool;
282
283 type ReadOnly: ReadOnlyQueryData<State = <Self as WorldQuery>::State>;
285
286 type Item<'a>;
290
291 fn shrink<'wlong: 'wshort, 'wshort>(item: Self::Item<'wlong>) -> Self::Item<'wshort>;
293
294 unsafe fn fetch<'w>(
306 fetch: &mut Self::Fetch<'w>,
307 entity: Entity,
308 table_row: TableRow,
309 ) -> Self::Item<'w>;
310}
311
312pub unsafe trait ReadOnlyQueryData: QueryData<ReadOnly = Self> {}
318
319pub type QueryItem<'w, Q> = <Q as QueryData>::Item<'w>;
321pub type ROQueryItem<'w, D> = QueryItem<'w, <D as QueryData>::ReadOnly>;
323
324unsafe impl WorldQuery for Entity {
328 type Fetch<'w> = ();
329 type State = ();
330
331 fn shrink_fetch<'wlong: 'wshort, 'wshort>(_: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {}
332
333 unsafe fn init_fetch<'w>(
334 _world: UnsafeWorldCell<'w>,
335 _state: &Self::State,
336 _last_run: Tick,
337 _this_run: Tick,
338 ) -> Self::Fetch<'w> {
339 }
340
341 const IS_DENSE: bool = true;
342
343 #[inline]
344 unsafe fn set_archetype<'w>(
345 _fetch: &mut Self::Fetch<'w>,
346 _state: &Self::State,
347 _archetype: &'w Archetype,
348 _table: &Table,
349 ) {
350 }
351
352 #[inline]
353 unsafe fn set_table<'w>(_fetch: &mut Self::Fetch<'w>, _state: &Self::State, _table: &'w Table) {
354 }
355
356 fn update_component_access(_state: &Self::State, _access: &mut FilteredAccess<ComponentId>) {}
357
358 fn init_state(_world: &mut World) {}
359
360 fn get_state(_components: &Components) -> Option<()> {
361 Some(())
362 }
363
364 fn matches_component_set(
365 _state: &Self::State,
366 _set_contains_id: &impl Fn(ComponentId) -> bool,
367 ) -> bool {
368 true
369 }
370}
371
372unsafe impl QueryData for Entity {
374 const IS_READ_ONLY: bool = true;
375 type ReadOnly = Self;
376
377 type Item<'w> = Entity;
378
379 fn shrink<'wlong: 'wshort, 'wshort>(item: Self::Item<'wlong>) -> Self::Item<'wshort> {
380 item
381 }
382
383 #[inline(always)]
384 unsafe fn fetch<'w>(
385 _fetch: &mut Self::Fetch<'w>,
386 entity: Entity,
387 _table_row: TableRow,
388 ) -> Self::Item<'w> {
389 entity
390 }
391}
392
393unsafe impl ReadOnlyQueryData for Entity {}
395
396unsafe impl WorldQuery for EntityLocation {
400 type Fetch<'w> = &'w Entities;
401 type State = ();
402
403 fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
404 fetch
405 }
406
407 unsafe fn init_fetch<'w>(
408 world: UnsafeWorldCell<'w>,
409 _state: &Self::State,
410 _last_run: Tick,
411 _this_run: Tick,
412 ) -> Self::Fetch<'w> {
413 world.entities()
414 }
415
416 const IS_DENSE: bool = true;
419
420 #[inline]
421 unsafe fn set_archetype<'w>(
422 _fetch: &mut Self::Fetch<'w>,
423 _state: &Self::State,
424 _archetype: &'w Archetype,
425 _table: &Table,
426 ) {
427 }
428
429 #[inline]
430 unsafe fn set_table<'w>(_fetch: &mut Self::Fetch<'w>, _state: &Self::State, _table: &'w Table) {
431 }
432
433 fn update_component_access(_state: &Self::State, _access: &mut FilteredAccess<ComponentId>) {}
434
435 fn init_state(_world: &mut World) {}
436
437 fn get_state(_components: &Components) -> Option<()> {
438 Some(())
439 }
440
441 fn matches_component_set(
442 _state: &Self::State,
443 _set_contains_id: &impl Fn(ComponentId) -> bool,
444 ) -> bool {
445 true
446 }
447}
448
449unsafe impl QueryData for EntityLocation {
451 const IS_READ_ONLY: bool = true;
452 type ReadOnly = Self;
453 type Item<'w> = EntityLocation;
454
455 fn shrink<'wlong: 'wshort, 'wshort>(item: Self::Item<'wlong>) -> Self::Item<'wshort> {
456 item
457 }
458
459 #[inline(always)]
460 unsafe fn fetch<'w>(
461 fetch: &mut Self::Fetch<'w>,
462 entity: Entity,
463 _table_row: TableRow,
464 ) -> Self::Item<'w> {
465 unsafe { fetch.get(entity).debug_checked_unwrap() }
467 }
468}
469
470unsafe impl ReadOnlyQueryData for EntityLocation {}
472
473unsafe impl<'a> WorldQuery for EntityRef<'a> {
478 type Fetch<'w> = UnsafeWorldCell<'w>;
479 type State = ();
480
481 fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
482 fetch
483 }
484
485 unsafe fn init_fetch<'w>(
486 world: UnsafeWorldCell<'w>,
487 _state: &Self::State,
488 _last_run: Tick,
489 _this_run: Tick,
490 ) -> Self::Fetch<'w> {
491 world
492 }
493
494 const IS_DENSE: bool = true;
495
496 #[inline]
497 unsafe fn set_archetype<'w>(
498 _fetch: &mut Self::Fetch<'w>,
499 _state: &Self::State,
500 _archetype: &'w Archetype,
501 _table: &Table,
502 ) {
503 }
504
505 #[inline]
506 unsafe fn set_table<'w>(_fetch: &mut Self::Fetch<'w>, _state: &Self::State, _table: &'w Table) {
507 }
508
509 fn update_component_access(_state: &Self::State, access: &mut FilteredAccess<ComponentId>) {
510 assert!(
511 !access.access().has_any_component_write(),
512 "EntityRef conflicts with a previous access in this query. Shared access cannot coincide with exclusive access.",
513 );
514 access.read_all_components();
515 }
516
517 fn init_state(_world: &mut World) {}
518
519 fn get_state(_components: &Components) -> Option<()> {
520 Some(())
521 }
522
523 fn matches_component_set(
524 _state: &Self::State,
525 _set_contains_id: &impl Fn(ComponentId) -> bool,
526 ) -> bool {
527 true
528 }
529}
530
531unsafe impl<'a> QueryData for EntityRef<'a> {
533 const IS_READ_ONLY: bool = true;
534 type ReadOnly = Self;
535 type Item<'w> = EntityRef<'w>;
536
537 fn shrink<'wlong: 'wshort, 'wshort>(item: Self::Item<'wlong>) -> Self::Item<'wshort> {
538 item
539 }
540
541 #[inline(always)]
542 unsafe fn fetch<'w>(
543 world: &mut Self::Fetch<'w>,
544 entity: Entity,
545 _table_row: TableRow,
546 ) -> Self::Item<'w> {
547 let cell = unsafe { world.get_entity(entity).debug_checked_unwrap() };
549 unsafe { EntityRef::new(cell) }
551 }
552}
553
554unsafe impl ReadOnlyQueryData for EntityRef<'_> {}
556
557unsafe impl<'a> WorldQuery for EntityMut<'a> {
559 type Fetch<'w> = UnsafeWorldCell<'w>;
560 type State = ();
561
562 fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
563 fetch
564 }
565
566 unsafe fn init_fetch<'w>(
567 world: UnsafeWorldCell<'w>,
568 _state: &Self::State,
569 _last_run: Tick,
570 _this_run: Tick,
571 ) -> Self::Fetch<'w> {
572 world
573 }
574
575 const IS_DENSE: bool = true;
576
577 #[inline]
578 unsafe fn set_archetype<'w>(
579 _fetch: &mut Self::Fetch<'w>,
580 _state: &Self::State,
581 _archetype: &'w Archetype,
582 _table: &Table,
583 ) {
584 }
585
586 #[inline]
587 unsafe fn set_table<'w>(_fetch: &mut Self::Fetch<'w>, _state: &Self::State, _table: &'w Table) {
588 }
589
590 fn update_component_access(_state: &Self::State, access: &mut FilteredAccess<ComponentId>) {
591 assert!(
592 !access.access().has_any_component_read(),
593 "EntityMut conflicts with a previous access in this query. Exclusive access cannot coincide with any other accesses.",
594 );
595 access.write_all_components();
596 }
597
598 fn init_state(_world: &mut World) {}
599
600 fn get_state(_components: &Components) -> Option<()> {
601 Some(())
602 }
603
604 fn matches_component_set(
605 _state: &Self::State,
606 _set_contains_id: &impl Fn(ComponentId) -> bool,
607 ) -> bool {
608 true
609 }
610}
611
612unsafe impl<'a> QueryData for EntityMut<'a> {
614 const IS_READ_ONLY: bool = false;
615 type ReadOnly = EntityRef<'a>;
616 type Item<'w> = EntityMut<'w>;
617
618 fn shrink<'wlong: 'wshort, 'wshort>(item: Self::Item<'wlong>) -> Self::Item<'wshort> {
619 item
620 }
621
622 #[inline(always)]
623 unsafe fn fetch<'w>(
624 world: &mut Self::Fetch<'w>,
625 entity: Entity,
626 _table_row: TableRow,
627 ) -> Self::Item<'w> {
628 let cell = unsafe { world.get_entity(entity).debug_checked_unwrap() };
630 unsafe { EntityMut::new(cell) }
632 }
633}
634
635unsafe impl<'a> WorldQuery for FilteredEntityRef<'a> {
637 type Fetch<'w> = (UnsafeWorldCell<'w>, Access<ComponentId>);
638 type State = FilteredAccess<ComponentId>;
639
640 fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
641 fetch
642 }
643
644 const IS_DENSE: bool = false;
645
646 unsafe fn init_fetch<'w>(
647 world: UnsafeWorldCell<'w>,
648 _state: &Self::State,
649 _last_run: Tick,
650 _this_run: Tick,
651 ) -> Self::Fetch<'w> {
652 let mut access = Access::default();
653 access.read_all_components();
654 (world, access)
655 }
656
657 #[inline]
658 unsafe fn set_archetype<'w>(
659 fetch: &mut Self::Fetch<'w>,
660 state: &Self::State,
661 _: &'w Archetype,
662 _table: &Table,
663 ) {
664 fetch.1.clone_from(&state.access);
665 }
666
667 #[inline]
668 unsafe fn set_table<'w>(fetch: &mut Self::Fetch<'w>, state: &Self::State, _: &'w Table) {
669 fetch.1.clone_from(&state.access);
670 }
671
672 #[inline]
673 fn set_access<'w>(state: &mut Self::State, access: &FilteredAccess<ComponentId>) {
674 state.clone_from(access);
675 state.access_mut().clear_writes();
676 }
677
678 fn update_component_access(
679 state: &Self::State,
680 filtered_access: &mut FilteredAccess<ComponentId>,
681 ) {
682 assert!(
683 filtered_access.access().is_compatible(&state.access),
684 "FilteredEntityRef conflicts with a previous access in this query. Exclusive access cannot coincide with any other accesses.",
685 );
686 filtered_access.access.extend(&state.access);
687 }
688
689 fn init_state(_world: &mut World) -> Self::State {
690 FilteredAccess::default()
691 }
692
693 fn get_state(_components: &Components) -> Option<Self::State> {
694 Some(FilteredAccess::default())
695 }
696
697 fn matches_component_set(
698 _state: &Self::State,
699 _set_contains_id: &impl Fn(ComponentId) -> bool,
700 ) -> bool {
701 true
702 }
703}
704
705unsafe impl<'a> QueryData for FilteredEntityRef<'a> {
707 const IS_READ_ONLY: bool = true;
708 type ReadOnly = Self;
709 type Item<'w> = FilteredEntityRef<'w>;
710
711 fn shrink<'wlong: 'wshort, 'wshort>(item: Self::Item<'wlong>) -> Self::Item<'wshort> {
712 item
713 }
714
715 #[inline(always)]
716 unsafe fn fetch<'w>(
717 (world, access): &mut Self::Fetch<'w>,
718 entity: Entity,
719 _table_row: TableRow,
720 ) -> Self::Item<'w> {
721 let cell = unsafe { world.get_entity(entity).debug_checked_unwrap() };
723 unsafe { FilteredEntityRef::new(cell, access.clone()) }
725 }
726}
727
728unsafe impl ReadOnlyQueryData for FilteredEntityRef<'_> {}
730
731unsafe impl<'a> WorldQuery for FilteredEntityMut<'a> {
733 type Fetch<'w> = (UnsafeWorldCell<'w>, Access<ComponentId>);
734 type State = FilteredAccess<ComponentId>;
735
736 fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
737 fetch
738 }
739
740 const IS_DENSE: bool = false;
741
742 unsafe fn init_fetch<'w>(
743 world: UnsafeWorldCell<'w>,
744 _state: &Self::State,
745 _last_run: Tick,
746 _this_run: Tick,
747 ) -> Self::Fetch<'w> {
748 let mut access = Access::default();
749 access.write_all_components();
750 (world, access)
751 }
752
753 #[inline]
754 unsafe fn set_archetype<'w>(
755 fetch: &mut Self::Fetch<'w>,
756 state: &Self::State,
757 _: &'w Archetype,
758 _table: &Table,
759 ) {
760 fetch.1.clone_from(&state.access);
761 }
762
763 #[inline]
764 unsafe fn set_table<'w>(fetch: &mut Self::Fetch<'w>, state: &Self::State, _: &'w Table) {
765 fetch.1.clone_from(&state.access);
766 }
767
768 #[inline]
769 fn set_access<'w>(state: &mut Self::State, access: &FilteredAccess<ComponentId>) {
770 state.clone_from(access);
771 }
772
773 fn update_component_access(
774 state: &Self::State,
775 filtered_access: &mut FilteredAccess<ComponentId>,
776 ) {
777 assert!(
778 filtered_access.access().is_compatible(&state.access),
779 "FilteredEntityMut conflicts with a previous access in this query. Exclusive access cannot coincide with any other accesses.",
780 );
781 filtered_access.access.extend(&state.access);
782 }
783
784 fn init_state(_world: &mut World) -> Self::State {
785 FilteredAccess::default()
786 }
787
788 fn get_state(_components: &Components) -> Option<Self::State> {
789 Some(FilteredAccess::default())
790 }
791
792 fn matches_component_set(
793 _state: &Self::State,
794 _set_contains_id: &impl Fn(ComponentId) -> bool,
795 ) -> bool {
796 true
797 }
798}
799
800unsafe impl<'a> QueryData for FilteredEntityMut<'a> {
802 const IS_READ_ONLY: bool = false;
803 type ReadOnly = FilteredEntityRef<'a>;
804 type Item<'w> = FilteredEntityMut<'w>;
805
806 fn shrink<'wlong: 'wshort, 'wshort>(item: Self::Item<'wlong>) -> Self::Item<'wshort> {
807 item
808 }
809
810 #[inline(always)]
811 unsafe fn fetch<'w>(
812 (world, access): &mut Self::Fetch<'w>,
813 entity: Entity,
814 _table_row: TableRow,
815 ) -> Self::Item<'w> {
816 let cell = unsafe { world.get_entity(entity).debug_checked_unwrap() };
818 unsafe { FilteredEntityMut::new(cell, access.clone()) }
820 }
821}
822
823unsafe impl<'a, B> WorldQuery for EntityRefExcept<'a, B>
827where
828 B: Bundle,
829{
830 type Fetch<'w> = UnsafeWorldCell<'w>;
831 type State = SmallVec<[ComponentId; 4]>;
832
833 fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
834 fetch
835 }
836
837 unsafe fn init_fetch<'w>(
838 world: UnsafeWorldCell<'w>,
839 _: &Self::State,
840 _: Tick,
841 _: Tick,
842 ) -> Self::Fetch<'w> {
843 world
844 }
845
846 const IS_DENSE: bool = true;
847
848 unsafe fn set_archetype<'w>(
849 _: &mut Self::Fetch<'w>,
850 _: &Self::State,
851 _: &'w Archetype,
852 _: &'w Table,
853 ) {
854 }
855
856 unsafe fn set_table<'w>(_: &mut Self::Fetch<'w>, _: &Self::State, _: &'w Table) {}
857
858 fn update_component_access(
859 state: &Self::State,
860 filtered_access: &mut FilteredAccess<ComponentId>,
861 ) {
862 let mut my_access = Access::new();
863 my_access.read_all_components();
864 for id in state {
865 my_access.remove_component_read(*id);
866 }
867
868 let access = filtered_access.access_mut();
869 assert!(
870 access.is_compatible(&my_access),
871 "`EntityRefExcept<{}>` conflicts with a previous access in this query.",
872 core::any::type_name::<B>(),
873 );
874 access.extend(&my_access);
875 }
876
877 fn init_state(world: &mut World) -> Self::State {
878 Self::get_state(world.components()).unwrap()
879 }
880
881 fn get_state(components: &Components) -> Option<Self::State> {
882 let mut ids = SmallVec::new();
883 B::get_component_ids(components, &mut |maybe_id| {
884 if let Some(id) = maybe_id {
885 ids.push(id);
886 }
887 });
888 Some(ids)
889 }
890
891 fn matches_component_set(_: &Self::State, _: &impl Fn(ComponentId) -> bool) -> bool {
892 true
893 }
894}
895
896unsafe impl<'a, B> QueryData for EntityRefExcept<'a, B>
898where
899 B: Bundle,
900{
901 const IS_READ_ONLY: bool = true;
902 type ReadOnly = Self;
903 type Item<'w> = EntityRefExcept<'w, B>;
904
905 fn shrink<'wlong: 'wshort, 'wshort>(item: Self::Item<'wlong>) -> Self::Item<'wshort> {
906 item
907 }
908
909 unsafe fn fetch<'w>(
910 world: &mut Self::Fetch<'w>,
911 entity: Entity,
912 _: TableRow,
913 ) -> Self::Item<'w> {
914 let cell = world.get_entity(entity).unwrap();
915 EntityRefExcept::new(cell)
916 }
917}
918
919unsafe impl<'a, B> ReadOnlyQueryData for EntityRefExcept<'a, B> where B: Bundle {}
922
923unsafe impl<'a, B> WorldQuery for EntityMutExcept<'a, B>
927where
928 B: Bundle,
929{
930 type Fetch<'w> = UnsafeWorldCell<'w>;
931 type State = SmallVec<[ComponentId; 4]>;
932
933 fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
934 fetch
935 }
936
937 unsafe fn init_fetch<'w>(
938 world: UnsafeWorldCell<'w>,
939 _: &Self::State,
940 _: Tick,
941 _: Tick,
942 ) -> Self::Fetch<'w> {
943 world
944 }
945
946 const IS_DENSE: bool = true;
947
948 unsafe fn set_archetype<'w>(
949 _: &mut Self::Fetch<'w>,
950 _: &Self::State,
951 _: &'w Archetype,
952 _: &'w Table,
953 ) {
954 }
955
956 unsafe fn set_table<'w>(_: &mut Self::Fetch<'w>, _: &Self::State, _: &'w Table) {}
957
958 fn update_component_access(
959 state: &Self::State,
960 filtered_access: &mut FilteredAccess<ComponentId>,
961 ) {
962 let mut my_access = Access::new();
963 my_access.write_all_components();
964 for id in state {
965 my_access.remove_component_read(*id);
966 }
967
968 let access = filtered_access.access_mut();
969 assert!(
970 access.is_compatible(&my_access),
971 "`EntityMutExcept<{}>` conflicts with a previous access in this query.",
972 core::any::type_name::<B>()
973 );
974 access.extend(&my_access);
975 }
976
977 fn init_state(world: &mut World) -> Self::State {
978 Self::get_state(world.components()).unwrap()
979 }
980
981 fn get_state(components: &Components) -> Option<Self::State> {
982 let mut ids = SmallVec::new();
983 B::get_component_ids(components, &mut |maybe_id| {
984 if let Some(id) = maybe_id {
985 ids.push(id);
986 }
987 });
988 Some(ids)
989 }
990
991 fn matches_component_set(_: &Self::State, _: &impl Fn(ComponentId) -> bool) -> bool {
992 true
993 }
994}
995
996unsafe impl<'a, B> QueryData for EntityMutExcept<'a, B>
999where
1000 B: Bundle,
1001{
1002 const IS_READ_ONLY: bool = false;
1003 type ReadOnly = EntityRefExcept<'a, B>;
1004 type Item<'w> = EntityMutExcept<'w, B>;
1005
1006 fn shrink<'wlong: 'wshort, 'wshort>(item: Self::Item<'wlong>) -> Self::Item<'wshort> {
1007 item
1008 }
1009
1010 unsafe fn fetch<'w>(
1011 world: &mut Self::Fetch<'w>,
1012 entity: Entity,
1013 _: TableRow,
1014 ) -> Self::Item<'w> {
1015 let cell = world.get_entity(entity).unwrap();
1016 EntityMutExcept::new(cell)
1017 }
1018}
1019
1020unsafe impl WorldQuery for &Archetype {
1024 type Fetch<'w> = (&'w Entities, &'w Archetypes);
1025 type State = ();
1026
1027 fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
1028 fetch
1029 }
1030
1031 unsafe fn init_fetch<'w>(
1032 world: UnsafeWorldCell<'w>,
1033 _state: &Self::State,
1034 _last_run: Tick,
1035 _this_run: Tick,
1036 ) -> Self::Fetch<'w> {
1037 (world.entities(), world.archetypes())
1038 }
1039
1040 const IS_DENSE: bool = true;
1043
1044 #[inline]
1045 unsafe fn set_archetype<'w>(
1046 _fetch: &mut Self::Fetch<'w>,
1047 _state: &Self::State,
1048 _archetype: &'w Archetype,
1049 _table: &Table,
1050 ) {
1051 }
1052
1053 #[inline]
1054 unsafe fn set_table<'w>(_fetch: &mut Self::Fetch<'w>, _state: &Self::State, _table: &'w Table) {
1055 }
1056
1057 fn update_component_access(_state: &Self::State, _access: &mut FilteredAccess<ComponentId>) {}
1058
1059 fn init_state(_world: &mut World) {}
1060
1061 fn get_state(_components: &Components) -> Option<()> {
1062 Some(())
1063 }
1064
1065 fn matches_component_set(
1066 _state: &Self::State,
1067 _set_contains_id: &impl Fn(ComponentId) -> bool,
1068 ) -> bool {
1069 true
1070 }
1071}
1072
1073unsafe impl QueryData for &Archetype {
1075 const IS_READ_ONLY: bool = true;
1076 type ReadOnly = Self;
1077 type Item<'w> = &'w Archetype;
1078
1079 fn shrink<'wlong: 'wshort, 'wshort>(item: Self::Item<'wlong>) -> Self::Item<'wshort> {
1080 item
1081 }
1082
1083 #[inline(always)]
1084 unsafe fn fetch<'w>(
1085 fetch: &mut Self::Fetch<'w>,
1086 entity: Entity,
1087 _table_row: TableRow,
1088 ) -> Self::Item<'w> {
1089 let (entities, archetypes) = *fetch;
1090 let location = unsafe { entities.get(entity).debug_checked_unwrap() };
1092 unsafe { archetypes.get(location.archetype_id).debug_checked_unwrap() }
1094 }
1095}
1096
1097unsafe impl ReadOnlyQueryData for &Archetype {}
1099
1100pub struct ReadFetch<'w, T: Component> {
1102 components: StorageSwitch<
1103 T,
1104 Option<ThinSlicePtr<'w, UnsafeCell<T>>>,
1106 Option<&'w ComponentSparseSet>,
1108 >,
1109}
1110
1111impl<T: Component> Clone for ReadFetch<'_, T> {
1112 fn clone(&self) -> Self {
1113 *self
1114 }
1115}
1116impl<T: Component> Copy for ReadFetch<'_, T> {}
1117
1118unsafe impl<T: Component> WorldQuery for &T {
1124 type Fetch<'w> = ReadFetch<'w, T>;
1125 type State = ComponentId;
1126
1127 fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
1128 fetch
1129 }
1130
1131 #[inline]
1132 unsafe fn init_fetch<'w>(
1133 world: UnsafeWorldCell<'w>,
1134 &component_id: &ComponentId,
1135 _last_run: Tick,
1136 _this_run: Tick,
1137 ) -> ReadFetch<'w, T> {
1138 ReadFetch {
1139 components: StorageSwitch::new(
1140 || None,
1141 || {
1142 unsafe { world.storages().sparse_sets.get(component_id) }
1147 },
1148 ),
1149 }
1150 }
1151
1152 const IS_DENSE: bool = {
1153 match T::STORAGE_TYPE {
1154 StorageType::Table => true,
1155 StorageType::SparseSet => false,
1156 }
1157 };
1158
1159 #[inline]
1160 unsafe fn set_archetype<'w>(
1161 fetch: &mut ReadFetch<'w, T>,
1162 component_id: &ComponentId,
1163 _archetype: &'w Archetype,
1164 table: &'w Table,
1165 ) {
1166 if Self::IS_DENSE {
1167 unsafe {
1169 Self::set_table(fetch, component_id, table);
1170 }
1171 }
1172 }
1173
1174 #[inline]
1175 unsafe fn set_table<'w>(
1176 fetch: &mut ReadFetch<'w, T>,
1177 &component_id: &ComponentId,
1178 table: &'w Table,
1179 ) {
1180 let table_data = Some(
1181 table
1182 .get_data_slice_for(component_id)
1183 .debug_checked_unwrap()
1184 .into(),
1185 );
1186 unsafe { fetch.components.set_table(table_data) };
1188 }
1189
1190 fn update_component_access(
1191 &component_id: &ComponentId,
1192 access: &mut FilteredAccess<ComponentId>,
1193 ) {
1194 assert!(
1195 !access.access().has_component_write(component_id),
1196 "&{} conflicts with a previous access in this query. Shared access cannot coincide with exclusive access.",
1197 core::any::type_name::<T>(),
1198 );
1199 access.add_component_read(component_id);
1200 }
1201
1202 fn init_state(world: &mut World) -> ComponentId {
1203 world.register_component::<T>()
1204 }
1205
1206 fn get_state(components: &Components) -> Option<Self::State> {
1207 components.component_id::<T>()
1208 }
1209
1210 fn matches_component_set(
1211 &state: &ComponentId,
1212 set_contains_id: &impl Fn(ComponentId) -> bool,
1213 ) -> bool {
1214 set_contains_id(state)
1215 }
1216}
1217
1218unsafe impl<T: Component> QueryData for &T {
1220 const IS_READ_ONLY: bool = true;
1221 type ReadOnly = Self;
1222 type Item<'w> = &'w T;
1223
1224 fn shrink<'wlong: 'wshort, 'wshort>(item: &'wlong T) -> &'wshort T {
1225 item
1226 }
1227
1228 #[inline(always)]
1229 unsafe fn fetch<'w>(
1230 fetch: &mut Self::Fetch<'w>,
1231 entity: Entity,
1232 table_row: TableRow,
1233 ) -> Self::Item<'w> {
1234 fetch.components.extract(
1235 |table| {
1236 let table = unsafe { table.debug_checked_unwrap() };
1238 let item = unsafe { table.get(table_row.as_usize()) };
1240 item.deref()
1241 },
1242 |sparse_set| {
1243 let item = unsafe {
1245 sparse_set
1246 .debug_checked_unwrap()
1247 .get(entity)
1248 .debug_checked_unwrap()
1249 };
1250 item.deref()
1251 },
1252 )
1253 }
1254}
1255
1256unsafe impl<T: Component> ReadOnlyQueryData for &T {}
1258
1259#[doc(hidden)]
1260pub struct RefFetch<'w, T: Component> {
1261 components: StorageSwitch<
1262 T,
1263 Option<(
1265 ThinSlicePtr<'w, UnsafeCell<T>>,
1266 ThinSlicePtr<'w, UnsafeCell<Tick>>,
1267 ThinSlicePtr<'w, UnsafeCell<Tick>>,
1268 MaybeLocation<ThinSlicePtr<'w, UnsafeCell<&'static Location<'static>>>>,
1269 )>,
1270 Option<&'w ComponentSparseSet>,
1273 >,
1274 last_run: Tick,
1275 this_run: Tick,
1276}
1277
1278impl<T: Component> Clone for RefFetch<'_, T> {
1279 fn clone(&self) -> Self {
1280 *self
1281 }
1282}
1283impl<T: Component> Copy for RefFetch<'_, T> {}
1284
1285unsafe impl<'__w, T: Component> WorldQuery for Ref<'__w, T> {
1291 type Fetch<'w> = RefFetch<'w, T>;
1292 type State = ComponentId;
1293
1294 fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
1295 fetch
1296 }
1297
1298 #[inline]
1299 unsafe fn init_fetch<'w>(
1300 world: UnsafeWorldCell<'w>,
1301 &component_id: &ComponentId,
1302 last_run: Tick,
1303 this_run: Tick,
1304 ) -> RefFetch<'w, T> {
1305 RefFetch {
1306 components: StorageSwitch::new(
1307 || None,
1308 || {
1309 unsafe { world.storages().sparse_sets.get(component_id) }
1314 },
1315 ),
1316 last_run,
1317 this_run,
1318 }
1319 }
1320
1321 const IS_DENSE: bool = {
1322 match T::STORAGE_TYPE {
1323 StorageType::Table => true,
1324 StorageType::SparseSet => false,
1325 }
1326 };
1327
1328 #[inline]
1329 unsafe fn set_archetype<'w>(
1330 fetch: &mut RefFetch<'w, T>,
1331 component_id: &ComponentId,
1332 _archetype: &'w Archetype,
1333 table: &'w Table,
1334 ) {
1335 if Self::IS_DENSE {
1336 unsafe {
1338 Self::set_table(fetch, component_id, table);
1339 }
1340 }
1341 }
1342
1343 #[inline]
1344 unsafe fn set_table<'w>(
1345 fetch: &mut RefFetch<'w, T>,
1346 &component_id: &ComponentId,
1347 table: &'w Table,
1348 ) {
1349 let column = table.get_column(component_id).debug_checked_unwrap();
1350 let table_data = Some((
1351 column.get_data_slice(table.entity_count()).into(),
1352 column.get_added_ticks_slice(table.entity_count()).into(),
1353 column.get_changed_ticks_slice(table.entity_count()).into(),
1354 column
1355 .get_changed_by_slice(table.entity_count())
1356 .map(Into::into),
1357 ));
1358 unsafe { fetch.components.set_table(table_data) };
1360 }
1361
1362 fn update_component_access(
1363 &component_id: &ComponentId,
1364 access: &mut FilteredAccess<ComponentId>,
1365 ) {
1366 assert!(
1367 !access.access().has_component_write(component_id),
1368 "&{} conflicts with a previous access in this query. Shared access cannot coincide with exclusive access.",
1369 core::any::type_name::<T>(),
1370 );
1371 access.add_component_read(component_id);
1372 }
1373
1374 fn init_state(world: &mut World) -> ComponentId {
1375 world.register_component::<T>()
1376 }
1377
1378 fn get_state(components: &Components) -> Option<Self::State> {
1379 components.component_id::<T>()
1380 }
1381
1382 fn matches_component_set(
1383 &state: &ComponentId,
1384 set_contains_id: &impl Fn(ComponentId) -> bool,
1385 ) -> bool {
1386 set_contains_id(state)
1387 }
1388}
1389
1390unsafe impl<'__w, T: Component> QueryData for Ref<'__w, T> {
1392 const IS_READ_ONLY: bool = true;
1393 type ReadOnly = Self;
1394 type Item<'w> = Ref<'w, T>;
1395
1396 fn shrink<'wlong: 'wshort, 'wshort>(item: Ref<'wlong, T>) -> Ref<'wshort, T> {
1397 item
1398 }
1399
1400 #[inline(always)]
1401 unsafe fn fetch<'w>(
1402 fetch: &mut Self::Fetch<'w>,
1403 entity: Entity,
1404 table_row: TableRow,
1405 ) -> Self::Item<'w> {
1406 fetch.components.extract(
1407 |table| {
1408 let (table_components, added_ticks, changed_ticks, callers) =
1410 unsafe { table.debug_checked_unwrap() };
1411
1412 let component = unsafe { table_components.get(table_row.as_usize()) };
1414 let added = unsafe { added_ticks.get(table_row.as_usize()) };
1416 let changed = unsafe { changed_ticks.get(table_row.as_usize()) };
1418 let caller = callers.map(|callers| unsafe { callers.get(table_row.as_usize()) });
1420
1421 Ref {
1422 value: component.deref(),
1423 ticks: Ticks {
1424 added: added.deref(),
1425 changed: changed.deref(),
1426 this_run: fetch.this_run,
1427 last_run: fetch.last_run,
1428 },
1429 changed_by: caller.map(|caller| caller.deref()),
1430 }
1431 },
1432 |sparse_set| {
1433 let (component, ticks, caller) = unsafe {
1435 sparse_set
1436 .debug_checked_unwrap()
1437 .get_with_ticks(entity)
1438 .debug_checked_unwrap()
1439 };
1440
1441 Ref {
1442 value: component.deref(),
1443 ticks: Ticks::from_tick_cells(ticks, fetch.last_run, fetch.this_run),
1444 changed_by: caller.map(|caller| caller.deref()),
1445 }
1446 },
1447 )
1448 }
1449}
1450
1451unsafe impl<'__w, T: Component> ReadOnlyQueryData for Ref<'__w, T> {}
1453
1454pub struct WriteFetch<'w, T: Component> {
1456 components: StorageSwitch<
1457 T,
1458 Option<(
1460 ThinSlicePtr<'w, UnsafeCell<T>>,
1461 ThinSlicePtr<'w, UnsafeCell<Tick>>,
1462 ThinSlicePtr<'w, UnsafeCell<Tick>>,
1463 MaybeLocation<ThinSlicePtr<'w, UnsafeCell<&'static Location<'static>>>>,
1464 )>,
1465 Option<&'w ComponentSparseSet>,
1468 >,
1469 last_run: Tick,
1470 this_run: Tick,
1471}
1472
1473impl<T: Component> Clone for WriteFetch<'_, T> {
1474 fn clone(&self) -> Self {
1475 *self
1476 }
1477}
1478impl<T: Component> Copy for WriteFetch<'_, T> {}
1479
1480unsafe impl<'__w, T: Component> WorldQuery for &'__w mut T {
1486 type Fetch<'w> = WriteFetch<'w, T>;
1487 type State = ComponentId;
1488
1489 fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
1490 fetch
1491 }
1492
1493 #[inline]
1494 unsafe fn init_fetch<'w>(
1495 world: UnsafeWorldCell<'w>,
1496 &component_id: &ComponentId,
1497 last_run: Tick,
1498 this_run: Tick,
1499 ) -> WriteFetch<'w, T> {
1500 WriteFetch {
1501 components: StorageSwitch::new(
1502 || None,
1503 || {
1504 unsafe { world.storages().sparse_sets.get(component_id) }
1509 },
1510 ),
1511 last_run,
1512 this_run,
1513 }
1514 }
1515
1516 const IS_DENSE: bool = {
1517 match T::STORAGE_TYPE {
1518 StorageType::Table => true,
1519 StorageType::SparseSet => false,
1520 }
1521 };
1522
1523 #[inline]
1524 unsafe fn set_archetype<'w>(
1525 fetch: &mut WriteFetch<'w, T>,
1526 component_id: &ComponentId,
1527 _archetype: &'w Archetype,
1528 table: &'w Table,
1529 ) {
1530 if Self::IS_DENSE {
1531 unsafe {
1533 Self::set_table(fetch, component_id, table);
1534 }
1535 }
1536 }
1537
1538 #[inline]
1539 unsafe fn set_table<'w>(
1540 fetch: &mut WriteFetch<'w, T>,
1541 &component_id: &ComponentId,
1542 table: &'w Table,
1543 ) {
1544 let column = table.get_column(component_id).debug_checked_unwrap();
1545 let table_data = Some((
1546 column.get_data_slice(table.entity_count()).into(),
1547 column.get_added_ticks_slice(table.entity_count()).into(),
1548 column.get_changed_ticks_slice(table.entity_count()).into(),
1549 column
1550 .get_changed_by_slice(table.entity_count())
1551 .map(Into::into),
1552 ));
1553 unsafe { fetch.components.set_table(table_data) };
1555 }
1556
1557 fn update_component_access(
1558 &component_id: &ComponentId,
1559 access: &mut FilteredAccess<ComponentId>,
1560 ) {
1561 assert!(
1562 !access.access().has_component_read(component_id),
1563 "&mut {} conflicts with a previous access in this query. Mutable component access must be unique.",
1564 core::any::type_name::<T>(),
1565 );
1566 access.add_component_write(component_id);
1567 }
1568
1569 fn init_state(world: &mut World) -> ComponentId {
1570 world.register_component::<T>()
1571 }
1572
1573 fn get_state(components: &Components) -> Option<Self::State> {
1574 components.component_id::<T>()
1575 }
1576
1577 fn matches_component_set(
1578 &state: &ComponentId,
1579 set_contains_id: &impl Fn(ComponentId) -> bool,
1580 ) -> bool {
1581 set_contains_id(state)
1582 }
1583}
1584
1585unsafe impl<'__w, T: Component<Mutability = Mutable>> QueryData for &'__w mut T {
1587 const IS_READ_ONLY: bool = false;
1588 type ReadOnly = &'__w T;
1589 type Item<'w> = Mut<'w, T>;
1590
1591 fn shrink<'wlong: 'wshort, 'wshort>(item: Mut<'wlong, T>) -> Mut<'wshort, T> {
1592 item
1593 }
1594
1595 #[inline(always)]
1596 unsafe fn fetch<'w>(
1597 fetch: &mut Self::Fetch<'w>,
1598 entity: Entity,
1599 table_row: TableRow,
1600 ) -> Self::Item<'w> {
1601 fetch.components.extract(
1602 |table| {
1603 let (table_components, added_ticks, changed_ticks, callers) =
1605 unsafe { table.debug_checked_unwrap() };
1606
1607 let component = unsafe { table_components.get(table_row.as_usize()) };
1609 let added = unsafe { added_ticks.get(table_row.as_usize()) };
1611 let changed = unsafe { changed_ticks.get(table_row.as_usize()) };
1613 let caller = callers.map(|callers| unsafe { callers.get(table_row.as_usize()) });
1615
1616 Mut {
1617 value: component.deref_mut(),
1618 ticks: TicksMut {
1619 added: added.deref_mut(),
1620 changed: changed.deref_mut(),
1621 this_run: fetch.this_run,
1622 last_run: fetch.last_run,
1623 },
1624 changed_by: caller.map(|caller| caller.deref_mut()),
1625 }
1626 },
1627 |sparse_set| {
1628 let (component, ticks, caller) = unsafe {
1630 sparse_set
1631 .debug_checked_unwrap()
1632 .get_with_ticks(entity)
1633 .debug_checked_unwrap()
1634 };
1635
1636 Mut {
1637 value: component.assert_unique().deref_mut(),
1638 ticks: TicksMut::from_tick_cells(ticks, fetch.last_run, fetch.this_run),
1639 changed_by: caller.map(|caller| caller.deref_mut()),
1640 }
1641 },
1642 )
1643 }
1644}
1645
1646unsafe impl<'__w, T: Component> WorldQuery for Mut<'__w, T> {
1656 type Fetch<'w> = WriteFetch<'w, T>;
1657 type State = ComponentId;
1658
1659 fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
1660 fetch
1661 }
1662
1663 #[inline]
1664 unsafe fn init_fetch<'w>(
1666 world: UnsafeWorldCell<'w>,
1667 state: &ComponentId,
1668 last_run: Tick,
1669 this_run: Tick,
1670 ) -> WriteFetch<'w, T> {
1671 <&mut T as WorldQuery>::init_fetch(world, state, last_run, this_run)
1672 }
1673
1674 const IS_DENSE: bool = <&mut T as WorldQuery>::IS_DENSE;
1676
1677 #[inline]
1678 unsafe fn set_archetype<'w>(
1680 fetch: &mut WriteFetch<'w, T>,
1681 state: &ComponentId,
1682 archetype: &'w Archetype,
1683 table: &'w Table,
1684 ) {
1685 <&mut T as WorldQuery>::set_archetype(fetch, state, archetype, table);
1686 }
1687
1688 #[inline]
1689 unsafe fn set_table<'w>(fetch: &mut WriteFetch<'w, T>, state: &ComponentId, table: &'w Table) {
1691 <&mut T as WorldQuery>::set_table(fetch, state, table);
1692 }
1693
1694 fn update_component_access(
1696 &component_id: &ComponentId,
1697 access: &mut FilteredAccess<ComponentId>,
1698 ) {
1699 assert!(
1702 !access.access().has_component_read(component_id),
1703 "Mut<{}> conflicts with a previous access in this query. Mutable component access mut be unique.",
1704 core::any::type_name::<T>(),
1705 );
1706 access.add_component_write(component_id);
1707 }
1708
1709 fn init_state(world: &mut World) -> ComponentId {
1711 <&mut T as WorldQuery>::init_state(world)
1712 }
1713
1714 fn get_state(components: &Components) -> Option<ComponentId> {
1716 <&mut T as WorldQuery>::get_state(components)
1717 }
1718
1719 fn matches_component_set(
1721 state: &ComponentId,
1722 set_contains_id: &impl Fn(ComponentId) -> bool,
1723 ) -> bool {
1724 <&mut T as WorldQuery>::matches_component_set(state, set_contains_id)
1725 }
1726}
1727
1728unsafe impl<'__w, T: Component<Mutability = Mutable>> QueryData for Mut<'__w, T> {
1730 const IS_READ_ONLY: bool = false;
1731 type ReadOnly = Ref<'__w, T>;
1732 type Item<'w> = Mut<'w, T>;
1733
1734 fn shrink<'wlong: 'wshort, 'wshort>(item: Mut<'wlong, T>) -> Mut<'wshort, T> {
1736 <&mut T as QueryData>::shrink(item)
1737 }
1738
1739 #[inline(always)]
1740 unsafe fn fetch<'w>(
1742 fetch: &mut Self::Fetch<'w>,
1745 entity: Entity,
1746 table_row: TableRow,
1747 ) -> Mut<'w, T> {
1748 <&mut T as QueryData>::fetch(fetch, entity, table_row)
1749 }
1750}
1751
1752#[doc(hidden)]
1753pub struct OptionFetch<'w, T: WorldQuery> {
1754 fetch: T::Fetch<'w>,
1755 matches: bool,
1756}
1757
1758impl<T: WorldQuery> Clone for OptionFetch<'_, T> {
1759 fn clone(&self) -> Self {
1760 Self {
1761 fetch: self.fetch.clone(),
1762 matches: self.matches,
1763 }
1764 }
1765}
1766
1767unsafe impl<T: WorldQuery> WorldQuery for Option<T> {
1772 type Fetch<'w> = OptionFetch<'w, T>;
1773 type State = T::State;
1774
1775 fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
1776 OptionFetch {
1777 fetch: T::shrink_fetch(fetch.fetch),
1778 matches: fetch.matches,
1779 }
1780 }
1781
1782 #[inline]
1783 unsafe fn init_fetch<'w>(
1784 world: UnsafeWorldCell<'w>,
1785 state: &T::State,
1786 last_run: Tick,
1787 this_run: Tick,
1788 ) -> OptionFetch<'w, T> {
1789 OptionFetch {
1790 fetch: unsafe { T::init_fetch(world, state, last_run, this_run) },
1792 matches: false,
1793 }
1794 }
1795
1796 const IS_DENSE: bool = T::IS_DENSE;
1797
1798 #[inline]
1799 unsafe fn set_archetype<'w>(
1800 fetch: &mut OptionFetch<'w, T>,
1801 state: &T::State,
1802 archetype: &'w Archetype,
1803 table: &'w Table,
1804 ) {
1805 fetch.matches = T::matches_component_set(state, &|id| archetype.contains(id));
1806 if fetch.matches {
1807 unsafe {
1809 T::set_archetype(&mut fetch.fetch, state, archetype, table);
1810 }
1811 }
1812 }
1813
1814 #[inline]
1815 unsafe fn set_table<'w>(fetch: &mut OptionFetch<'w, T>, state: &T::State, table: &'w Table) {
1816 fetch.matches = T::matches_component_set(state, &|id| table.has_column(id));
1817 if fetch.matches {
1818 unsafe {
1820 T::set_table(&mut fetch.fetch, state, table);
1821 }
1822 }
1823 }
1824
1825 fn update_component_access(state: &T::State, access: &mut FilteredAccess<ComponentId>) {
1826 let mut intermediate = access.clone();
1836 T::update_component_access(state, &mut intermediate);
1837 access.extend_access(&intermediate);
1838 }
1839
1840 fn init_state(world: &mut World) -> T::State {
1841 T::init_state(world)
1842 }
1843
1844 fn get_state(components: &Components) -> Option<Self::State> {
1845 T::get_state(components)
1846 }
1847
1848 fn matches_component_set(
1849 _state: &T::State,
1850 _set_contains_id: &impl Fn(ComponentId) -> bool,
1851 ) -> bool {
1852 true
1853 }
1854}
1855
1856unsafe impl<T: QueryData> QueryData for Option<T> {
1858 const IS_READ_ONLY: bool = T::IS_READ_ONLY;
1859 type ReadOnly = Option<T::ReadOnly>;
1860 type Item<'w> = Option<T::Item<'w>>;
1861
1862 fn shrink<'wlong: 'wshort, 'wshort>(item: Self::Item<'wlong>) -> Self::Item<'wshort> {
1863 item.map(T::shrink)
1864 }
1865
1866 #[inline(always)]
1867 unsafe fn fetch<'w>(
1868 fetch: &mut Self::Fetch<'w>,
1869 entity: Entity,
1870 table_row: TableRow,
1871 ) -> Self::Item<'w> {
1872 fetch
1873 .matches
1874 .then(|| unsafe { T::fetch(&mut fetch.fetch, entity, table_row) })
1876 }
1877}
1878
1879unsafe impl<T: ReadOnlyQueryData> ReadOnlyQueryData for Option<T> {}
1881
1882pub struct Has<T>(PhantomData<T>);
1946
1947impl<T> core::fmt::Debug for Has<T> {
1948 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> {
1949 write!(f, "Has<{}>", core::any::type_name::<T>())
1950 }
1951}
1952
1953unsafe impl<T: Component> WorldQuery for Has<T> {
1957 type Fetch<'w> = bool;
1958 type State = ComponentId;
1959
1960 fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
1961 fetch
1962 }
1963
1964 #[inline]
1965 unsafe fn init_fetch<'w>(
1966 _world: UnsafeWorldCell<'w>,
1967 _state: &Self::State,
1968 _last_run: Tick,
1969 _this_run: Tick,
1970 ) -> Self::Fetch<'w> {
1971 false
1972 }
1973
1974 const IS_DENSE: bool = {
1975 match T::STORAGE_TYPE {
1976 StorageType::Table => true,
1977 StorageType::SparseSet => false,
1978 }
1979 };
1980
1981 #[inline]
1982 unsafe fn set_archetype<'w>(
1983 fetch: &mut Self::Fetch<'w>,
1984 state: &Self::State,
1985 archetype: &'w Archetype,
1986 _table: &Table,
1987 ) {
1988 *fetch = archetype.contains(*state);
1989 }
1990
1991 #[inline]
1992 unsafe fn set_table<'w>(fetch: &mut Self::Fetch<'w>, state: &Self::State, table: &'w Table) {
1993 *fetch = table.has_column(*state);
1994 }
1995
1996 fn update_component_access(
1997 &component_id: &Self::State,
1998 access: &mut FilteredAccess<ComponentId>,
1999 ) {
2000 access.access_mut().add_archetypal(component_id);
2001 }
2002
2003 fn init_state(world: &mut World) -> ComponentId {
2004 world.register_component::<T>()
2005 }
2006
2007 fn get_state(components: &Components) -> Option<Self::State> {
2008 components.component_id::<T>()
2009 }
2010
2011 fn matches_component_set(
2012 _state: &Self::State,
2013 _set_contains_id: &impl Fn(ComponentId) -> bool,
2014 ) -> bool {
2015 true
2017 }
2018}
2019
2020unsafe impl<T: Component> QueryData for Has<T> {
2022 const IS_READ_ONLY: bool = true;
2023 type ReadOnly = Self;
2024 type Item<'w> = bool;
2025
2026 fn shrink<'wlong: 'wshort, 'wshort>(item: Self::Item<'wlong>) -> Self::Item<'wshort> {
2027 item
2028 }
2029
2030 #[inline(always)]
2031 unsafe fn fetch<'w>(
2032 fetch: &mut Self::Fetch<'w>,
2033 _entity: Entity,
2034 _table_row: TableRow,
2035 ) -> Self::Item<'w> {
2036 *fetch
2037 }
2038}
2039
2040unsafe impl<T: Component> ReadOnlyQueryData for Has<T> {}
2042
2043pub struct AnyOf<T>(PhantomData<T>);
2049
2050macro_rules! impl_tuple_query_data {
2051 ($(#[$meta:meta])* $(($name: ident, $state: ident)),*) => {
2052 #[expect(
2053 clippy::allow_attributes,
2054 reason = "This is a tuple-related macro; as such the lints below may not always apply."
2055 )]
2056 #[allow(
2057 non_snake_case,
2058 reason = "The names of some variables are provided by the macro's caller, not by us."
2059 )]
2060 #[allow(
2061 unused_variables,
2062 reason = "Zero-length tuples won't use any of the parameters."
2063 )]
2064 #[allow(
2065 clippy::unused_unit,
2066 reason = "Zero-length tuples will generate some function bodies equivalent to `()`; however, this macro is meant for all applicable tuples, and as such it makes no sense to rewrite it just for that case."
2067 )]
2068 $(#[$meta])*
2069 unsafe impl<$($name: QueryData),*> QueryData for ($($name,)*) {
2071 const IS_READ_ONLY: bool = true $(&& $name::IS_READ_ONLY)*;
2072 type ReadOnly = ($($name::ReadOnly,)*);
2073 type Item<'w> = ($($name::Item<'w>,)*);
2074
2075 fn shrink<'wlong: 'wshort, 'wshort>(item: Self::Item<'wlong>) -> Self::Item<'wshort> {
2076 let ($($name,)*) = item;
2077 ($(
2078 $name::shrink($name),
2079 )*)
2080 }
2081
2082 #[inline(always)]
2083 unsafe fn fetch<'w>(
2084 fetch: &mut Self::Fetch<'w>,
2085 entity: Entity,
2086 table_row: TableRow
2087 ) -> Self::Item<'w> {
2088 let ($($name,)*) = fetch;
2089 ($(unsafe { $name::fetch($name, entity, table_row) },)*)
2091 }
2092 }
2093
2094 $(#[$meta])*
2095 unsafe impl<$($name: ReadOnlyQueryData),*> ReadOnlyQueryData for ($($name,)*) {}
2097
2098 };
2099}
2100
2101macro_rules! impl_anytuple_fetch {
2102 ($(#[$meta:meta])* $(($name: ident, $state: ident)),*) => {
2103 $(#[$meta])*
2104 #[expect(
2105 clippy::allow_attributes,
2106 reason = "This is a tuple-related macro; as such the lints below may not always apply."
2107 )]
2108 #[allow(
2109 non_snake_case,
2110 reason = "The names of some variables are provided by the macro's caller, not by us."
2111 )]
2112 #[allow(
2113 unused_variables,
2114 reason = "Zero-length tuples won't use any of the parameters."
2115 )]
2116 #[allow(
2117 clippy::unused_unit,
2118 reason = "Zero-length tuples will generate some function bodies equivalent to `()`; however, this macro is meant for all applicable tuples, and as such it makes no sense to rewrite it just for that case."
2119 )]
2120 unsafe impl<$($name: WorldQuery),*> WorldQuery for AnyOf<($($name,)*)> {
2126 type Fetch<'w> = ($(($name::Fetch<'w>, bool),)*);
2127 type State = ($($name::State,)*);
2128
2129 fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
2130 let ($($name,)*) = fetch;
2131 ($(
2132 ($name::shrink_fetch($name.0), $name.1),
2133 )*)
2134 }
2135
2136 #[inline]
2137 unsafe fn init_fetch<'w>(_world: UnsafeWorldCell<'w>, state: &Self::State, _last_run: Tick, _this_run: Tick) -> Self::Fetch<'w> {
2138 let ($($name,)*) = state;
2139 ($(( unsafe { $name::init_fetch(_world, $name, _last_run, _this_run) }, false),)*)
2141 }
2142
2143 const IS_DENSE: bool = true $(&& $name::IS_DENSE)*;
2144
2145 #[inline]
2146 unsafe fn set_archetype<'w>(
2147 _fetch: &mut Self::Fetch<'w>,
2148 _state: &Self::State,
2149 _archetype: &'w Archetype,
2150 _table: &'w Table
2151 ) {
2152 let ($($name,)*) = _fetch;
2153 let ($($state,)*) = _state;
2154 $(
2155 $name.1 = $name::matches_component_set($state, &|id| _archetype.contains(id));
2156 if $name.1 {
2157 unsafe { $name::set_archetype(&mut $name.0, $state, _archetype, _table); }
2159 }
2160 )*
2161 }
2162
2163 #[inline]
2164 unsafe fn set_table<'w>(_fetch: &mut Self::Fetch<'w>, _state: &Self::State, _table: &'w Table) {
2165 let ($($name,)*) = _fetch;
2166 let ($($state,)*) = _state;
2167 $(
2168 $name.1 = $name::matches_component_set($state, &|id| _table.has_column(id));
2169 if $name.1 {
2170 unsafe { $name::set_table(&mut $name.0, $state, _table); }
2172 }
2173 )*
2174 }
2175
2176 fn update_component_access(state: &Self::State, access: &mut FilteredAccess<ComponentId>) {
2177 let ($($name,)*) = state;
2179
2180 let mut _new_access = FilteredAccess::matches_nothing();
2181
2182 $(
2183 let mut intermediate = access.clone();
2187 $name::update_component_access($name, &mut intermediate);
2188 _new_access.append_or(&intermediate);
2189 )*
2190
2191 access.filter_sets = _new_access.filter_sets;
2193
2194 <($(Option<$name>,)*)>::update_component_access(state, access);
2200
2201 }
2202 fn init_state(world: &mut World) -> Self::State {
2203 ($($name::init_state(world),)*)
2204 }
2205 fn get_state(components: &Components) -> Option<Self::State> {
2206 Some(($($name::get_state(components)?,)*))
2207 }
2208
2209 fn matches_component_set(_state: &Self::State, _set_contains_id: &impl Fn(ComponentId) -> bool) -> bool {
2210 let ($($name,)*) = _state;
2211 false $(|| $name::matches_component_set($name, _set_contains_id))*
2212 }
2213 }
2214
2215 #[expect(
2216 clippy::allow_attributes,
2217 reason = "This is a tuple-related macro; as such the lints below may not always apply."
2218 )]
2219 #[allow(
2220 non_snake_case,
2221 reason = "The names of some variables are provided by the macro's caller, not by us."
2222 )]
2223 #[allow(
2224 unused_variables,
2225 reason = "Zero-length tuples won't use any of the parameters."
2226 )]
2227 #[allow(
2228 clippy::unused_unit,
2229 reason = "Zero-length tuples will generate some function bodies equivalent to `()`; however, this macro is meant for all applicable tuples, and as such it makes no sense to rewrite it just for that case."
2230 )]
2231 $(#[$meta])*
2232 unsafe impl<$($name: QueryData),*> QueryData for AnyOf<($($name,)*)> {
2234 const IS_READ_ONLY: bool = true $(&& $name::IS_READ_ONLY)*;
2235 type ReadOnly = AnyOf<($($name::ReadOnly,)*)>;
2236 type Item<'w> = ($(Option<$name::Item<'w>>,)*);
2237
2238 fn shrink<'wlong: 'wshort, 'wshort>(item: Self::Item<'wlong>) -> Self::Item<'wshort> {
2239 let ($($name,)*) = item;
2240 ($(
2241 $name.map($name::shrink),
2242 )*)
2243 }
2244
2245 #[inline(always)]
2246 unsafe fn fetch<'w>(
2247 _fetch: &mut Self::Fetch<'w>,
2248 _entity: Entity,
2249 _table_row: TableRow
2250 ) -> Self::Item<'w> {
2251 let ($($name,)*) = _fetch;
2252 ($(
2253 $name.1.then(|| unsafe { $name::fetch(&mut $name.0, _entity, _table_row) }),
2255 )*)
2256 }
2257 }
2258
2259 $(#[$meta])*
2260 unsafe impl<$($name: ReadOnlyQueryData),*> ReadOnlyQueryData for AnyOf<($($name,)*)> {}
2262 };
2263}
2264
2265all_tuples!(
2266 #[doc(fake_variadic)]
2267 impl_tuple_query_data,
2268 0,
2269 15,
2270 F,
2271 S
2272);
2273all_tuples!(
2274 #[doc(fake_variadic)]
2275 impl_anytuple_fetch,
2276 0,
2277 15,
2278 F,
2279 S
2280);
2281
2282pub(crate) struct NopWorldQuery<D: QueryData>(PhantomData<D>);
2286
2287unsafe impl<D: QueryData> WorldQuery for NopWorldQuery<D> {
2291 type Fetch<'w> = ();
2292 type State = D::State;
2293
2294 fn shrink_fetch<'wlong: 'wshort, 'wshort>(_: ()) {}
2295
2296 #[inline(always)]
2297 unsafe fn init_fetch(
2298 _world: UnsafeWorldCell,
2299 _state: &D::State,
2300 _last_run: Tick,
2301 _this_run: Tick,
2302 ) {
2303 }
2304
2305 const IS_DENSE: bool = D::IS_DENSE;
2306
2307 #[inline(always)]
2308 unsafe fn set_archetype(
2309 _fetch: &mut (),
2310 _state: &D::State,
2311 _archetype: &Archetype,
2312 _tables: &Table,
2313 ) {
2314 }
2315
2316 #[inline(always)]
2317 unsafe fn set_table<'w>(_fetch: &mut (), _state: &D::State, _table: &Table) {}
2318
2319 fn update_component_access(_state: &D::State, _access: &mut FilteredAccess<ComponentId>) {}
2320
2321 fn init_state(world: &mut World) -> Self::State {
2322 D::init_state(world)
2323 }
2324
2325 fn get_state(components: &Components) -> Option<Self::State> {
2326 D::get_state(components)
2327 }
2328
2329 fn matches_component_set(
2330 state: &Self::State,
2331 set_contains_id: &impl Fn(ComponentId) -> bool,
2332 ) -> bool {
2333 D::matches_component_set(state, set_contains_id)
2334 }
2335}
2336
2337unsafe impl<D: QueryData> QueryData for NopWorldQuery<D> {
2339 const IS_READ_ONLY: bool = true;
2340 type ReadOnly = Self;
2341 type Item<'w> = ();
2342
2343 fn shrink<'wlong: 'wshort, 'wshort>(_: ()) {}
2344
2345 #[inline(always)]
2346 unsafe fn fetch<'w>(
2347 _fetch: &mut Self::Fetch<'w>,
2348 _entity: Entity,
2349 _table_row: TableRow,
2350 ) -> Self::Item<'w> {
2351 }
2352}
2353
2354unsafe impl<D: QueryData> ReadOnlyQueryData for NopWorldQuery<D> {}
2356
2357unsafe impl<T: ?Sized> WorldQuery for PhantomData<T> {
2361 type Fetch<'a> = ();
2362
2363 type State = ();
2364
2365 fn shrink_fetch<'wlong: 'wshort, 'wshort>(_fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
2366 }
2367
2368 unsafe fn init_fetch<'w>(
2369 _world: UnsafeWorldCell<'w>,
2370 _state: &Self::State,
2371 _last_run: Tick,
2372 _this_run: Tick,
2373 ) -> Self::Fetch<'w> {
2374 }
2375
2376 const IS_DENSE: bool = true;
2379
2380 unsafe fn set_archetype<'w>(
2381 _fetch: &mut Self::Fetch<'w>,
2382 _state: &Self::State,
2383 _archetype: &'w Archetype,
2384 _table: &'w Table,
2385 ) {
2386 }
2387
2388 unsafe fn set_table<'w>(_fetch: &mut Self::Fetch<'w>, _state: &Self::State, _table: &'w Table) {
2389 }
2390
2391 fn update_component_access(_state: &Self::State, _access: &mut FilteredAccess<ComponentId>) {}
2392
2393 fn init_state(_world: &mut World) -> Self::State {}
2394
2395 fn get_state(_components: &Components) -> Option<Self::State> {
2396 Some(())
2397 }
2398
2399 fn matches_component_set(
2400 _state: &Self::State,
2401 _set_contains_id: &impl Fn(ComponentId) -> bool,
2402 ) -> bool {
2403 true
2404 }
2405}
2406
2407unsafe impl<T: ?Sized> QueryData for PhantomData<T> {
2409 const IS_READ_ONLY: bool = true;
2410 type ReadOnly = Self;
2411 type Item<'a> = ();
2412
2413 fn shrink<'wlong: 'wshort, 'wshort>(_item: Self::Item<'wlong>) -> Self::Item<'wshort> {}
2414
2415 unsafe fn fetch<'w>(
2416 _fetch: &mut Self::Fetch<'w>,
2417 _entity: Entity,
2418 _table_row: TableRow,
2419 ) -> Self::Item<'w> {
2420 }
2421}
2422
2423unsafe impl<T: ?Sized> ReadOnlyQueryData for PhantomData<T> {}
2425
2426pub(super) union StorageSwitch<C: Component, T: Copy, S: Copy> {
2429 table: T,
2431 sparse_set: S,
2433 _marker: PhantomData<C>,
2434}
2435
2436impl<C: Component, T: Copy, S: Copy> StorageSwitch<C, T, S> {
2437 pub fn new(table: impl FnOnce() -> T, sparse_set: impl FnOnce() -> S) -> Self {
2440 match C::STORAGE_TYPE {
2441 StorageType::Table => Self { table: table() },
2442 StorageType::SparseSet => Self {
2443 sparse_set: sparse_set(),
2444 },
2445 }
2446 }
2447
2448 #[inline]
2458 pub unsafe fn set_table(&mut self, table: T) {
2459 match C::STORAGE_TYPE {
2460 StorageType::Table => self.table = table,
2461 _ => {
2462 #[cfg(debug_assertions)]
2463 unreachable!();
2464 #[cfg(not(debug_assertions))]
2465 core::hint::unreachable_unchecked()
2466 }
2467 }
2468 }
2469
2470 pub fn extract<R>(&self, table: impl FnOnce(T) -> R, sparse_set: impl FnOnce(S) -> R) -> R {
2473 match C::STORAGE_TYPE {
2474 StorageType::Table => table(
2475 unsafe { self.table },
2477 ),
2478 StorageType::SparseSet => sparse_set(
2479 unsafe { self.sparse_set },
2481 ),
2482 }
2483 }
2484}
2485
2486impl<C: Component, T: Copy, S: Copy> Clone for StorageSwitch<C, T, S> {
2487 fn clone(&self) -> Self {
2488 *self
2489 }
2490}
2491
2492impl<C: Component, T: Copy, S: Copy> Copy for StorageSwitch<C, T, S> {}
2493
2494#[cfg(test)]
2495mod tests {
2496 use bevy_ecs_macros::QueryData;
2497
2498 use super::*;
2499 use crate::system::{assert_is_system, Query};
2500
2501 #[derive(Component)]
2502 pub struct A;
2503
2504 #[derive(Component)]
2505 pub struct B;
2506
2507 #[test]
2509 fn world_query_struct_variants() {
2510 #[derive(QueryData)]
2511 pub struct NamedQuery {
2512 id: Entity,
2513 a: &'static A,
2514 }
2515
2516 #[derive(QueryData)]
2517 pub struct TupleQuery(&'static A, &'static B);
2518
2519 #[derive(QueryData)]
2520 pub struct UnitQuery;
2521
2522 fn my_system(_: Query<(NamedQuery, TupleQuery, UnitQuery)>) {}
2523
2524 assert_is_system(my_system);
2525 }
2526
2527 #[test]
2529 fn world_query_phantom_data() {
2530 #[derive(QueryData)]
2531 pub struct IgnoredQuery<Marker> {
2532 id: Entity,
2533 _marker: PhantomData<Marker>,
2534 }
2535
2536 fn ignored_system(_: Query<IgnoredQuery<()>>) {}
2537
2538 assert_is_system(ignored_system);
2539 }
2540
2541 #[test]
2544 fn read_only_field_visibility() {
2545 mod private {
2546 use super::*;
2547
2548 #[derive(QueryData)]
2549 #[query_data(mutable)]
2550 pub struct D {
2551 pub a: &'static mut A,
2552 }
2553 }
2554
2555 let _ = private::DReadOnly { a: &A };
2556
2557 fn my_system(query: Query<private::D>) {
2558 for q in &query {
2559 let _ = &q.a;
2560 }
2561 }
2562
2563 assert_is_system(my_system);
2564 }
2565
2566 #[test]
2570 fn world_query_metadata_collision() {
2571 #[derive(QueryData)]
2574 pub struct Client<S: ClientState> {
2575 pub state: &'static S,
2576 pub fetch: &'static ClientFetch,
2577 }
2578
2579 pub trait ClientState: Component {}
2580
2581 #[derive(Component)]
2582 pub struct ClientFetch;
2583
2584 #[derive(Component)]
2585 pub struct C;
2586
2587 impl ClientState for C {}
2588
2589 fn client_system(_: Query<Client<C>>) {}
2590
2591 assert_is_system(client_system);
2592 }
2593}