1use crate::{
2 archetype::{Archetype, Archetypes},
3 bundle::Bundle,
4 change_detection::{ComponentTicksMut, ComponentTicksRef, MaybeLocation, Tick},
5 component::{Component, ComponentId, Components, Mutable, StorageType},
6 entity::{Entities, Entity, EntityLocation},
7 query::{
8 access_iter::{EcsAccessLevel, EcsAccessType},
9 Access, DebugCheckedUnwrap, FilteredAccess, WorldQuery,
10 },
11 storage::{ComponentSparseSet, Table, TableRow},
12 world::{
13 unsafe_world_cell::UnsafeWorldCell, EntityMut, EntityMutExcept, EntityRef, EntityRefExcept,
14 FilteredEntityMut, FilteredEntityRef, Mut, Ref, World,
15 },
16};
17use bevy_ptr::{ThinSlicePtr, UnsafeCellDeref};
18use bevy_utils::prelude::DebugName;
19use core::{cell::UnsafeCell, iter, marker::PhantomData, panic::Location};
20use variadics_please::all_tuples;
21
22#[diagnostic::on_unimplemented(
282 message = "`{Self}` is not valid to request as data in a `Query`",
283 label = "invalid `Query` data",
284 note = "if `{Self}` is a component type, try using `&{Self}` or `&mut {Self}`"
285)]
286pub unsafe trait QueryData: WorldQuery {
287 const IS_READ_ONLY: bool;
289
290 const IS_ARCHETYPAL: bool;
298
299 type ReadOnly: ReadOnlyQueryData<State = <Self as WorldQuery>::State>;
301
302 type Item<'w, 's>;
306
307 fn shrink<'wlong: 'wshort, 'wshort, 's>(
309 item: Self::Item<'wlong, 's>,
310 ) -> Self::Item<'wshort, 's>;
311
312 fn provide_extra_access(
322 _state: &mut Self::State,
323 _access: &mut Access,
324 _available_access: &Access,
325 ) {
326 }
327
328 unsafe fn fetch<'w, 's>(
343 state: &'s Self::State,
344 fetch: &mut Self::Fetch<'w>,
345 entity: Entity,
346 table_row: TableRow,
347 ) -> Option<Self::Item<'w, 's>>;
348
349 fn iter_access(state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>>;
353}
354
355pub unsafe trait ReadOnlyQueryData: QueryData<ReadOnly = Self> {}
361
362pub type QueryItem<'w, 's, Q> = <Q as QueryData>::Item<'w, 's>;
364pub type ROQueryItem<'w, 's, D> = QueryItem<'w, 's, <D as QueryData>::ReadOnly>;
366
367pub trait ReleaseStateQueryData: QueryData {
374 fn release_state<'w>(item: Self::Item<'w, '_>) -> Self::Item<'w, 'static>;
376}
377
378pub trait ArchetypeQueryData: QueryData {}
385
386unsafe impl WorldQuery for Entity {
390 type Fetch<'w> = ();
391 type State = ();
392
393 fn shrink_fetch<'wlong: 'wshort, 'wshort>(_: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {}
394
395 unsafe fn init_fetch<'w, 's>(
396 _world: UnsafeWorldCell<'w>,
397 _state: &'s Self::State,
398 _last_run: Tick,
399 _this_run: Tick,
400 ) -> Self::Fetch<'w> {
401 }
402
403 const IS_DENSE: bool = true;
404
405 #[inline]
406 unsafe fn set_archetype<'w, 's>(
407 _fetch: &mut Self::Fetch<'w>,
408 _state: &'s Self::State,
409 _archetype: &'w Archetype,
410 _table: &Table,
411 ) {
412 }
413
414 #[inline]
415 unsafe fn set_table<'w, 's>(
416 _fetch: &mut Self::Fetch<'w>,
417 _state: &'s Self::State,
418 _table: &'w Table,
419 ) {
420 }
421
422 fn update_component_access(_state: &Self::State, _access: &mut FilteredAccess) {}
423
424 fn init_state(_world: &mut World) {}
425
426 fn get_state(_components: &Components) -> Option<()> {
427 Some(())
428 }
429
430 fn matches_component_set(
431 _state: &Self::State,
432 _set_contains_id: &impl Fn(ComponentId) -> bool,
433 ) -> bool {
434 true
435 }
436}
437
438unsafe impl QueryData for Entity {
440 const IS_READ_ONLY: bool = true;
441 const IS_ARCHETYPAL: bool = true;
442 type ReadOnly = Self;
443
444 type Item<'w, 's> = Entity;
445
446 fn shrink<'wlong: 'wshort, 'wshort, 's>(
447 item: Self::Item<'wlong, 's>,
448 ) -> Self::Item<'wshort, 's> {
449 item
450 }
451
452 #[inline(always)]
453 unsafe fn fetch<'w, 's>(
454 _state: &'s Self::State,
455 _fetch: &mut Self::Fetch<'w>,
456 entity: Entity,
457 _table_row: TableRow,
458 ) -> Option<Self::Item<'w, 's>> {
459 Some(entity)
460 }
461
462 fn iter_access(_state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
463 iter::empty()
464 }
465}
466
467unsafe impl ReadOnlyQueryData for Entity {}
469
470impl ReleaseStateQueryData for Entity {
471 fn release_state<'w>(item: Self::Item<'w, '_>) -> Self::Item<'w, 'static> {
472 item
473 }
474}
475
476impl ArchetypeQueryData for Entity {}
477
478unsafe impl WorldQuery for EntityLocation {
482 type Fetch<'w> = &'w Entities;
483 type State = ();
484
485 fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
486 fetch
487 }
488
489 unsafe fn init_fetch<'w, 's>(
490 world: UnsafeWorldCell<'w>,
491 _state: &'s Self::State,
492 _last_run: Tick,
493 _this_run: Tick,
494 ) -> Self::Fetch<'w> {
495 world.entities()
496 }
497
498 const IS_DENSE: bool = true;
501
502 #[inline]
503 unsafe fn set_archetype<'w, 's>(
504 _fetch: &mut Self::Fetch<'w>,
505 _state: &'s Self::State,
506 _archetype: &'w Archetype,
507 _table: &Table,
508 ) {
509 }
510
511 #[inline]
512 unsafe fn set_table<'w, 's>(
513 _fetch: &mut Self::Fetch<'w>,
514 _state: &'s Self::State,
515 _table: &'w Table,
516 ) {
517 }
518
519 fn update_component_access(_state: &Self::State, _access: &mut FilteredAccess) {}
520
521 fn init_state(_world: &mut World) {}
522
523 fn get_state(_components: &Components) -> Option<()> {
524 Some(())
525 }
526
527 fn matches_component_set(
528 _state: &Self::State,
529 _set_contains_id: &impl Fn(ComponentId) -> bool,
530 ) -> bool {
531 true
532 }
533}
534
535unsafe impl QueryData for EntityLocation {
537 const IS_READ_ONLY: bool = true;
538 const IS_ARCHETYPAL: bool = true;
539 type ReadOnly = Self;
540 type Item<'w, 's> = EntityLocation;
541
542 fn shrink<'wlong: 'wshort, 'wshort, 's>(
543 item: Self::Item<'wlong, 's>,
544 ) -> Self::Item<'wshort, 's> {
545 item
546 }
547
548 #[inline(always)]
549 unsafe fn fetch<'w, 's>(
550 _state: &'s Self::State,
551 fetch: &mut Self::Fetch<'w>,
552 entity: Entity,
553 _table_row: TableRow,
554 ) -> Option<Self::Item<'w, 's>> {
555 Some(unsafe { fetch.get_spawned(entity).debug_checked_unwrap() })
557 }
558
559 fn iter_access(_state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
560 iter::empty()
561 }
562}
563
564unsafe impl ReadOnlyQueryData for EntityLocation {}
566
567impl ReleaseStateQueryData for EntityLocation {
568 fn release_state<'w>(item: Self::Item<'w, '_>) -> Self::Item<'w, 'static> {
569 item
570 }
571}
572
573impl ArchetypeQueryData for EntityLocation {}
574
575#[derive(Clone, Copy, Debug)]
612pub struct SpawnDetails {
613 spawned_by: MaybeLocation,
614 spawn_tick: Tick,
615 last_run: Tick,
616 this_run: Tick,
617}
618
619impl SpawnDetails {
620 pub fn is_spawned(self) -> bool {
623 self.spawn_tick.is_newer_than(self.last_run, self.this_run)
624 }
625
626 pub fn spawn_tick(self) -> Tick {
628 self.spawn_tick
629 }
630
631 pub fn spawned_by(self) -> MaybeLocation {
633 self.spawned_by
634 }
635}
636
637#[doc(hidden)]
638#[derive(Clone)]
639pub struct SpawnDetailsFetch<'w> {
640 entities: &'w Entities,
641 last_run: Tick,
642 this_run: Tick,
643}
644
645unsafe impl WorldQuery for SpawnDetails {
648 type Fetch<'w> = SpawnDetailsFetch<'w>;
649 type State = ();
650
651 fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
652 fetch
653 }
654
655 unsafe fn init_fetch<'w, 's>(
656 world: UnsafeWorldCell<'w>,
657 _state: &'s Self::State,
658 last_run: Tick,
659 this_run: Tick,
660 ) -> Self::Fetch<'w> {
661 SpawnDetailsFetch {
662 entities: world.entities(),
663 last_run,
664 this_run,
665 }
666 }
667
668 const IS_DENSE: bool = true;
669
670 #[inline]
671 unsafe fn set_archetype<'w, 's>(
672 _fetch: &mut Self::Fetch<'w>,
673 _state: &'s Self::State,
674 _archetype: &'w Archetype,
675 _table: &'w Table,
676 ) {
677 }
678
679 #[inline]
680 unsafe fn set_table<'w, 's>(
681 _fetch: &mut Self::Fetch<'w>,
682 _state: &'s Self::State,
683 _table: &'w Table,
684 ) {
685 }
686
687 fn update_component_access(_state: &Self::State, _access: &mut FilteredAccess) {}
688
689 fn init_state(_world: &mut World) {}
690
691 fn get_state(_components: &Components) -> Option<()> {
692 Some(())
693 }
694
695 fn matches_component_set(
696 _state: &Self::State,
697 _set_contains_id: &impl Fn(ComponentId) -> bool,
698 ) -> bool {
699 true
700 }
701}
702
703unsafe impl QueryData for SpawnDetails {
707 const IS_READ_ONLY: bool = true;
708 const IS_ARCHETYPAL: bool = true;
709 type ReadOnly = Self;
710 type Item<'w, 's> = Self;
711
712 fn shrink<'wlong: 'wshort, 'wshort, 's>(
713 item: Self::Item<'wlong, 's>,
714 ) -> Self::Item<'wshort, 's> {
715 item
716 }
717
718 #[inline(always)]
719 unsafe fn fetch<'w, 's>(
720 _state: &'s Self::State,
721 fetch: &mut Self::Fetch<'w>,
722 entity: Entity,
723 _table_row: TableRow,
724 ) -> Option<Self::Item<'w, 's>> {
725 let (spawned_by, spawn_tick) = unsafe {
727 fetch
728 .entities
729 .entity_get_spawned_or_despawned_unchecked(entity)
730 };
731 Some(Self {
732 spawned_by,
733 spawn_tick,
734 last_run: fetch.last_run,
735 this_run: fetch.this_run,
736 })
737 }
738
739 fn iter_access(_state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
740 iter::empty()
741 }
742}
743
744unsafe impl ReadOnlyQueryData for SpawnDetails {}
746
747impl ReleaseStateQueryData for SpawnDetails {
748 fn release_state<'w>(item: Self::Item<'w, '_>) -> Self::Item<'w, 'static> {
749 item
750 }
751}
752
753impl ArchetypeQueryData for SpawnDetails {}
754
755#[derive(Copy, Clone)]
758#[doc(hidden)]
759pub struct EntityFetch<'w> {
760 world: UnsafeWorldCell<'w>,
761 last_run: Tick,
762 this_run: Tick,
763}
764
765unsafe impl<'a> WorldQuery for EntityRef<'a> {
770 type Fetch<'w> = EntityFetch<'w>;
771 type State = ();
772
773 fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
774 fetch
775 }
776
777 unsafe fn init_fetch<'w, 's>(
778 world: UnsafeWorldCell<'w>,
779 _state: &'s Self::State,
780 last_run: Tick,
781 this_run: Tick,
782 ) -> Self::Fetch<'w> {
783 EntityFetch {
784 world,
785 last_run,
786 this_run,
787 }
788 }
789
790 const IS_DENSE: bool = true;
791
792 #[inline]
793 unsafe fn set_archetype<'w, 's>(
794 _fetch: &mut Self::Fetch<'w>,
795 _state: &'s Self::State,
796 _archetype: &'w Archetype,
797 _table: &Table,
798 ) {
799 }
800
801 #[inline]
802 unsafe fn set_table<'w, 's>(
803 _fetch: &mut Self::Fetch<'w>,
804 _state: &'s Self::State,
805 _table: &'w Table,
806 ) {
807 }
808
809 fn update_component_access(_state: &Self::State, access: &mut FilteredAccess) {
810 assert!(
811 !access.access().has_any_component_write(),
812 "EntityRef conflicts with a previous access in this query. Shared access cannot coincide with exclusive access.",
813 );
814 access.read_all_components();
815 }
816
817 fn init_state(_world: &mut World) {}
818
819 fn get_state(_components: &Components) -> Option<()> {
820 Some(())
821 }
822
823 fn matches_component_set(
824 _state: &Self::State,
825 _set_contains_id: &impl Fn(ComponentId) -> bool,
826 ) -> bool {
827 true
828 }
829}
830
831unsafe impl<'a> QueryData for EntityRef<'a> {
833 const IS_READ_ONLY: bool = true;
834 const IS_ARCHETYPAL: bool = true;
835 type ReadOnly = Self;
836 type Item<'w, 's> = EntityRef<'w>;
837
838 fn shrink<'wlong: 'wshort, 'wshort, 's>(
839 item: Self::Item<'wlong, 's>,
840 ) -> Self::Item<'wshort, 's> {
841 item
842 }
843
844 #[inline(always)]
845 unsafe fn fetch<'w, 's>(
846 _state: &'s Self::State,
847 fetch: &mut Self::Fetch<'w>,
848 entity: Entity,
849 _table_row: TableRow,
850 ) -> Option<Self::Item<'w, 's>> {
851 let cell = unsafe {
853 fetch
854 .world
855 .get_entity_with_ticks(entity, fetch.last_run, fetch.this_run)
856 .debug_checked_unwrap()
857 };
858 Some(unsafe { EntityRef::new(cell) })
860 }
861
862 fn iter_access(_state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
863 iter::once(EcsAccessType::Component(EcsAccessLevel::ReadAll))
864 }
865}
866
867unsafe impl ReadOnlyQueryData for EntityRef<'_> {}
869
870impl ReleaseStateQueryData for EntityRef<'_> {
871 fn release_state<'w>(item: Self::Item<'w, '_>) -> Self::Item<'w, 'static> {
872 item
873 }
874}
875
876impl ArchetypeQueryData for EntityRef<'_> {}
877
878unsafe impl<'a> WorldQuery for EntityMut<'a> {
880 type Fetch<'w> = EntityFetch<'w>;
881 type State = ();
882
883 fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
884 fetch
885 }
886
887 unsafe fn init_fetch<'w, 's>(
888 world: UnsafeWorldCell<'w>,
889 _state: &'s Self::State,
890 last_run: Tick,
891 this_run: Tick,
892 ) -> Self::Fetch<'w> {
893 EntityFetch {
894 world,
895 last_run,
896 this_run,
897 }
898 }
899
900 const IS_DENSE: bool = true;
901
902 #[inline]
903 unsafe fn set_archetype<'w, 's>(
904 _fetch: &mut Self::Fetch<'w>,
905 _state: &'s Self::State,
906 _archetype: &'w Archetype,
907 _table: &Table,
908 ) {
909 }
910
911 #[inline]
912 unsafe fn set_table<'w, 's>(
913 _fetch: &mut Self::Fetch<'w>,
914 _state: &'s Self::State,
915 _table: &'w Table,
916 ) {
917 }
918
919 fn update_component_access(_state: &Self::State, access: &mut FilteredAccess) {
920 assert!(
921 !access.access().has_any_component_read(),
922 "EntityMut conflicts with a previous access in this query. Exclusive access cannot coincide with any other accesses.",
923 );
924 access.write_all_components();
925 }
926
927 fn init_state(_world: &mut World) {}
928
929 fn get_state(_components: &Components) -> Option<()> {
930 Some(())
931 }
932
933 fn matches_component_set(
934 _state: &Self::State,
935 _set_contains_id: &impl Fn(ComponentId) -> bool,
936 ) -> bool {
937 true
938 }
939}
940
941unsafe impl<'a> QueryData for EntityMut<'a> {
943 const IS_READ_ONLY: bool = false;
944 const IS_ARCHETYPAL: bool = true;
945 type ReadOnly = EntityRef<'a>;
946 type Item<'w, 's> = EntityMut<'w>;
947
948 fn shrink<'wlong: 'wshort, 'wshort, 's>(
949 item: Self::Item<'wlong, 's>,
950 ) -> Self::Item<'wshort, 's> {
951 item
952 }
953
954 #[inline(always)]
955 unsafe fn fetch<'w, 's>(
956 _state: &'s Self::State,
957 fetch: &mut Self::Fetch<'w>,
958 entity: Entity,
959 _table_row: TableRow,
960 ) -> Option<Self::Item<'w, 's>> {
961 let cell = unsafe {
963 fetch
964 .world
965 .get_entity_with_ticks(entity, fetch.last_run, fetch.this_run)
966 .debug_checked_unwrap()
967 };
968 Some(unsafe { EntityMut::new(cell) })
970 }
971
972 fn iter_access(_state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
973 iter::once(EcsAccessType::Component(EcsAccessLevel::WriteAll))
974 }
975}
976
977impl ReleaseStateQueryData for EntityMut<'_> {
978 fn release_state<'w>(item: Self::Item<'w, '_>) -> Self::Item<'w, 'static> {
979 item
980 }
981}
982
983impl ArchetypeQueryData for EntityMut<'_> {}
984
985unsafe impl WorldQuery for FilteredEntityRef<'_, '_> {
987 type Fetch<'w> = EntityFetch<'w>;
988 type State = Access;
989
990 fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
991 fetch
992 }
993
994 const IS_DENSE: bool = true;
995
996 unsafe fn init_fetch<'w, 's>(
997 world: UnsafeWorldCell<'w>,
998 _state: &'s Self::State,
999 last_run: Tick,
1000 this_run: Tick,
1001 ) -> Self::Fetch<'w> {
1002 EntityFetch {
1003 world,
1004 last_run,
1005 this_run,
1006 }
1007 }
1008
1009 #[inline]
1010 unsafe fn set_archetype<'w, 's>(
1011 _fetch: &mut Self::Fetch<'w>,
1012 _state: &'s Self::State,
1013 _: &'w Archetype,
1014 _table: &Table,
1015 ) {
1016 }
1017
1018 #[inline]
1019 unsafe fn set_table<'w, 's>(
1020 _fetch: &mut Self::Fetch<'w>,
1021 _state: &'s Self::State,
1022 _: &'w Table,
1023 ) {
1024 }
1025
1026 fn update_component_access(state: &Self::State, filtered_access: &mut FilteredAccess) {
1027 assert!(
1028 filtered_access.access().is_compatible(state),
1029 "FilteredEntityRef conflicts with a previous access in this query. Exclusive access cannot coincide with any other accesses.",
1030 );
1031 filtered_access.access.extend(state);
1032 }
1033
1034 fn init_state(_world: &mut World) -> Self::State {
1035 Access::default()
1036 }
1037
1038 fn get_state(_components: &Components) -> Option<Self::State> {
1039 Some(Access::default())
1040 }
1041
1042 fn matches_component_set(
1043 _state: &Self::State,
1044 _set_contains_id: &impl Fn(ComponentId) -> bool,
1045 ) -> bool {
1046 true
1047 }
1048}
1049
1050unsafe impl<'a, 'b> QueryData for FilteredEntityRef<'a, 'b> {
1052 const IS_READ_ONLY: bool = true;
1053 const IS_ARCHETYPAL: bool = true;
1054 type ReadOnly = Self;
1055 type Item<'w, 's> = FilteredEntityRef<'w, 's>;
1056
1057 fn shrink<'wlong: 'wshort, 'wshort, 's>(
1058 item: Self::Item<'wlong, 's>,
1059 ) -> Self::Item<'wshort, 's> {
1060 item
1061 }
1062
1063 #[inline]
1064 fn provide_extra_access(
1065 state: &mut Self::State,
1066 access: &mut Access,
1067 available_access: &Access,
1068 ) {
1069 state.clone_from(available_access);
1073 state.clear_writes();
1075 state.remove_conflicting_access(access);
1077 access.extend(state);
1080 }
1081
1082 #[inline(always)]
1083 unsafe fn fetch<'w, 's>(
1084 access: &'s Self::State,
1085 fetch: &mut Self::Fetch<'w>,
1086 entity: Entity,
1087 _table_row: TableRow,
1088 ) -> Option<Self::Item<'w, 's>> {
1089 let cell = unsafe {
1091 fetch
1092 .world
1093 .get_entity_with_ticks(entity, fetch.last_run, fetch.this_run)
1094 .debug_checked_unwrap()
1095 };
1096 Some(unsafe { FilteredEntityRef::new(cell, access) })
1098 }
1099
1100 fn iter_access(state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
1101 iter::once(EcsAccessType::Access(state))
1102 }
1103}
1104
1105unsafe impl ReadOnlyQueryData for FilteredEntityRef<'_, '_> {}
1107
1108impl ArchetypeQueryData for FilteredEntityRef<'_, '_> {}
1109
1110unsafe impl WorldQuery for FilteredEntityMut<'_, '_> {
1112 type Fetch<'w> = EntityFetch<'w>;
1113 type State = Access;
1114
1115 fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
1116 fetch
1117 }
1118
1119 const IS_DENSE: bool = true;
1120
1121 unsafe fn init_fetch<'w, 's>(
1122 world: UnsafeWorldCell<'w>,
1123 _state: &'s Self::State,
1124 last_run: Tick,
1125 this_run: Tick,
1126 ) -> Self::Fetch<'w> {
1127 EntityFetch {
1128 world,
1129 last_run,
1130 this_run,
1131 }
1132 }
1133
1134 #[inline]
1135 unsafe fn set_archetype<'w, 's>(
1136 _fetch: &mut Self::Fetch<'w>,
1137 _state: &'s Self::State,
1138 _: &'w Archetype,
1139 _table: &Table,
1140 ) {
1141 }
1142
1143 #[inline]
1144 unsafe fn set_table<'w, 's>(
1145 _fetch: &mut Self::Fetch<'w>,
1146 _state: &'s Self::State,
1147 _: &'w Table,
1148 ) {
1149 }
1150
1151 fn update_component_access(state: &Self::State, filtered_access: &mut FilteredAccess) {
1152 assert!(
1153 filtered_access.access().is_compatible(state),
1154 "FilteredEntityMut conflicts with a previous access in this query. Exclusive access cannot coincide with any other accesses.",
1155 );
1156 filtered_access.access.extend(state);
1157 }
1158
1159 fn init_state(_world: &mut World) -> Self::State {
1160 Access::default()
1161 }
1162
1163 fn get_state(_components: &Components) -> Option<Self::State> {
1164 Some(Access::default())
1165 }
1166
1167 fn matches_component_set(
1168 _state: &Self::State,
1169 _set_contains_id: &impl Fn(ComponentId) -> bool,
1170 ) -> bool {
1171 true
1172 }
1173}
1174
1175unsafe impl<'a, 'b> QueryData for FilteredEntityMut<'a, 'b> {
1177 const IS_READ_ONLY: bool = false;
1178 const IS_ARCHETYPAL: bool = true;
1179 type ReadOnly = FilteredEntityRef<'a, 'b>;
1180 type Item<'w, 's> = FilteredEntityMut<'w, 's>;
1181
1182 fn shrink<'wlong: 'wshort, 'wshort, 's>(
1183 item: Self::Item<'wlong, 's>,
1184 ) -> Self::Item<'wshort, 's> {
1185 item
1186 }
1187
1188 #[inline]
1189 fn provide_extra_access(
1190 state: &mut Self::State,
1191 access: &mut Access,
1192 available_access: &Access,
1193 ) {
1194 state.clone_from(available_access);
1198 state.remove_conflicting_access(access);
1200 access.extend(state);
1203 }
1204
1205 #[inline(always)]
1206 unsafe fn fetch<'w, 's>(
1207 access: &'s Self::State,
1208 fetch: &mut Self::Fetch<'w>,
1209 entity: Entity,
1210 _table_row: TableRow,
1211 ) -> Option<Self::Item<'w, 's>> {
1212 let cell = unsafe {
1214 fetch
1215 .world
1216 .get_entity_with_ticks(entity, fetch.last_run, fetch.this_run)
1217 .debug_checked_unwrap()
1218 };
1219 Some(unsafe { FilteredEntityMut::new(cell, access) })
1221 }
1222
1223 fn iter_access(state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
1224 iter::once(EcsAccessType::Access(state))
1225 }
1226}
1227
1228impl ArchetypeQueryData for FilteredEntityMut<'_, '_> {}
1229
1230unsafe impl<'a, 'b, B> WorldQuery for EntityRefExcept<'a, 'b, B>
1234where
1235 B: Bundle,
1236{
1237 type Fetch<'w> = EntityFetch<'w>;
1238 type State = Access;
1239
1240 fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
1241 fetch
1242 }
1243
1244 unsafe fn init_fetch<'w, 's>(
1245 world: UnsafeWorldCell<'w>,
1246 _: &'s Self::State,
1247 last_run: Tick,
1248 this_run: Tick,
1249 ) -> Self::Fetch<'w> {
1250 EntityFetch {
1251 world,
1252 last_run,
1253 this_run,
1254 }
1255 }
1256
1257 const IS_DENSE: bool = true;
1258
1259 unsafe fn set_archetype<'w, 's>(
1260 _: &mut Self::Fetch<'w>,
1261 _: &'s Self::State,
1262 _: &'w Archetype,
1263 _: &'w Table,
1264 ) {
1265 }
1266
1267 unsafe fn set_table<'w, 's>(_: &mut Self::Fetch<'w>, _: &'s Self::State, _: &'w Table) {}
1268
1269 fn update_component_access(state: &Self::State, filtered_access: &mut FilteredAccess) {
1270 let access = filtered_access.access_mut();
1271 assert!(
1272 access.is_compatible(state),
1273 "`EntityRefExcept<{}>` conflicts with a previous access in this query.",
1274 DebugName::type_name::<B>(),
1275 );
1276 access.extend(state);
1277 }
1278
1279 fn init_state(world: &mut World) -> Self::State {
1280 let mut access = Access::new();
1281 access.read_all_components();
1282 for id in B::component_ids(&mut world.components_registrator()) {
1283 access.remove_component_read(id);
1284 }
1285 access
1286 }
1287
1288 fn get_state(components: &Components) -> Option<Self::State> {
1289 let mut access = Access::new();
1290 access.read_all_components();
1291 for id in B::get_component_ids(components).flatten() {
1298 access.remove_component_read(id);
1299 }
1300 Some(access)
1301 }
1302
1303 fn matches_component_set(_: &Self::State, _: &impl Fn(ComponentId) -> bool) -> bool {
1304 true
1305 }
1306}
1307
1308unsafe impl<'a, 'b, B> QueryData for EntityRefExcept<'a, 'b, B>
1310where
1311 B: Bundle,
1312{
1313 const IS_READ_ONLY: bool = true;
1314 const IS_ARCHETYPAL: bool = true;
1315 type ReadOnly = Self;
1316 type Item<'w, 's> = EntityRefExcept<'w, 's, B>;
1317
1318 fn shrink<'wlong: 'wshort, 'wshort, 's>(
1319 item: Self::Item<'wlong, 's>,
1320 ) -> Self::Item<'wshort, 's> {
1321 item
1322 }
1323
1324 unsafe fn fetch<'w, 's>(
1325 access: &'s Self::State,
1326 fetch: &mut Self::Fetch<'w>,
1327 entity: Entity,
1328 _: TableRow,
1329 ) -> Option<Self::Item<'w, 's>> {
1330 let cell = fetch
1331 .world
1332 .get_entity_with_ticks(entity, fetch.last_run, fetch.this_run)
1333 .unwrap();
1334 Some(EntityRefExcept::new(cell, access))
1335 }
1336
1337 fn iter_access(state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
1338 iter::once(EcsAccessType::Access(state))
1339 }
1340}
1341
1342unsafe impl<B> ReadOnlyQueryData for EntityRefExcept<'_, '_, B> where B: Bundle {}
1345
1346impl<B: Bundle> ArchetypeQueryData for EntityRefExcept<'_, '_, B> {}
1347
1348unsafe impl<'a, 'b, B> WorldQuery for EntityMutExcept<'a, 'b, B>
1352where
1353 B: Bundle,
1354{
1355 type Fetch<'w> = EntityFetch<'w>;
1356 type State = Access;
1357
1358 fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
1359 fetch
1360 }
1361
1362 unsafe fn init_fetch<'w, 's>(
1363 world: UnsafeWorldCell<'w>,
1364 _: &'s Self::State,
1365 last_run: Tick,
1366 this_run: Tick,
1367 ) -> Self::Fetch<'w> {
1368 EntityFetch {
1369 world,
1370 last_run,
1371 this_run,
1372 }
1373 }
1374
1375 const IS_DENSE: bool = true;
1376
1377 unsafe fn set_archetype<'w, 's>(
1378 _: &mut Self::Fetch<'w>,
1379 _: &'s Self::State,
1380 _: &'w Archetype,
1381 _: &'w Table,
1382 ) {
1383 }
1384
1385 unsafe fn set_table<'w, 's>(_: &mut Self::Fetch<'w>, _: &'s Self::State, _: &'w Table) {}
1386
1387 fn update_component_access(state: &Self::State, filtered_access: &mut FilteredAccess) {
1388 let access = filtered_access.access_mut();
1389 assert!(
1390 access.is_compatible(state),
1391 "`EntityMutExcept<{}>` conflicts with a previous access in this query.",
1392 DebugName::type_name::<B>()
1393 );
1394 access.extend(state);
1395 }
1396
1397 fn init_state(world: &mut World) -> Self::State {
1398 let mut access = Access::new();
1399 access.write_all_components();
1400 for id in B::component_ids(&mut world.components_registrator()) {
1401 access.remove_component_read(id);
1402 }
1403 access
1404 }
1405
1406 fn get_state(components: &Components) -> Option<Self::State> {
1407 let mut access = Access::new();
1408 access.write_all_components();
1409 for id in B::get_component_ids(components).flatten() {
1416 access.remove_component_read(id);
1417 }
1418 Some(access)
1419 }
1420
1421 fn matches_component_set(_: &Self::State, _: &impl Fn(ComponentId) -> bool) -> bool {
1422 true
1423 }
1424}
1425
1426unsafe impl<'a, 'b, B> QueryData for EntityMutExcept<'a, 'b, B>
1429where
1430 B: Bundle,
1431{
1432 const IS_READ_ONLY: bool = false;
1433 const IS_ARCHETYPAL: bool = true;
1434 type ReadOnly = EntityRefExcept<'a, 'b, B>;
1435 type Item<'w, 's> = EntityMutExcept<'w, 's, B>;
1436
1437 fn shrink<'wlong: 'wshort, 'wshort, 's>(
1438 item: Self::Item<'wlong, 's>,
1439 ) -> Self::Item<'wshort, 's> {
1440 item
1441 }
1442
1443 unsafe fn fetch<'w, 's>(
1444 access: &'s Self::State,
1445 fetch: &mut Self::Fetch<'w>,
1446 entity: Entity,
1447 _: TableRow,
1448 ) -> Option<Self::Item<'w, 's>> {
1449 let cell = fetch
1450 .world
1451 .get_entity_with_ticks(entity, fetch.last_run, fetch.this_run)
1452 .unwrap();
1453 Some(EntityMutExcept::new(cell, access))
1454 }
1455
1456 fn iter_access(state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
1457 iter::once(EcsAccessType::Access(state))
1458 }
1459}
1460
1461impl<B: Bundle> ArchetypeQueryData for EntityMutExcept<'_, '_, B> {}
1462
1463unsafe impl WorldQuery for &Archetype {
1467 type Fetch<'w> = (&'w Entities, &'w Archetypes);
1468 type State = ();
1469
1470 fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
1471 fetch
1472 }
1473
1474 unsafe fn init_fetch<'w, 's>(
1475 world: UnsafeWorldCell<'w>,
1476 _state: &'s Self::State,
1477 _last_run: Tick,
1478 _this_run: Tick,
1479 ) -> Self::Fetch<'w> {
1480 (world.entities(), world.archetypes())
1481 }
1482
1483 const IS_DENSE: bool = true;
1486
1487 #[inline]
1488 unsafe fn set_archetype<'w, 's>(
1489 _fetch: &mut Self::Fetch<'w>,
1490 _state: &'s Self::State,
1491 _archetype: &'w Archetype,
1492 _table: &Table,
1493 ) {
1494 }
1495
1496 #[inline]
1497 unsafe fn set_table<'w, 's>(
1498 _fetch: &mut Self::Fetch<'w>,
1499 _state: &'s Self::State,
1500 _table: &'w Table,
1501 ) {
1502 }
1503
1504 fn update_component_access(_state: &Self::State, _access: &mut FilteredAccess) {}
1505
1506 fn init_state(_world: &mut World) {}
1507
1508 fn get_state(_components: &Components) -> Option<()> {
1509 Some(())
1510 }
1511
1512 fn matches_component_set(
1513 _state: &Self::State,
1514 _set_contains_id: &impl Fn(ComponentId) -> bool,
1515 ) -> bool {
1516 true
1517 }
1518}
1519
1520unsafe impl QueryData for &Archetype {
1522 const IS_READ_ONLY: bool = true;
1523 const IS_ARCHETYPAL: bool = true;
1524 type ReadOnly = Self;
1525 type Item<'w, 's> = &'w Archetype;
1526
1527 fn shrink<'wlong: 'wshort, 'wshort, 's>(
1528 item: Self::Item<'wlong, 's>,
1529 ) -> Self::Item<'wshort, 's> {
1530 item
1531 }
1532
1533 #[inline(always)]
1534 unsafe fn fetch<'w, 's>(
1535 _state: &'s Self::State,
1536 fetch: &mut Self::Fetch<'w>,
1537 entity: Entity,
1538 _table_row: TableRow,
1539 ) -> Option<Self::Item<'w, 's>> {
1540 let (entities, archetypes) = *fetch;
1541 let location = unsafe { entities.get_spawned(entity).debug_checked_unwrap() };
1543 Some(unsafe { archetypes.get(location.archetype_id).debug_checked_unwrap() })
1545 }
1546
1547 fn iter_access(_state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
1548 iter::empty()
1549 }
1550}
1551
1552unsafe impl ReadOnlyQueryData for &Archetype {}
1554
1555impl ReleaseStateQueryData for &Archetype {
1556 fn release_state<'w>(item: Self::Item<'w, '_>) -> Self::Item<'w, 'static> {
1557 item
1558 }
1559}
1560
1561impl ArchetypeQueryData for &Archetype {}
1562
1563pub struct ReadFetch<'w, T: Component> {
1565 components: StorageSwitch<
1566 T,
1567 Option<ThinSlicePtr<'w, UnsafeCell<T>>>,
1569 Option<&'w ComponentSparseSet>,
1571 >,
1572}
1573
1574impl<T: Component> Clone for ReadFetch<'_, T> {
1575 fn clone(&self) -> Self {
1576 *self
1577 }
1578}
1579
1580impl<T: Component> Copy for ReadFetch<'_, T> {}
1581
1582unsafe impl<T: Component> WorldQuery for &T {
1588 type Fetch<'w> = ReadFetch<'w, T>;
1589 type State = ComponentId;
1590
1591 fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
1592 fetch
1593 }
1594
1595 #[inline]
1596 unsafe fn init_fetch<'w, 's>(
1597 world: UnsafeWorldCell<'w>,
1598 &component_id: &ComponentId,
1599 _last_run: Tick,
1600 _this_run: Tick,
1601 ) -> ReadFetch<'w, T> {
1602 ReadFetch {
1603 components: StorageSwitch::new(
1604 || None,
1605 || {
1606 unsafe { world.storages().sparse_sets.get(component_id) }
1611 },
1612 ),
1613 }
1614 }
1615
1616 const IS_DENSE: bool = {
1617 match T::STORAGE_TYPE {
1618 StorageType::Table => true,
1619 StorageType::SparseSet => false,
1620 }
1621 };
1622
1623 #[inline]
1624 unsafe fn set_archetype<'w>(
1625 fetch: &mut ReadFetch<'w, T>,
1626 component_id: &ComponentId,
1627 _archetype: &'w Archetype,
1628 table: &'w Table,
1629 ) {
1630 if Self::IS_DENSE {
1631 unsafe {
1633 Self::set_table(fetch, component_id, table);
1634 }
1635 }
1636 }
1637
1638 #[inline]
1639 unsafe fn set_table<'w>(
1640 fetch: &mut ReadFetch<'w, T>,
1641 &component_id: &ComponentId,
1642 table: &'w Table,
1643 ) {
1644 let table_data = Some(
1645 table
1646 .get_data_slice_for(component_id)
1647 .debug_checked_unwrap()
1648 .into(),
1649 );
1650 unsafe { fetch.components.set_table(table_data) };
1652 }
1653
1654 fn update_component_access(&component_id: &ComponentId, access: &mut FilteredAccess) {
1655 assert!(
1656 !access.access().has_component_write(component_id),
1657 "&{} conflicts with a previous access in this query. Shared access cannot coincide with exclusive access.",
1658 DebugName::type_name::<T>(),
1659 );
1660 access.add_component_read(component_id);
1661 }
1662
1663 fn init_state(world: &mut World) -> ComponentId {
1664 world.register_component::<T>()
1665 }
1666
1667 fn get_state(components: &Components) -> Option<Self::State> {
1668 components.component_id::<T>()
1669 }
1670
1671 fn matches_component_set(
1672 &state: &ComponentId,
1673 set_contains_id: &impl Fn(ComponentId) -> bool,
1674 ) -> bool {
1675 set_contains_id(state)
1676 }
1677}
1678
1679unsafe impl<T: Component> QueryData for &T {
1681 const IS_READ_ONLY: bool = true;
1682 const IS_ARCHETYPAL: bool = true;
1683 type ReadOnly = Self;
1684 type Item<'w, 's> = &'w T;
1685
1686 fn shrink<'wlong: 'wshort, 'wshort, 's>(
1687 item: Self::Item<'wlong, 's>,
1688 ) -> Self::Item<'wshort, 's> {
1689 item
1690 }
1691
1692 #[inline(always)]
1693 unsafe fn fetch<'w, 's>(
1694 _state: &'s Self::State,
1695 fetch: &mut Self::Fetch<'w>,
1696 entity: Entity,
1697 table_row: TableRow,
1698 ) -> Option<Self::Item<'w, 's>> {
1699 Some(fetch.components.extract(
1700 |table| {
1701 let table = unsafe { table.debug_checked_unwrap() };
1703 let item = unsafe { table.get_unchecked(table_row.index()) };
1705 item.deref()
1706 },
1707 |sparse_set| {
1708 let item = unsafe {
1710 sparse_set
1711 .debug_checked_unwrap()
1712 .get(entity)
1713 .debug_checked_unwrap()
1714 };
1715 item.deref()
1716 },
1717 ))
1718 }
1719
1720 fn iter_access(state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
1721 iter::once(EcsAccessType::Component(EcsAccessLevel::Read(*state)))
1722 }
1723}
1724
1725unsafe impl<T: Component> ReadOnlyQueryData for &T {}
1727
1728impl<T: Component> ReleaseStateQueryData for &T {
1729 fn release_state<'w>(item: Self::Item<'w, '_>) -> Self::Item<'w, 'static> {
1730 item
1731 }
1732}
1733
1734impl<T: Component> ArchetypeQueryData for &T {}
1735
1736#[doc(hidden)]
1737pub struct RefFetch<'w, T: Component> {
1738 components: StorageSwitch<
1739 T,
1740 Option<(
1742 ThinSlicePtr<'w, UnsafeCell<T>>,
1743 ThinSlicePtr<'w, UnsafeCell<Tick>>,
1744 ThinSlicePtr<'w, UnsafeCell<Tick>>,
1745 MaybeLocation<ThinSlicePtr<'w, UnsafeCell<&'static Location<'static>>>>,
1746 )>,
1747 Option<&'w ComponentSparseSet>,
1750 >,
1751 last_run: Tick,
1752 this_run: Tick,
1753}
1754
1755impl<T: Component> Clone for RefFetch<'_, T> {
1756 fn clone(&self) -> Self {
1757 *self
1758 }
1759}
1760
1761impl<T: Component> Copy for RefFetch<'_, T> {}
1762
1763unsafe impl<'__w, T: Component> WorldQuery for Ref<'__w, T> {
1769 type Fetch<'w> = RefFetch<'w, T>;
1770 type State = ComponentId;
1771
1772 fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
1773 fetch
1774 }
1775
1776 #[inline]
1777 unsafe fn init_fetch<'w, 's>(
1778 world: UnsafeWorldCell<'w>,
1779 &component_id: &ComponentId,
1780 last_run: Tick,
1781 this_run: Tick,
1782 ) -> RefFetch<'w, T> {
1783 RefFetch {
1784 components: StorageSwitch::new(
1785 || None,
1786 || {
1787 unsafe { world.storages().sparse_sets.get(component_id) }
1792 },
1793 ),
1794 last_run,
1795 this_run,
1796 }
1797 }
1798
1799 const IS_DENSE: bool = {
1800 match T::STORAGE_TYPE {
1801 StorageType::Table => true,
1802 StorageType::SparseSet => false,
1803 }
1804 };
1805
1806 #[inline]
1807 unsafe fn set_archetype<'w>(
1808 fetch: &mut RefFetch<'w, T>,
1809 component_id: &ComponentId,
1810 _archetype: &'w Archetype,
1811 table: &'w Table,
1812 ) {
1813 if Self::IS_DENSE {
1814 unsafe {
1816 Self::set_table(fetch, component_id, table);
1817 }
1818 }
1819 }
1820
1821 #[inline]
1822 unsafe fn set_table<'w>(
1823 fetch: &mut RefFetch<'w, T>,
1824 &component_id: &ComponentId,
1825 table: &'w Table,
1826 ) {
1827 let column = table.get_column(component_id).debug_checked_unwrap();
1828 let table_data = Some((
1829 column.get_data_slice(table.entity_count() as usize).into(),
1830 column
1831 .get_added_ticks_slice(table.entity_count() as usize)
1832 .into(),
1833 column
1834 .get_changed_ticks_slice(table.entity_count() as usize)
1835 .into(),
1836 column
1837 .get_changed_by_slice(table.entity_count() as usize)
1838 .map(Into::into),
1839 ));
1840 unsafe { fetch.components.set_table(table_data) };
1842 }
1843
1844 fn update_component_access(&component_id: &ComponentId, access: &mut FilteredAccess) {
1845 assert!(
1846 !access.access().has_component_write(component_id),
1847 "&{} conflicts with a previous access in this query. Shared access cannot coincide with exclusive access.",
1848 DebugName::type_name::<T>(),
1849 );
1850 access.add_component_read(component_id);
1851 }
1852
1853 fn init_state(world: &mut World) -> ComponentId {
1854 world.register_component::<T>()
1855 }
1856
1857 fn get_state(components: &Components) -> Option<Self::State> {
1858 components.component_id::<T>()
1859 }
1860
1861 fn matches_component_set(
1862 &state: &ComponentId,
1863 set_contains_id: &impl Fn(ComponentId) -> bool,
1864 ) -> bool {
1865 set_contains_id(state)
1866 }
1867}
1868
1869unsafe impl<'__w, T: Component> QueryData for Ref<'__w, T> {
1871 const IS_READ_ONLY: bool = true;
1872 const IS_ARCHETYPAL: bool = true;
1873 type ReadOnly = Self;
1874 type Item<'w, 's> = Ref<'w, T>;
1875
1876 fn shrink<'wlong: 'wshort, 'wshort, 's>(
1877 item: Self::Item<'wlong, 's>,
1878 ) -> Self::Item<'wshort, 's> {
1879 item
1880 }
1881
1882 #[inline(always)]
1883 unsafe fn fetch<'w, 's>(
1884 _state: &'s Self::State,
1885 fetch: &mut Self::Fetch<'w>,
1886 entity: Entity,
1887 table_row: TableRow,
1888 ) -> Option<Self::Item<'w, 's>> {
1889 Some(fetch.components.extract(
1890 |table| {
1891 let (table_components, added_ticks, changed_ticks, callers) =
1893 unsafe { table.debug_checked_unwrap() };
1894
1895 let component = unsafe { table_components.get_unchecked(table_row.index()) };
1897 let added = unsafe { added_ticks.get_unchecked(table_row.index()) };
1899 let changed = unsafe { changed_ticks.get_unchecked(table_row.index()) };
1901 let caller =
1903 callers.map(|callers| unsafe { callers.get_unchecked(table_row.index()) });
1904
1905 Ref {
1906 value: component.deref(),
1907 ticks: ComponentTicksRef {
1908 added: added.deref(),
1909 changed: changed.deref(),
1910 changed_by: caller.map(|caller| caller.deref()),
1911 this_run: fetch.this_run,
1912 last_run: fetch.last_run,
1913 },
1914 }
1915 },
1916 |sparse_set| {
1917 let (component, ticks) = unsafe {
1919 sparse_set
1920 .debug_checked_unwrap()
1921 .get_with_ticks(entity)
1922 .debug_checked_unwrap()
1923 };
1924
1925 Ref {
1926 value: component.deref(),
1927 ticks: ComponentTicksRef::from_tick_cells(
1928 ticks,
1929 fetch.last_run,
1930 fetch.this_run,
1931 ),
1932 }
1933 },
1934 ))
1935 }
1936
1937 fn iter_access(state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
1938 iter::once(EcsAccessType::Component(EcsAccessLevel::Read(*state)))
1939 }
1940}
1941
1942unsafe impl<'__w, T: Component> ReadOnlyQueryData for Ref<'__w, T> {}
1944
1945impl<T: Component> ReleaseStateQueryData for Ref<'_, T> {
1946 fn release_state<'w>(item: Self::Item<'w, '_>) -> Self::Item<'w, 'static> {
1947 item
1948 }
1949}
1950
1951impl<T: Component> ArchetypeQueryData for Ref<'_, T> {}
1952
1953pub struct WriteFetch<'w, T: Component> {
1955 components: StorageSwitch<
1956 T,
1957 Option<(
1959 ThinSlicePtr<'w, UnsafeCell<T>>,
1960 ThinSlicePtr<'w, UnsafeCell<Tick>>,
1961 ThinSlicePtr<'w, UnsafeCell<Tick>>,
1962 MaybeLocation<ThinSlicePtr<'w, UnsafeCell<&'static Location<'static>>>>,
1963 )>,
1964 Option<&'w ComponentSparseSet>,
1967 >,
1968 last_run: Tick,
1969 this_run: Tick,
1970}
1971
1972impl<T: Component> Clone for WriteFetch<'_, T> {
1973 fn clone(&self) -> Self {
1974 *self
1975 }
1976}
1977
1978impl<T: Component> Copy for WriteFetch<'_, T> {}
1979
1980unsafe impl<'__w, T: Component> WorldQuery for &'__w mut T {
1986 type Fetch<'w> = WriteFetch<'w, T>;
1987 type State = ComponentId;
1988
1989 fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
1990 fetch
1991 }
1992
1993 #[inline]
1994 unsafe fn init_fetch<'w, 's>(
1995 world: UnsafeWorldCell<'w>,
1996 &component_id: &ComponentId,
1997 last_run: Tick,
1998 this_run: Tick,
1999 ) -> WriteFetch<'w, T> {
2000 WriteFetch {
2001 components: StorageSwitch::new(
2002 || None,
2003 || {
2004 unsafe { world.storages().sparse_sets.get(component_id) }
2009 },
2010 ),
2011 last_run,
2012 this_run,
2013 }
2014 }
2015
2016 const IS_DENSE: bool = {
2017 match T::STORAGE_TYPE {
2018 StorageType::Table => true,
2019 StorageType::SparseSet => false,
2020 }
2021 };
2022
2023 #[inline]
2024 unsafe fn set_archetype<'w>(
2025 fetch: &mut WriteFetch<'w, T>,
2026 component_id: &ComponentId,
2027 _archetype: &'w Archetype,
2028 table: &'w Table,
2029 ) {
2030 if Self::IS_DENSE {
2031 unsafe {
2033 Self::set_table(fetch, component_id, table);
2034 }
2035 }
2036 }
2037
2038 #[inline]
2039 unsafe fn set_table<'w>(
2040 fetch: &mut WriteFetch<'w, T>,
2041 &component_id: &ComponentId,
2042 table: &'w Table,
2043 ) {
2044 let column = table.get_column(component_id).debug_checked_unwrap();
2045 let table_data = Some((
2046 column.get_data_slice(table.entity_count() as usize).into(),
2047 column
2048 .get_added_ticks_slice(table.entity_count() as usize)
2049 .into(),
2050 column
2051 .get_changed_ticks_slice(table.entity_count() as usize)
2052 .into(),
2053 column
2054 .get_changed_by_slice(table.entity_count() as usize)
2055 .map(Into::into),
2056 ));
2057 unsafe { fetch.components.set_table(table_data) };
2059 }
2060
2061 fn update_component_access(&component_id: &ComponentId, access: &mut FilteredAccess) {
2062 assert!(
2063 !access.access().has_component_read(component_id),
2064 "&mut {} conflicts with a previous access in this query. Mutable component access must be unique.",
2065 DebugName::type_name::<T>(),
2066 );
2067 access.add_component_write(component_id);
2068 }
2069
2070 fn init_state(world: &mut World) -> ComponentId {
2071 world.register_component::<T>()
2072 }
2073
2074 fn get_state(components: &Components) -> Option<Self::State> {
2075 components.component_id::<T>()
2076 }
2077
2078 fn matches_component_set(
2079 &state: &ComponentId,
2080 set_contains_id: &impl Fn(ComponentId) -> bool,
2081 ) -> bool {
2082 set_contains_id(state)
2083 }
2084}
2085
2086unsafe impl<'__w, T: Component<Mutability = Mutable>> QueryData for &'__w mut T {
2088 const IS_READ_ONLY: bool = false;
2089 const IS_ARCHETYPAL: bool = true;
2090 type ReadOnly = &'__w T;
2091 type Item<'w, 's> = Mut<'w, T>;
2092
2093 fn shrink<'wlong: 'wshort, 'wshort, 's>(
2094 item: Self::Item<'wlong, 's>,
2095 ) -> Self::Item<'wshort, 's> {
2096 item
2097 }
2098
2099 #[inline(always)]
2100 unsafe fn fetch<'w, 's>(
2101 _state: &'s Self::State,
2102 fetch: &mut Self::Fetch<'w>,
2103 entity: Entity,
2104 table_row: TableRow,
2105 ) -> Option<Self::Item<'w, 's>> {
2106 Some(fetch.components.extract(
2107 |table| {
2108 let (table_components, added_ticks, changed_ticks, callers) =
2110 unsafe { table.debug_checked_unwrap() };
2111
2112 let component = unsafe { table_components.get_unchecked(table_row.index()) };
2114 let added = unsafe { added_ticks.get_unchecked(table_row.index()) };
2116 let changed = unsafe { changed_ticks.get_unchecked(table_row.index()) };
2118 let caller =
2120 callers.map(|callers| unsafe { callers.get_unchecked(table_row.index()) });
2121
2122 Mut {
2123 value: component.deref_mut(),
2124 ticks: ComponentTicksMut {
2125 added: added.deref_mut(),
2126 changed: changed.deref_mut(),
2127 changed_by: caller.map(|caller| caller.deref_mut()),
2128 this_run: fetch.this_run,
2129 last_run: fetch.last_run,
2130 },
2131 }
2132 },
2133 |sparse_set| {
2134 let (component, ticks) = unsafe {
2136 sparse_set
2137 .debug_checked_unwrap()
2138 .get_with_ticks(entity)
2139 .debug_checked_unwrap()
2140 };
2141
2142 Mut {
2143 value: component.assert_unique().deref_mut(),
2144 ticks: ComponentTicksMut::from_tick_cells(
2145 ticks,
2146 fetch.last_run,
2147 fetch.this_run,
2148 ),
2149 }
2150 },
2151 ))
2152 }
2153
2154 fn iter_access(state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
2155 iter::once(EcsAccessType::Component(EcsAccessLevel::Write(*state)))
2156 }
2157}
2158
2159impl<T: Component<Mutability = Mutable>> ReleaseStateQueryData for &mut T {
2160 fn release_state<'w>(item: Self::Item<'w, '_>) -> Self::Item<'w, 'static> {
2161 item
2162 }
2163}
2164
2165impl<T: Component<Mutability = Mutable>> ArchetypeQueryData for &mut T {}
2166
2167unsafe impl<'__w, T: Component> WorldQuery for Mut<'__w, T> {
2177 type Fetch<'w> = WriteFetch<'w, T>;
2178 type State = ComponentId;
2179
2180 fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
2181 fetch
2182 }
2183
2184 #[inline]
2185 unsafe fn init_fetch<'w, 's>(
2187 world: UnsafeWorldCell<'w>,
2188 state: &ComponentId,
2189 last_run: Tick,
2190 this_run: Tick,
2191 ) -> WriteFetch<'w, T> {
2192 <&mut T as WorldQuery>::init_fetch(world, state, last_run, this_run)
2193 }
2194
2195 const IS_DENSE: bool = <&mut T as WorldQuery>::IS_DENSE;
2197
2198 #[inline]
2199 unsafe fn set_archetype<'w>(
2201 fetch: &mut WriteFetch<'w, T>,
2202 state: &ComponentId,
2203 archetype: &'w Archetype,
2204 table: &'w Table,
2205 ) {
2206 <&mut T as WorldQuery>::set_archetype(fetch, state, archetype, table);
2207 }
2208
2209 #[inline]
2210 unsafe fn set_table<'w>(fetch: &mut WriteFetch<'w, T>, state: &ComponentId, table: &'w Table) {
2212 <&mut T as WorldQuery>::set_table(fetch, state, table);
2213 }
2214
2215 fn update_component_access(&component_id: &ComponentId, access: &mut FilteredAccess) {
2217 assert!(
2220 !access.access().has_component_read(component_id),
2221 "Mut<{}> conflicts with a previous access in this query. Mutable component access mut be unique.",
2222 DebugName::type_name::<T>(),
2223 );
2224 access.add_component_write(component_id);
2225 }
2226
2227 fn init_state(world: &mut World) -> ComponentId {
2229 <&mut T as WorldQuery>::init_state(world)
2230 }
2231
2232 fn get_state(components: &Components) -> Option<ComponentId> {
2234 <&mut T as WorldQuery>::get_state(components)
2235 }
2236
2237 fn matches_component_set(
2239 state: &ComponentId,
2240 set_contains_id: &impl Fn(ComponentId) -> bool,
2241 ) -> bool {
2242 <&mut T as WorldQuery>::matches_component_set(state, set_contains_id)
2243 }
2244}
2245
2246unsafe impl<'__w, T: Component<Mutability = Mutable>> QueryData for Mut<'__w, T> {
2248 const IS_READ_ONLY: bool = false;
2249 const IS_ARCHETYPAL: bool = true;
2250 type ReadOnly = Ref<'__w, T>;
2251 type Item<'w, 's> = Mut<'w, T>;
2252
2253 fn shrink<'wlong: 'wshort, 'wshort, 's>(
2255 item: Self::Item<'wlong, 's>,
2256 ) -> Self::Item<'wshort, 's> {
2257 <&mut T as QueryData>::shrink(item)
2258 }
2259
2260 #[inline(always)]
2261 unsafe fn fetch<'w, 's>(
2263 state: &'s Self::State,
2264 fetch: &mut Self::Fetch<'w>,
2267 entity: Entity,
2268 table_row: TableRow,
2269 ) -> Option<Self::Item<'w, 's>> {
2270 <&mut T as QueryData>::fetch(state, fetch, entity, table_row)
2271 }
2272
2273 fn iter_access(state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
2274 iter::once(EcsAccessType::Component(EcsAccessLevel::Write(*state)))
2275 }
2276}
2277
2278impl<T: Component<Mutability = Mutable>> ReleaseStateQueryData for Mut<'_, T> {
2279 fn release_state<'w>(item: Self::Item<'w, '_>) -> Self::Item<'w, 'static> {
2280 item
2281 }
2282}
2283
2284impl<T: Component<Mutability = Mutable>> ArchetypeQueryData for Mut<'_, T> {}
2285
2286#[doc(hidden)]
2287pub struct OptionFetch<'w, T: WorldQuery> {
2288 fetch: T::Fetch<'w>,
2289 matches: bool,
2290}
2291
2292impl<T: WorldQuery> Clone for OptionFetch<'_, T> {
2293 fn clone(&self) -> Self {
2294 Self {
2295 fetch: self.fetch.clone(),
2296 matches: self.matches,
2297 }
2298 }
2299}
2300
2301unsafe impl<T: WorldQuery> WorldQuery for Option<T> {
2306 type Fetch<'w> = OptionFetch<'w, T>;
2307 type State = T::State;
2308
2309 fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
2310 OptionFetch {
2311 fetch: T::shrink_fetch(fetch.fetch),
2312 matches: fetch.matches,
2313 }
2314 }
2315
2316 #[inline]
2317 unsafe fn init_fetch<'w, 's>(
2318 world: UnsafeWorldCell<'w>,
2319 state: &'s T::State,
2320 last_run: Tick,
2321 this_run: Tick,
2322 ) -> OptionFetch<'w, T> {
2323 OptionFetch {
2324 fetch: unsafe { T::init_fetch(world, state, last_run, this_run) },
2326 matches: false,
2327 }
2328 }
2329
2330 const IS_DENSE: bool = T::IS_DENSE;
2331
2332 #[inline]
2333 unsafe fn set_archetype<'w, 's>(
2334 fetch: &mut OptionFetch<'w, T>,
2335 state: &'s T::State,
2336 archetype: &'w Archetype,
2337 table: &'w Table,
2338 ) {
2339 fetch.matches = T::matches_component_set(state, &|id| archetype.contains(id));
2340 if fetch.matches {
2341 unsafe {
2343 T::set_archetype(&mut fetch.fetch, state, archetype, table);
2344 }
2345 }
2346 }
2347
2348 #[inline]
2349 unsafe fn set_table<'w, 's>(
2350 fetch: &mut OptionFetch<'w, T>,
2351 state: &'s T::State,
2352 table: &'w Table,
2353 ) {
2354 fetch.matches = T::matches_component_set(state, &|id| table.has_column(id));
2355 if fetch.matches {
2356 unsafe {
2358 T::set_table(&mut fetch.fetch, state, table);
2359 }
2360 }
2361 }
2362
2363 fn update_component_access(state: &T::State, access: &mut FilteredAccess) {
2364 let mut intermediate = access.clone();
2374 T::update_component_access(state, &mut intermediate);
2375 access.extend_access(&intermediate);
2376 }
2377
2378 fn init_state(world: &mut World) -> T::State {
2379 T::init_state(world)
2380 }
2381
2382 fn get_state(components: &Components) -> Option<Self::State> {
2383 T::get_state(components)
2384 }
2385
2386 fn matches_component_set(
2387 _state: &T::State,
2388 _set_contains_id: &impl Fn(ComponentId) -> bool,
2389 ) -> bool {
2390 true
2391 }
2392}
2393
2394unsafe impl<T: QueryData> QueryData for Option<T> {
2396 const IS_READ_ONLY: bool = T::IS_READ_ONLY;
2397 const IS_ARCHETYPAL: bool = true;
2400 type ReadOnly = Option<T::ReadOnly>;
2401 type Item<'w, 's> = Option<T::Item<'w, 's>>;
2402
2403 fn shrink<'wlong: 'wshort, 'wshort, 's>(
2404 item: Self::Item<'wlong, 's>,
2405 ) -> Self::Item<'wshort, 's> {
2406 item.map(T::shrink)
2407 }
2408
2409 #[inline(always)]
2410 unsafe fn fetch<'w, 's>(
2411 state: &'s Self::State,
2412 fetch: &mut Self::Fetch<'w>,
2413 entity: Entity,
2414 table_row: TableRow,
2415 ) -> Option<Self::Item<'w, 's>> {
2416 Some(
2417 fetch
2418 .matches
2419 .then(|| unsafe { T::fetch(state, &mut fetch.fetch, entity, table_row) })
2421 .flatten(),
2422 )
2423 }
2424
2425 fn iter_access(state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
2426 T::iter_access(state)
2427 }
2428}
2429
2430unsafe impl<T: ReadOnlyQueryData> ReadOnlyQueryData for Option<T> {}
2432
2433impl<T: ReleaseStateQueryData> ReleaseStateQueryData for Option<T> {
2434 fn release_state<'w>(item: Self::Item<'w, '_>) -> Self::Item<'w, 'static> {
2435 item.map(T::release_state)
2436 }
2437}
2438
2439impl<T: QueryData> ArchetypeQueryData for Option<T> {}
2442
2443pub struct Has<T>(PhantomData<T>);
2507
2508impl<T> core::fmt::Debug for Has<T> {
2509 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> {
2510 write!(f, "Has<{}>", DebugName::type_name::<T>())
2511 }
2512}
2513
2514unsafe impl<T: Component> WorldQuery for Has<T> {
2518 type Fetch<'w> = bool;
2519 type State = ComponentId;
2520
2521 fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
2522 fetch
2523 }
2524
2525 #[inline]
2526 unsafe fn init_fetch<'w, 's>(
2527 _world: UnsafeWorldCell<'w>,
2528 _state: &'s Self::State,
2529 _last_run: Tick,
2530 _this_run: Tick,
2531 ) -> Self::Fetch<'w> {
2532 false
2533 }
2534
2535 const IS_DENSE: bool = {
2536 match T::STORAGE_TYPE {
2537 StorageType::Table => true,
2538 StorageType::SparseSet => false,
2539 }
2540 };
2541
2542 #[inline]
2543 unsafe fn set_archetype<'w, 's>(
2544 fetch: &mut Self::Fetch<'w>,
2545 state: &'s Self::State,
2546 archetype: &'w Archetype,
2547 _table: &Table,
2548 ) {
2549 *fetch = archetype.contains(*state);
2550 }
2551
2552 #[inline]
2553 unsafe fn set_table<'w, 's>(
2554 fetch: &mut Self::Fetch<'w>,
2555 state: &'s Self::State,
2556 table: &'w Table,
2557 ) {
2558 *fetch = table.has_column(*state);
2559 }
2560
2561 fn update_component_access(&component_id: &Self::State, access: &mut FilteredAccess) {
2562 access.access_mut().add_archetypal(component_id);
2563 }
2564
2565 fn init_state(world: &mut World) -> ComponentId {
2566 world.register_component::<T>()
2567 }
2568
2569 fn get_state(components: &Components) -> Option<Self::State> {
2570 components.component_id::<T>()
2571 }
2572
2573 fn matches_component_set(
2574 _state: &Self::State,
2575 _set_contains_id: &impl Fn(ComponentId) -> bool,
2576 ) -> bool {
2577 true
2579 }
2580}
2581
2582unsafe impl<T: Component> QueryData for Has<T> {
2584 const IS_READ_ONLY: bool = true;
2585 const IS_ARCHETYPAL: bool = true;
2586 type ReadOnly = Self;
2587 type Item<'w, 's> = bool;
2588
2589 fn shrink<'wlong: 'wshort, 'wshort, 's>(
2590 item: Self::Item<'wlong, 's>,
2591 ) -> Self::Item<'wshort, 's> {
2592 item
2593 }
2594
2595 #[inline(always)]
2596 unsafe fn fetch<'w, 's>(
2597 _state: &'s Self::State,
2598 fetch: &mut Self::Fetch<'w>,
2599 _entity: Entity,
2600 _table_row: TableRow,
2601 ) -> Option<Self::Item<'w, 's>> {
2602 Some(*fetch)
2603 }
2604
2605 fn iter_access(_state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
2606 iter::empty()
2607 }
2608}
2609
2610unsafe impl<T: Component> ReadOnlyQueryData for Has<T> {}
2612
2613impl<T: Component> ReleaseStateQueryData for Has<T> {
2614 fn release_state<'w>(item: Self::Item<'w, '_>) -> Self::Item<'w, 'static> {
2615 item
2616 }
2617}
2618
2619impl<T: Component> ArchetypeQueryData for Has<T> {}
2620
2621pub struct AnyOf<T>(PhantomData<T>);
2627
2628macro_rules! impl_tuple_query_data {
2629 ($(#[$meta:meta])* $(($name: ident, $item: ident, $state: ident)),*) => {
2630 #[expect(
2631 clippy::allow_attributes,
2632 reason = "This is a tuple-related macro; as such the lints below may not always apply."
2633 )]
2634 #[allow(
2635 non_snake_case,
2636 reason = "The names of some variables are provided by the macro's caller, not by us."
2637 )]
2638 #[allow(
2639 unused_variables,
2640 reason = "Zero-length tuples won't use any of the parameters."
2641 )]
2642 #[allow(
2643 clippy::unused_unit,
2644 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."
2645 )]
2646 $(#[$meta])*
2647 unsafe impl<$($name: QueryData),*> QueryData for ($($name,)*) {
2649 const IS_READ_ONLY: bool = true $(&& $name::IS_READ_ONLY)*;
2650 const IS_ARCHETYPAL: bool = true $(&& $name::IS_ARCHETYPAL)*;
2651 type ReadOnly = ($($name::ReadOnly,)*);
2652 type Item<'w, 's> = ($($name::Item<'w, 's>,)*);
2653
2654 fn shrink<'wlong: 'wshort, 'wshort, 's>(item: Self::Item<'wlong, 's>) -> Self::Item<'wshort, 's> {
2655 let ($($name,)*) = item;
2656 ($(
2657 $name::shrink($name),
2658 )*)
2659 }
2660
2661 #[inline]
2662 fn provide_extra_access(
2663 state: &mut Self::State,
2664 access: &mut Access,
2665 available_access: &Access,
2666 ) {
2667 let ($($name,)*) = state;
2668 $($name::provide_extra_access($name, access, available_access);)*
2669 }
2670
2671 #[inline(always)]
2672 unsafe fn fetch<'w, 's>(
2673 state: &'s Self::State,
2674 fetch: &mut Self::Fetch<'w>,
2675 entity: Entity,
2676 table_row: TableRow
2677 ) -> Option<Self::Item<'w, 's>> {
2678 let ($($state,)*) = state;
2679 let ($($name,)*) = fetch;
2680 Some(($(unsafe { $name::fetch($state, $name, entity, table_row) }?,)*))
2682 }
2683
2684 fn iter_access(state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
2685 let ($($name,)*) = state;
2686 iter::empty()$(.chain($name::iter_access($name)))*
2687 }
2688 }
2689
2690 $(#[$meta])*
2691 unsafe impl<$($name: ReadOnlyQueryData),*> ReadOnlyQueryData for ($($name,)*) {}
2693
2694 #[expect(
2695 clippy::allow_attributes,
2696 reason = "This is a tuple-related macro; as such the lints below may not always apply."
2697 )]
2698 #[allow(
2699 clippy::unused_unit,
2700 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."
2701 )]
2702 $(#[$meta])*
2703 impl<$($name: ReleaseStateQueryData),*> ReleaseStateQueryData for ($($name,)*) {
2704 fn release_state<'w>(($($item,)*): Self::Item<'w, '_>) -> Self::Item<'w, 'static> {
2705 ($($name::release_state($item),)*)
2706 }
2707 }
2708
2709 $(#[$meta])*
2710 impl<$($name: ArchetypeQueryData),*> ArchetypeQueryData for ($($name,)*) {}
2711 };
2712}
2713
2714macro_rules! impl_anytuple_fetch {
2715 ($(#[$meta:meta])* $(($name: ident, $state: ident, $item: ident)),*) => {
2716 $(#[$meta])*
2717 #[expect(
2718 clippy::allow_attributes,
2719 reason = "This is a tuple-related macro; as such the lints below may not always apply."
2720 )]
2721 #[allow(
2722 non_snake_case,
2723 reason = "The names of some variables are provided by the macro's caller, not by us."
2724 )]
2725 #[allow(
2726 unused_variables,
2727 reason = "Zero-length tuples won't use any of the parameters."
2728 )]
2729 #[allow(
2730 clippy::unused_unit,
2731 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."
2732 )]
2733 unsafe impl<$($name: WorldQuery),*> WorldQuery for AnyOf<($($name,)*)> {
2739 type Fetch<'w> = ($(($name::Fetch<'w>, bool),)*);
2740 type State = ($($name::State,)*);
2741
2742 fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
2743 let ($($name,)*) = fetch;
2744 ($(
2745 ($name::shrink_fetch($name.0), $name.1),
2746 )*)
2747 }
2748
2749 #[inline]
2750 unsafe fn init_fetch<'w, 's>(_world: UnsafeWorldCell<'w>, state: &'s Self::State, _last_run: Tick, _this_run: Tick) -> Self::Fetch<'w> {
2751 let ($($name,)*) = state;
2752 ($(( unsafe { $name::init_fetch(_world, $name, _last_run, _this_run) }, false),)*)
2754 }
2755
2756 const IS_DENSE: bool = true $(&& $name::IS_DENSE)*;
2757
2758 #[inline]
2759 unsafe fn set_archetype<'w, 's>(
2760 _fetch: &mut Self::Fetch<'w>,
2761 _state: &'s Self::State,
2762 _archetype: &'w Archetype,
2763 _table: &'w Table
2764 ) {
2765 let ($($name,)*) = _fetch;
2766 let ($($state,)*) = _state;
2767 $(
2768 $name.1 = $name::matches_component_set($state, &|id| _archetype.contains(id));
2769 if $name.1 {
2770 unsafe { $name::set_archetype(&mut $name.0, $state, _archetype, _table); }
2772 }
2773 )*
2774 }
2775
2776 #[inline]
2777 unsafe fn set_table<'w, 's>(_fetch: &mut Self::Fetch<'w>, _state: &'s Self::State, _table: &'w Table) {
2778 let ($($name,)*) = _fetch;
2779 let ($($state,)*) = _state;
2780 $(
2781 $name.1 = $name::matches_component_set($state, &|id| _table.has_column(id));
2782 if $name.1 {
2783 unsafe { $name::set_table(&mut $name.0, $state, _table); }
2785 }
2786 )*
2787 }
2788
2789 fn update_component_access(state: &Self::State, access: &mut FilteredAccess) {
2790 let ($($name,)*) = state;
2792
2793 let mut _new_access = FilteredAccess::matches_nothing();
2794
2795 $(
2796 let mut intermediate = access.clone();
2800 $name::update_component_access($name, &mut intermediate);
2801 _new_access.append_or(&intermediate);
2802 )*
2803
2804 access.filter_sets = _new_access.filter_sets;
2806
2807 <($(Option<$name>,)*)>::update_component_access(state, access);
2813
2814 }
2815 fn init_state(world: &mut World) -> Self::State {
2816 ($($name::init_state(world),)*)
2817 }
2818 fn get_state(components: &Components) -> Option<Self::State> {
2819 Some(($($name::get_state(components)?,)*))
2820 }
2821
2822 fn matches_component_set(_state: &Self::State, _set_contains_id: &impl Fn(ComponentId) -> bool) -> bool {
2823 let ($($name,)*) = _state;
2824 false $(|| $name::matches_component_set($name, _set_contains_id))*
2825 }
2826 }
2827
2828 #[expect(
2829 clippy::allow_attributes,
2830 reason = "This is a tuple-related macro; as such the lints below may not always apply."
2831 )]
2832 #[allow(
2833 non_snake_case,
2834 reason = "The names of some variables are provided by the macro's caller, not by us."
2835 )]
2836 #[allow(
2837 unused_variables,
2838 reason = "Zero-length tuples won't use any of the parameters."
2839 )]
2840 #[allow(
2841 clippy::unused_unit,
2842 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."
2843 )]
2844 $(#[$meta])*
2845 unsafe impl<$($name: QueryData),*> QueryData for AnyOf<($($name,)*)> {
2847 const IS_READ_ONLY: bool = true $(&& $name::IS_READ_ONLY)*;
2848 const IS_ARCHETYPAL: bool = true $(&& $name::IS_ARCHETYPAL)*;
2849 type ReadOnly = AnyOf<($($name::ReadOnly,)*)>;
2850 type Item<'w, 's> = ($(Option<$name::Item<'w, 's>>,)*);
2851
2852 fn shrink<'wlong: 'wshort, 'wshort, 's>(item: Self::Item<'wlong, 's>) -> Self::Item<'wshort, 's> {
2853 let ($($name,)*) = item;
2854 ($(
2855 $name.map($name::shrink),
2856 )*)
2857 }
2858
2859 #[inline(always)]
2860 unsafe fn fetch<'w, 's>(
2861 _state: &'s Self::State,
2862 _fetch: &mut Self::Fetch<'w>,
2863 _entity: Entity,
2864 _table_row: TableRow
2865 ) -> Option<Self::Item<'w, 's>> {
2866 let ($($name,)*) = _fetch;
2867 let ($($state,)*) = _state;
2868 let result = ($(
2869 $name.1.then(|| unsafe { $name::fetch($state, &mut $name.0, _entity, _table_row) }).flatten(),
2871 )*);
2872 (Self::IS_ARCHETYPAL
2875 || !matches!(result, ($(Option::<QueryItem<$name>>::None,)*))
2879 || !(false $(|| $name.1)*))
2883 .then_some(result)
2884 }
2885
2886 fn iter_access(state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
2887 let ($($name,)*) = state;
2888 iter::empty()$(.chain($name::iter_access($name)))*
2889 }
2890 }
2891
2892 $(#[$meta])*
2893 unsafe impl<$($name: ReadOnlyQueryData),*> ReadOnlyQueryData for AnyOf<($($name,)*)> {}
2895
2896 #[expect(
2897 clippy::allow_attributes,
2898 reason = "This is a tuple-related macro; as such the lints below may not always apply."
2899 )]
2900 #[allow(
2901 clippy::unused_unit,
2902 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."
2903 )]
2904 impl<$($name: ReleaseStateQueryData),*> ReleaseStateQueryData for AnyOf<($($name,)*)> {
2905 fn release_state<'w>(($($item,)*): Self::Item<'w, '_>) -> Self::Item<'w, 'static> {
2906 ($($item.map(|$item| $name::release_state($item)),)*)
2907 }
2908 }
2909
2910 $(#[$meta])*
2911 impl<$($name: ArchetypeQueryData),*> ArchetypeQueryData for AnyOf<($($name,)*)> {}
2912 };
2913}
2914
2915all_tuples!(
2916 #[doc(fake_variadic)]
2917 impl_tuple_query_data,
2918 0,
2919 15,
2920 F,
2921 i,
2922 s
2923);
2924all_tuples!(
2925 #[doc(fake_variadic)]
2926 impl_anytuple_fetch,
2927 0,
2928 15,
2929 F,
2930 S,
2931 i
2932);
2933
2934pub(crate) struct NopWorldQuery<D: QueryData>(PhantomData<D>);
2938
2939unsafe impl<D: QueryData> WorldQuery for NopWorldQuery<D> {
2943 type Fetch<'w> = ();
2944 type State = D::State;
2945
2946 fn shrink_fetch<'wlong: 'wshort, 'wshort>(_fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
2947 }
2948
2949 #[inline(always)]
2950 unsafe fn init_fetch(
2951 _world: UnsafeWorldCell,
2952 _state: &D::State,
2953 _last_run: Tick,
2954 _this_run: Tick,
2955 ) {
2956 }
2957
2958 const IS_DENSE: bool = D::IS_DENSE;
2959
2960 #[inline(always)]
2961 unsafe fn set_archetype(
2962 _fetch: &mut (),
2963 _state: &D::State,
2964 _archetype: &Archetype,
2965 _tables: &Table,
2966 ) {
2967 }
2968
2969 #[inline(always)]
2970 unsafe fn set_table<'w>(_fetch: &mut (), _state: &D::State, _table: &Table) {}
2971
2972 fn update_component_access(_state: &D::State, _access: &mut FilteredAccess) {}
2973
2974 fn init_state(world: &mut World) -> Self::State {
2975 D::init_state(world)
2976 }
2977
2978 fn get_state(components: &Components) -> Option<Self::State> {
2979 D::get_state(components)
2980 }
2981
2982 fn matches_component_set(
2983 state: &Self::State,
2984 set_contains_id: &impl Fn(ComponentId) -> bool,
2985 ) -> bool {
2986 D::matches_component_set(state, set_contains_id)
2987 }
2988}
2989
2990unsafe impl<D: QueryData> QueryData for NopWorldQuery<D> {
2992 const IS_READ_ONLY: bool = true;
2993 const IS_ARCHETYPAL: bool = true;
2994 type ReadOnly = Self;
2995 type Item<'w, 's> = ();
2996
2997 fn shrink<'wlong: 'wshort, 'wshort, 's>(
2998 _item: Self::Item<'wlong, 's>,
2999 ) -> Self::Item<'wshort, 's> {
3000 }
3001
3002 #[inline(always)]
3003 unsafe fn fetch<'w, 's>(
3004 _state: &'s Self::State,
3005 _fetch: &mut Self::Fetch<'w>,
3006 _entity: Entity,
3007 _table_row: TableRow,
3008 ) -> Option<Self::Item<'w, 's>> {
3009 Some(())
3010 }
3011
3012 fn iter_access(_state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
3013 iter::empty()
3014 }
3015}
3016
3017unsafe impl<D: QueryData> ReadOnlyQueryData for NopWorldQuery<D> {}
3019
3020impl<D: QueryData> ReleaseStateQueryData for NopWorldQuery<D> {
3021 fn release_state<'w>(_item: Self::Item<'w, '_>) -> Self::Item<'w, 'static> {}
3022}
3023
3024impl<D: QueryData> ArchetypeQueryData for NopWorldQuery<D> {}
3025
3026unsafe impl<T: ?Sized> WorldQuery for PhantomData<T> {
3030 type Fetch<'w> = ();
3031
3032 type State = ();
3033
3034 fn shrink_fetch<'wlong: 'wshort, 'wshort>(_fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
3035 }
3036
3037 unsafe fn init_fetch<'w, 's>(
3038 _world: UnsafeWorldCell<'w>,
3039 _state: &'s Self::State,
3040 _last_run: Tick,
3041 _this_run: Tick,
3042 ) -> Self::Fetch<'w> {
3043 }
3044
3045 const IS_DENSE: bool = true;
3048
3049 unsafe fn set_archetype<'w, 's>(
3050 _fetch: &mut Self::Fetch<'w>,
3051 _state: &'s Self::State,
3052 _archetype: &'w Archetype,
3053 _table: &'w Table,
3054 ) {
3055 }
3056
3057 unsafe fn set_table<'w, 's>(
3058 _fetch: &mut Self::Fetch<'w>,
3059 _state: &'s Self::State,
3060 _table: &'w Table,
3061 ) {
3062 }
3063
3064 fn update_component_access(_state: &Self::State, _access: &mut FilteredAccess) {}
3065
3066 fn init_state(_world: &mut World) -> Self::State {}
3067
3068 fn get_state(_components: &Components) -> Option<Self::State> {
3069 Some(())
3070 }
3071
3072 fn matches_component_set(
3073 _state: &Self::State,
3074 _set_contains_id: &impl Fn(ComponentId) -> bool,
3075 ) -> bool {
3076 true
3077 }
3078}
3079
3080unsafe impl<T: ?Sized> QueryData for PhantomData<T> {
3082 const IS_READ_ONLY: bool = true;
3083 const IS_ARCHETYPAL: bool = true;
3084 type ReadOnly = Self;
3085 type Item<'w, 's> = ();
3086
3087 fn shrink<'wlong: 'wshort, 'wshort, 's>(
3088 _item: Self::Item<'wlong, 's>,
3089 ) -> Self::Item<'wshort, 's> {
3090 }
3091
3092 unsafe fn fetch<'w, 's>(
3093 _state: &'s Self::State,
3094 _fetch: &mut Self::Fetch<'w>,
3095 _entity: Entity,
3096 _table_row: TableRow,
3097 ) -> Option<Self::Item<'w, 's>> {
3098 Some(())
3099 }
3100
3101 fn iter_access(_state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
3102 iter::empty()
3103 }
3104}
3105
3106unsafe impl<T: ?Sized> ReadOnlyQueryData for PhantomData<T> {}
3108
3109impl<T: ?Sized> ReleaseStateQueryData for PhantomData<T> {
3110 fn release_state<'w>(_item: Self::Item<'w, '_>) -> Self::Item<'w, 'static> {}
3111}
3112
3113impl<T: ?Sized> ArchetypeQueryData for PhantomData<T> {}
3114
3115pub(super) union StorageSwitch<C: Component, T: Copy, S: Copy> {
3118 table: T,
3120 sparse_set: S,
3122 _marker: PhantomData<C>,
3123}
3124
3125impl<C: Component, T: Copy, S: Copy> StorageSwitch<C, T, S> {
3126 pub fn new(table: impl FnOnce() -> T, sparse_set: impl FnOnce() -> S) -> Self {
3129 match C::STORAGE_TYPE {
3130 StorageType::Table => Self { table: table() },
3131 StorageType::SparseSet => Self {
3132 sparse_set: sparse_set(),
3133 },
3134 }
3135 }
3136
3137 #[inline]
3147 pub unsafe fn set_table(&mut self, table: T) {
3148 match C::STORAGE_TYPE {
3149 StorageType::Table => self.table = table,
3150 _ => {
3151 #[cfg(debug_assertions)]
3152 unreachable!();
3153 #[cfg(not(debug_assertions))]
3154 core::hint::unreachable_unchecked()
3155 }
3156 }
3157 }
3158
3159 pub fn extract<R>(&self, table: impl FnOnce(T) -> R, sparse_set: impl FnOnce(S) -> R) -> R {
3162 match C::STORAGE_TYPE {
3163 StorageType::Table => table(
3164 unsafe { self.table },
3166 ),
3167 StorageType::SparseSet => sparse_set(
3168 unsafe { self.sparse_set },
3170 ),
3171 }
3172 }
3173}
3174
3175impl<C: Component, T: Copy, S: Copy> Clone for StorageSwitch<C, T, S> {
3176 fn clone(&self) -> Self {
3177 *self
3178 }
3179}
3180
3181impl<C: Component, T: Copy, S: Copy> Copy for StorageSwitch<C, T, S> {}
3182
3183#[cfg(test)]
3184mod tests {
3185 use super::*;
3186 use crate::change_detection::DetectChanges;
3187 use crate::system::{assert_is_system, Query};
3188 use bevy_ecs::prelude::Schedule;
3189 use bevy_ecs_macros::QueryData;
3190
3191 #[derive(Component)]
3192 pub struct A;
3193
3194 #[derive(Component)]
3195 pub struct B;
3196
3197 #[test]
3199 fn world_query_struct_variants() {
3200 #[derive(QueryData)]
3201 pub struct NamedQuery {
3202 id: Entity,
3203 a: &'static A,
3204 }
3205
3206 #[derive(QueryData)]
3207 pub struct TupleQuery(&'static A, &'static B);
3208
3209 #[derive(QueryData)]
3210 pub struct UnitQuery;
3211
3212 fn my_system(_: Query<(NamedQuery, TupleQuery, UnitQuery)>) {}
3213
3214 assert_is_system(my_system);
3215 }
3216
3217 #[test]
3219 fn world_query_phantom_data() {
3220 #[derive(QueryData)]
3221 pub struct IgnoredQuery<Marker> {
3222 id: Entity,
3223 _marker: PhantomData<Marker>,
3224 }
3225
3226 fn ignored_system(_: Query<IgnoredQuery<()>>) {}
3227
3228 assert_is_system(ignored_system);
3229 }
3230
3231 #[test]
3232 fn derive_release_state() {
3233 struct NonReleaseQueryData;
3234
3235 unsafe impl WorldQuery for NonReleaseQueryData {
3239 type Fetch<'w> = ();
3240 type State = ();
3241
3242 fn shrink_fetch<'wlong: 'wshort, 'wshort>(
3243 _: Self::Fetch<'wlong>,
3244 ) -> Self::Fetch<'wshort> {
3245 }
3246
3247 unsafe fn init_fetch<'w, 's>(
3248 _world: UnsafeWorldCell<'w>,
3249 _state: &'s Self::State,
3250 _last_run: Tick,
3251 _this_run: Tick,
3252 ) -> Self::Fetch<'w> {
3253 }
3254
3255 const IS_DENSE: bool = true;
3256
3257 #[inline]
3258 unsafe fn set_archetype<'w, 's>(
3259 _fetch: &mut Self::Fetch<'w>,
3260 _state: &'s Self::State,
3261 _archetype: &'w Archetype,
3262 _table: &Table,
3263 ) {
3264 }
3265
3266 #[inline]
3267 unsafe fn set_table<'w, 's>(
3268 _fetch: &mut Self::Fetch<'w>,
3269 _state: &'s Self::State,
3270 _table: &'w Table,
3271 ) {
3272 }
3273
3274 fn update_component_access(_state: &Self::State, _access: &mut FilteredAccess) {}
3275
3276 fn init_state(_world: &mut World) {}
3277
3278 fn get_state(_components: &Components) -> Option<()> {
3279 Some(())
3280 }
3281
3282 fn matches_component_set(
3283 _state: &Self::State,
3284 _set_contains_id: &impl Fn(ComponentId) -> bool,
3285 ) -> bool {
3286 true
3287 }
3288 }
3289
3290 unsafe impl QueryData for NonReleaseQueryData {
3292 type ReadOnly = Self;
3293 const IS_READ_ONLY: bool = true;
3294 const IS_ARCHETYPAL: bool = true;
3295
3296 type Item<'w, 's> = ();
3297
3298 fn shrink<'wlong: 'wshort, 'wshort, 's>(
3299 _item: Self::Item<'wlong, 's>,
3300 ) -> Self::Item<'wshort, 's> {
3301 }
3302
3303 #[inline(always)]
3304 unsafe fn fetch<'w, 's>(
3305 _state: &'s Self::State,
3306 _fetch: &mut Self::Fetch<'w>,
3307 _entity: Entity,
3308 _table_row: TableRow,
3309 ) -> Option<Self::Item<'w, 's>> {
3310 Some(())
3311 }
3312
3313 fn iter_access(_state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
3314 iter::empty()
3315 }
3316 }
3317
3318 unsafe impl ReadOnlyQueryData for NonReleaseQueryData {}
3320
3321 impl ArchetypeQueryData for NonReleaseQueryData {}
3322
3323 #[derive(QueryData)]
3324 pub struct DerivedNonReleaseRead {
3325 non_release: NonReleaseQueryData,
3326 a: &'static A,
3327 }
3328
3329 #[derive(QueryData)]
3330 #[query_data(mutable)]
3331 pub struct DerivedNonReleaseMutable {
3332 non_release: NonReleaseQueryData,
3333 a: &'static mut A,
3334 }
3335
3336 #[derive(QueryData)]
3337 pub struct DerivedReleaseRead {
3338 a: &'static A,
3339 }
3340
3341 #[derive(QueryData)]
3342 #[query_data(mutable)]
3343 pub struct DerivedReleaseMutable {
3344 a: &'static mut A,
3345 }
3346
3347 fn assert_is_release_state<Q: ReleaseStateQueryData>() {}
3348
3349 assert_is_release_state::<DerivedReleaseRead>();
3350 assert_is_release_state::<DerivedReleaseMutable>();
3351 }
3352
3353 #[test]
3356 fn read_only_field_visibility() {
3357 mod private {
3358 use super::*;
3359
3360 #[derive(QueryData)]
3361 #[query_data(mutable)]
3362 pub struct D {
3363 pub a: &'static mut A,
3364 }
3365 }
3366
3367 let _ = private::DReadOnly { a: &A };
3368
3369 fn my_system(query: Query<private::D>) {
3370 for q in &query {
3371 let _ = &q.a;
3372 }
3373 }
3374
3375 assert_is_system(my_system);
3376 }
3377
3378 #[test]
3382 fn world_query_metadata_collision() {
3383 #[derive(QueryData)]
3386 pub struct Client<S: ClientState> {
3387 pub state: &'static S,
3388 pub fetch: &'static ClientFetch,
3389 }
3390
3391 pub trait ClientState: Component {}
3392
3393 #[derive(Component)]
3394 pub struct ClientFetch;
3395
3396 #[derive(Component)]
3397 pub struct C;
3398
3399 impl ClientState for C {}
3400
3401 fn client_system(_: Query<Client<C>>) {}
3402
3403 assert_is_system(client_system);
3404 }
3405
3406 #[test]
3410 fn test_entity_ref_query_with_ticks() {
3411 #[derive(Component)]
3412 pub struct C;
3413
3414 fn system(query: Query<EntityRef>) {
3415 for entity_ref in &query {
3416 if let Some(c) = entity_ref.get_ref::<C>()
3417 && !c.is_added()
3418 {
3419 panic!("Expected C to be added");
3420 }
3421 }
3422 }
3423
3424 let mut world = World::new();
3425 let mut schedule = Schedule::default();
3426 schedule.add_systems(system);
3427 world.spawn(C);
3428
3429 world.clear_trackers();
3431
3432 schedule.run(&mut world);
3434 }
3435}