1use crate::{
2 archetype::{Archetype, Archetypes},
3 bundle::Bundle,
4 change_detection::{
5 AtomicTick, ComponentTicksMut, ComponentTicksRef, ContiguousComponentTicksMut,
6 ContiguousComponentTicksRef, ContiguousMut, ContiguousRef, MaybeLocation, Tick,
7 },
8 component::{Component, ComponentId, Components, Mutable, StorageType},
9 entity::{Entities, Entity, EntityLocation},
10 query::{
11 access_iter::{EcsAccessLevel, EcsAccessType},
12 Access, DebugCheckedUnwrap, FilteredAccess, FilteredAccessSet, QueryFilter, QueryState,
13 WorldQuery,
14 },
15 storage::{ComponentSparseSet, Table, TableRow},
16 system::Query,
17 world::{
18 unsafe_world_cell::UnsafeWorldCell, EntityMut, EntityMutExcept, EntityRef, EntityRefExcept,
19 FilteredEntityMut, FilteredEntityRef, Mut, Ref, World,
20 },
21};
22use bevy_ptr::{ThinSlicePtr, UnsafeCellDeref};
23use bevy_utils::prelude::DebugName;
24use core::{cell::UnsafeCell, iter, marker::PhantomData, ops::Range, panic::Location};
25use variadics_please::all_tuples;
26
27#[diagnostic::on_unimplemented(
320 message = "`{Self}` is not valid to request as data in a `Query`",
321 label = "invalid `Query` data",
322 note = "if `{Self}` is a component type, try using `&{Self}` or `&mut {Self}`"
323)]
324pub unsafe trait QueryData: WorldQuery {
325 const IS_READ_ONLY: bool;
327
328 const IS_ARCHETYPAL: bool;
336
337 type ReadOnly: ReadOnlyQueryData<State = <Self as WorldQuery>::State>;
339
340 type Item<'w, 's>;
344
345 fn shrink<'wlong: 'wshort, 'wshort, 's>(
347 item: Self::Item<'wlong, 's>,
348 ) -> Self::Item<'wshort, 's>;
349
350 fn provide_extra_access(
360 _state: &mut Self::State,
361 _access: &mut Access,
362 _available_access: &Access,
363 ) {
364 }
365
366 unsafe fn fetch<'w, 's>(
383 state: &'s Self::State,
384 fetch: &mut Self::Fetch<'w>,
385 entity: Entity,
386 table_row: TableRow,
387 ) -> Option<Self::Item<'w, 's>>;
388
389 fn iter_access(state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>>;
393}
394
395#[diagnostic::on_unimplemented(
405 message = "`{Self}` cannot be iterated contiguously",
406 label = "invalid contiguous `Query` data",
407 note = "if `{Self}` is a custom query type, using `QueryData` derive macro, ensure that the `#[query_data(contiguous(target))]` attribute is added"
408)]
409pub trait ContiguousQueryData: ArchetypeQueryData + IterQueryData {
410 type Contiguous<'w, 's>;
413
414 unsafe fn fetch_contiguous<'w, 's>(
427 state: &'s Self::State,
428 fetch: &mut Self::Fetch<'w>,
429 entities: &'w [Entity],
430 range: Range<u32>,
431 ) -> Self::Contiguous<'w, 's>;
432}
433
434pub unsafe trait IterQueryData: QueryData {}
461
462pub unsafe trait ReadOnlyQueryData: IterQueryData<ReadOnly = Self> {}
468
469pub unsafe trait SingleEntityQueryData: IterQueryData {}
478
479pub type QueryItem<'w, 's, Q> = <Q as QueryData>::Item<'w, 's>;
481pub type ROQueryItem<'w, 's, D> = QueryItem<'w, 's, <D as QueryData>::ReadOnly>;
483
484pub trait ReleaseStateQueryData: QueryData {
491 fn release_state<'w>(item: Self::Item<'w, '_>) -> Self::Item<'w, 'static>;
493}
494
495pub trait ArchetypeQueryData: QueryData {}
502
503unsafe impl WorldQuery for Entity {
507 type Fetch<'w> = ();
508 type State = ();
509
510 fn shrink_fetch<'wlong: 'wshort, 'wshort>(_: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {}
511
512 unsafe fn init_fetch<'w, 's>(
513 _world: UnsafeWorldCell<'w>,
514 _state: &'s Self::State,
515 _last_run: Tick,
516 _this_run: Tick,
517 ) -> Self::Fetch<'w> {
518 }
519
520 const IS_DENSE: bool = true;
521
522 #[inline]
523 unsafe fn set_archetype<'w, 's>(
524 _fetch: &mut Self::Fetch<'w>,
525 _state: &'s Self::State,
526 _archetype: &'w Archetype,
527 _table: &Table,
528 ) {
529 }
530
531 #[inline]
532 unsafe fn set_table<'w, 's>(
533 _fetch: &mut Self::Fetch<'w>,
534 _state: &'s Self::State,
535 _table: &'w Table,
536 ) {
537 }
538
539 fn update_component_access(_state: &Self::State, _access: &mut FilteredAccess) {}
540
541 fn init_nested_access(
542 _state: &Self::State,
543 _system_name: Option<&str>,
544 _component_access_set: &mut FilteredAccessSet,
545 _world: UnsafeWorldCell,
546 ) {
547 }
548
549 fn init_state(_world: &mut World) {}
550
551 fn get_state(_components: &Components) -> Option<()> {
552 Some(())
553 }
554
555 fn matches_component_set(
556 _state: &Self::State,
557 _set_contains_id: &impl Fn(ComponentId) -> bool,
558 ) -> bool {
559 true
560 }
561
562 fn update_archetypes(_state: &mut Self::State, _world: UnsafeWorldCell) {}
563}
564
565unsafe impl QueryData for Entity {
567 const IS_READ_ONLY: bool = true;
568 const IS_ARCHETYPAL: bool = true;
569 type ReadOnly = Self;
570
571 type Item<'w, 's> = Entity;
572
573 fn shrink<'wlong: 'wshort, 'wshort, 's>(
574 item: Self::Item<'wlong, 's>,
575 ) -> Self::Item<'wshort, 's> {
576 item
577 }
578
579 #[inline(always)]
580 unsafe fn fetch<'w, 's>(
581 _state: &'s Self::State,
582 _fetch: &mut Self::Fetch<'w>,
583 entity: Entity,
584 _table_row: TableRow,
585 ) -> Option<Self::Item<'w, 's>> {
586 Some(entity)
587 }
588
589 fn iter_access(_state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
590 iter::empty()
591 }
592}
593
594unsafe impl IterQueryData for Entity {}
596
597unsafe impl ReadOnlyQueryData for Entity {}
599
600unsafe impl SingleEntityQueryData for Entity {}
602
603impl ReleaseStateQueryData for Entity {
604 fn release_state<'w>(item: Self::Item<'w, '_>) -> Self::Item<'w, 'static> {
605 item
606 }
607}
608
609impl ArchetypeQueryData for Entity {}
610
611impl ContiguousQueryData for Entity {
612 type Contiguous<'w, 's> = &'w [Entity];
613
614 unsafe fn fetch_contiguous<'w, 's>(
615 _state: &'s Self::State,
616 _fetch: &mut Self::Fetch<'w>,
617 entities: &'w [Entity],
618 range: Range<u32>,
619 ) -> Self::Contiguous<'w, 's> {
620 &entities[(range.start as usize)..(range.end as usize)]
621 }
622}
623
624unsafe impl WorldQuery for EntityLocation {
628 type Fetch<'w> = &'w Entities;
629 type State = ();
630
631 fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
632 fetch
633 }
634
635 unsafe fn init_fetch<'w, 's>(
636 world: UnsafeWorldCell<'w>,
637 _state: &'s Self::State,
638 _last_run: Tick,
639 _this_run: Tick,
640 ) -> Self::Fetch<'w> {
641 world.entities()
642 }
643
644 const IS_DENSE: bool = true;
647
648 #[inline]
649 unsafe fn set_archetype<'w, 's>(
650 _fetch: &mut Self::Fetch<'w>,
651 _state: &'s Self::State,
652 _archetype: &'w Archetype,
653 _table: &Table,
654 ) {
655 }
656
657 #[inline]
658 unsafe fn set_table<'w, 's>(
659 _fetch: &mut Self::Fetch<'w>,
660 _state: &'s Self::State,
661 _table: &'w Table,
662 ) {
663 }
664
665 fn update_component_access(_state: &Self::State, _access: &mut FilteredAccess) {}
666
667 fn init_nested_access(
668 _state: &Self::State,
669 _system_name: Option<&str>,
670 _component_access_set: &mut FilteredAccessSet,
671 _world: UnsafeWorldCell,
672 ) {
673 }
674
675 fn init_state(_world: &mut World) {}
676
677 fn get_state(_components: &Components) -> Option<()> {
678 Some(())
679 }
680
681 fn matches_component_set(
682 _state: &Self::State,
683 _set_contains_id: &impl Fn(ComponentId) -> bool,
684 ) -> bool {
685 true
686 }
687
688 fn update_archetypes(_state: &mut Self::State, _world: UnsafeWorldCell) {}
689}
690
691unsafe impl QueryData for EntityLocation {
693 const IS_READ_ONLY: bool = true;
694 const IS_ARCHETYPAL: bool = true;
695 type ReadOnly = Self;
696 type Item<'w, 's> = EntityLocation;
697
698 fn shrink<'wlong: 'wshort, 'wshort, 's>(
699 item: Self::Item<'wlong, 's>,
700 ) -> Self::Item<'wshort, 's> {
701 item
702 }
703
704 #[inline(always)]
705 unsafe fn fetch<'w, 's>(
706 _state: &'s Self::State,
707 fetch: &mut Self::Fetch<'w>,
708 entity: Entity,
709 _table_row: TableRow,
710 ) -> Option<Self::Item<'w, 's>> {
711 Some(unsafe { fetch.get_spawned(entity).debug_checked_unwrap() })
713 }
714
715 fn iter_access(_state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
716 iter::empty()
717 }
718}
719
720unsafe impl IterQueryData for EntityLocation {}
722
723unsafe impl ReadOnlyQueryData for EntityLocation {}
725
726unsafe impl SingleEntityQueryData for EntityLocation {}
728
729impl ReleaseStateQueryData for EntityLocation {
730 fn release_state<'w>(item: Self::Item<'w, '_>) -> Self::Item<'w, 'static> {
731 item
732 }
733}
734
735impl ArchetypeQueryData for EntityLocation {}
736
737#[derive(Clone, Copy, Debug)]
774pub struct SpawnDetails {
775 spawned_by: MaybeLocation,
776 spawn_tick: Tick,
777 last_run: Tick,
778 this_run: Tick,
779}
780
781impl SpawnDetails {
782 pub fn is_spawned(self) -> bool {
785 self.is_spawned_after(self.last_run)
786 }
787
788 #[inline]
791 pub fn is_spawned_after(self, other: Tick) -> bool {
792 self.spawn_tick.is_newer_than(other, self.this_run)
793 }
794
795 pub fn spawn_tick(self) -> Tick {
797 self.spawn_tick
798 }
799
800 pub fn spawned_by(self) -> MaybeLocation {
802 self.spawned_by
803 }
804}
805
806#[doc(hidden)]
807#[derive(Clone)]
808pub struct SpawnDetailsFetch<'w> {
809 entities: &'w Entities,
810 last_run: Tick,
811 this_run: Tick,
812}
813
814unsafe impl WorldQuery for SpawnDetails {
817 type Fetch<'w> = SpawnDetailsFetch<'w>;
818 type State = ();
819
820 fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
821 fetch
822 }
823
824 unsafe fn init_fetch<'w, 's>(
825 world: UnsafeWorldCell<'w>,
826 _state: &'s Self::State,
827 last_run: Tick,
828 this_run: Tick,
829 ) -> Self::Fetch<'w> {
830 SpawnDetailsFetch {
831 entities: world.entities(),
832 last_run,
833 this_run,
834 }
835 }
836
837 const IS_DENSE: bool = true;
838
839 #[inline]
840 unsafe fn set_archetype<'w, 's>(
841 _fetch: &mut Self::Fetch<'w>,
842 _state: &'s Self::State,
843 _archetype: &'w Archetype,
844 _table: &'w Table,
845 ) {
846 }
847
848 #[inline]
849 unsafe fn set_table<'w, 's>(
850 _fetch: &mut Self::Fetch<'w>,
851 _state: &'s Self::State,
852 _table: &'w Table,
853 ) {
854 }
855
856 fn update_component_access(_state: &Self::State, _access: &mut FilteredAccess) {}
857
858 fn init_nested_access(
859 _state: &Self::State,
860 _system_name: Option<&str>,
861 _component_access_set: &mut FilteredAccessSet,
862 _world: UnsafeWorldCell,
863 ) {
864 }
865
866 fn init_state(_world: &mut World) {}
867
868 fn get_state(_components: &Components) -> Option<()> {
869 Some(())
870 }
871
872 fn matches_component_set(
873 _state: &Self::State,
874 _set_contains_id: &impl Fn(ComponentId) -> bool,
875 ) -> bool {
876 true
877 }
878
879 fn update_archetypes(_state: &mut Self::State, _world: UnsafeWorldCell) {}
880}
881
882unsafe impl QueryData for SpawnDetails {
886 const IS_READ_ONLY: bool = true;
887 const IS_ARCHETYPAL: bool = true;
888 type ReadOnly = Self;
889 type Item<'w, 's> = Self;
890
891 fn shrink<'wlong: 'wshort, 'wshort, 's>(
892 item: Self::Item<'wlong, 's>,
893 ) -> Self::Item<'wshort, 's> {
894 item
895 }
896
897 #[inline(always)]
898 unsafe fn fetch<'w, 's>(
899 _state: &'s Self::State,
900 fetch: &mut Self::Fetch<'w>,
901 entity: Entity,
902 _table_row: TableRow,
903 ) -> Option<Self::Item<'w, 's>> {
904 let (spawned_by, spawn_tick) = unsafe {
906 fetch
907 .entities
908 .entity_get_spawned_or_despawned_unchecked(entity)
909 };
910 Some(Self {
911 spawned_by,
912 spawn_tick,
913 last_run: fetch.last_run,
914 this_run: fetch.this_run,
915 })
916 }
917
918 fn iter_access(_state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
919 iter::empty()
920 }
921}
922
923unsafe impl IterQueryData for SpawnDetails {}
925
926unsafe impl ReadOnlyQueryData for SpawnDetails {}
928
929unsafe impl SingleEntityQueryData for SpawnDetails {}
931
932impl ReleaseStateQueryData for SpawnDetails {
933 fn release_state<'w>(item: Self::Item<'w, '_>) -> Self::Item<'w, 'static> {
934 item
935 }
936}
937
938impl ArchetypeQueryData for SpawnDetails {}
939
940#[derive(Copy, Clone)]
943#[doc(hidden)]
944pub struct EntityFetch<'w> {
945 world: UnsafeWorldCell<'w>,
946 last_run: Tick,
947 this_run: Tick,
948}
949
950unsafe impl<'a> WorldQuery for EntityRef<'a> {
955 type Fetch<'w> = EntityFetch<'w>;
956 type State = ();
957
958 fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
959 fetch
960 }
961
962 unsafe fn init_fetch<'w, 's>(
963 world: UnsafeWorldCell<'w>,
964 _state: &'s Self::State,
965 last_run: Tick,
966 this_run: Tick,
967 ) -> Self::Fetch<'w> {
968 EntityFetch {
969 world,
970 last_run,
971 this_run,
972 }
973 }
974
975 const IS_DENSE: bool = true;
976
977 #[inline]
978 unsafe fn set_archetype<'w, 's>(
979 _fetch: &mut Self::Fetch<'w>,
980 _state: &'s Self::State,
981 _archetype: &'w Archetype,
982 _table: &Table,
983 ) {
984 }
985
986 #[inline]
987 unsafe fn set_table<'w, 's>(
988 _fetch: &mut Self::Fetch<'w>,
989 _state: &'s Self::State,
990 _table: &'w Table,
991 ) {
992 }
993
994 fn update_component_access(_state: &Self::State, access: &mut FilteredAccess) {
995 assert!(
996 !access.access().has_any_write(),
997 "EntityRef conflicts with a previous access in this query. Shared access cannot coincide with exclusive access.",
998 );
999 access.read_all();
1000 }
1001
1002 fn init_nested_access(
1003 _state: &Self::State,
1004 _system_name: Option<&str>,
1005 _component_access_set: &mut FilteredAccessSet,
1006 _world: UnsafeWorldCell,
1007 ) {
1008 }
1009
1010 fn init_state(_world: &mut World) {}
1011
1012 fn get_state(_components: &Components) -> Option<()> {
1013 Some(())
1014 }
1015
1016 fn matches_component_set(
1017 _state: &Self::State,
1018 _set_contains_id: &impl Fn(ComponentId) -> bool,
1019 ) -> bool {
1020 true
1021 }
1022
1023 fn update_archetypes(_state: &mut Self::State, _world: UnsafeWorldCell) {}
1024}
1025
1026unsafe impl<'a> QueryData for EntityRef<'a> {
1028 const IS_READ_ONLY: bool = true;
1029 const IS_ARCHETYPAL: bool = true;
1030 type ReadOnly = Self;
1031 type Item<'w, 's> = EntityRef<'w>;
1032
1033 fn shrink<'wlong: 'wshort, 'wshort, 's>(
1034 item: Self::Item<'wlong, 's>,
1035 ) -> Self::Item<'wshort, 's> {
1036 item
1037 }
1038
1039 #[inline(always)]
1040 unsafe fn fetch<'w, 's>(
1041 _state: &'s Self::State,
1042 fetch: &mut Self::Fetch<'w>,
1043 entity: Entity,
1044 _table_row: TableRow,
1045 ) -> Option<Self::Item<'w, 's>> {
1046 let cell = unsafe {
1048 fetch
1049 .world
1050 .get_entity_with_ticks(entity, fetch.last_run, fetch.this_run)
1051 .debug_checked_unwrap()
1052 };
1053 Some(unsafe { EntityRef::new(cell) })
1055 }
1056
1057 fn iter_access(_state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
1058 iter::once(EcsAccessType::Component(EcsAccessLevel::ReadAll))
1059 }
1060}
1061
1062unsafe impl IterQueryData for EntityRef<'_> {}
1064
1065unsafe impl ReadOnlyQueryData for EntityRef<'_> {}
1067
1068unsafe impl SingleEntityQueryData for EntityRef<'_> {}
1070
1071impl ReleaseStateQueryData for EntityRef<'_> {
1072 fn release_state<'w>(item: Self::Item<'w, '_>) -> Self::Item<'w, 'static> {
1073 item
1074 }
1075}
1076
1077impl ArchetypeQueryData for EntityRef<'_> {}
1078
1079unsafe impl<'a> WorldQuery for EntityMut<'a> {
1081 type Fetch<'w> = EntityFetch<'w>;
1082 type State = ();
1083
1084 fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
1085 fetch
1086 }
1087
1088 unsafe fn init_fetch<'w, 's>(
1089 world: UnsafeWorldCell<'w>,
1090 _state: &'s Self::State,
1091 last_run: Tick,
1092 this_run: Tick,
1093 ) -> Self::Fetch<'w> {
1094 EntityFetch {
1095 world,
1096 last_run,
1097 this_run,
1098 }
1099 }
1100
1101 const IS_DENSE: bool = true;
1102
1103 #[inline]
1104 unsafe fn set_archetype<'w, 's>(
1105 _fetch: &mut Self::Fetch<'w>,
1106 _state: &'s Self::State,
1107 _archetype: &'w Archetype,
1108 _table: &Table,
1109 ) {
1110 }
1111
1112 #[inline]
1113 unsafe fn set_table<'w, 's>(
1114 _fetch: &mut Self::Fetch<'w>,
1115 _state: &'s Self::State,
1116 _table: &'w Table,
1117 ) {
1118 }
1119
1120 fn update_component_access(_state: &Self::State, access: &mut FilteredAccess) {
1121 assert!(
1122 !access.access().has_any_read(),
1123 "EntityMut conflicts with a previous access in this query. Exclusive access cannot coincide with any other accesses.",
1124 );
1125 access.write_all();
1126 }
1127
1128 fn init_nested_access(
1129 _state: &Self::State,
1130 _system_name: Option<&str>,
1131 _component_access_set: &mut FilteredAccessSet,
1132 _world: UnsafeWorldCell,
1133 ) {
1134 }
1135
1136 fn init_state(_world: &mut World) {}
1137
1138 fn get_state(_components: &Components) -> Option<()> {
1139 Some(())
1140 }
1141
1142 fn matches_component_set(
1143 _state: &Self::State,
1144 _set_contains_id: &impl Fn(ComponentId) -> bool,
1145 ) -> bool {
1146 true
1147 }
1148
1149 fn update_archetypes(_state: &mut Self::State, _world: UnsafeWorldCell) {}
1150}
1151
1152unsafe impl<'a> QueryData for EntityMut<'a> {
1154 const IS_READ_ONLY: bool = false;
1155 const IS_ARCHETYPAL: bool = true;
1156 type ReadOnly = EntityRef<'a>;
1157 type Item<'w, 's> = EntityMut<'w>;
1158
1159 fn shrink<'wlong: 'wshort, 'wshort, 's>(
1160 item: Self::Item<'wlong, 's>,
1161 ) -> Self::Item<'wshort, 's> {
1162 item
1163 }
1164
1165 #[inline(always)]
1166 unsafe fn fetch<'w, 's>(
1167 _state: &'s Self::State,
1168 fetch: &mut Self::Fetch<'w>,
1169 entity: Entity,
1170 _table_row: TableRow,
1171 ) -> Option<Self::Item<'w, 's>> {
1172 let cell = unsafe {
1174 fetch
1175 .world
1176 .get_entity_with_ticks(entity, fetch.last_run, fetch.this_run)
1177 .debug_checked_unwrap()
1178 };
1179 Some(unsafe { EntityMut::new(cell) })
1181 }
1182
1183 fn iter_access(_state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
1184 iter::once(EcsAccessType::Component(EcsAccessLevel::WriteAll))
1185 }
1186}
1187
1188unsafe impl IterQueryData for EntityMut<'_> {}
1190
1191unsafe impl SingleEntityQueryData for EntityMut<'_> {}
1193
1194impl ReleaseStateQueryData for EntityMut<'_> {
1195 fn release_state<'w>(item: Self::Item<'w, '_>) -> Self::Item<'w, 'static> {
1196 item
1197 }
1198}
1199
1200impl ArchetypeQueryData for EntityMut<'_> {}
1201
1202unsafe impl WorldQuery for FilteredEntityRef<'_, '_> {
1204 type Fetch<'w> = EntityFetch<'w>;
1205 type State = Access;
1206
1207 fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
1208 fetch
1209 }
1210
1211 const IS_DENSE: bool = true;
1212
1213 unsafe fn init_fetch<'w, 's>(
1214 world: UnsafeWorldCell<'w>,
1215 _state: &'s Self::State,
1216 last_run: Tick,
1217 this_run: Tick,
1218 ) -> Self::Fetch<'w> {
1219 EntityFetch {
1220 world,
1221 last_run,
1222 this_run,
1223 }
1224 }
1225
1226 #[inline]
1227 unsafe fn set_archetype<'w, 's>(
1228 _fetch: &mut Self::Fetch<'w>,
1229 _state: &'s Self::State,
1230 _: &'w Archetype,
1231 _table: &Table,
1232 ) {
1233 }
1234
1235 #[inline]
1236 unsafe fn set_table<'w, 's>(
1237 _fetch: &mut Self::Fetch<'w>,
1238 _state: &'s Self::State,
1239 _: &'w Table,
1240 ) {
1241 }
1242
1243 fn update_component_access(state: &Self::State, filtered_access: &mut FilteredAccess) {
1244 assert!(
1245 filtered_access.access().is_compatible(state),
1246 "FilteredEntityRef conflicts with a previous access in this query. Exclusive access cannot coincide with any other accesses.",
1247 );
1248 filtered_access.access.extend(state);
1249 }
1250
1251 fn init_nested_access(
1252 _state: &Self::State,
1253 _system_name: Option<&str>,
1254 _component_access_set: &mut FilteredAccessSet,
1255 _world: UnsafeWorldCell,
1256 ) {
1257 }
1258
1259 fn init_state(_world: &mut World) -> Self::State {
1260 Access::default()
1261 }
1262
1263 fn get_state(_components: &Components) -> Option<Self::State> {
1264 Some(Access::default())
1265 }
1266
1267 fn matches_component_set(
1268 _state: &Self::State,
1269 _set_contains_id: &impl Fn(ComponentId) -> bool,
1270 ) -> bool {
1271 true
1272 }
1273
1274 fn update_archetypes(_state: &mut Self::State, _world: UnsafeWorldCell) {}
1275}
1276
1277unsafe impl<'a, 'b> QueryData for FilteredEntityRef<'a, 'b> {
1279 const IS_READ_ONLY: bool = true;
1280 const IS_ARCHETYPAL: bool = true;
1281 type ReadOnly = Self;
1282 type Item<'w, 's> = FilteredEntityRef<'w, 's>;
1283
1284 fn shrink<'wlong: 'wshort, 'wshort, 's>(
1285 item: Self::Item<'wlong, 's>,
1286 ) -> Self::Item<'wshort, 's> {
1287 item
1288 }
1289
1290 #[inline]
1291 fn provide_extra_access(
1292 state: &mut Self::State,
1293 access: &mut Access,
1294 available_access: &Access,
1295 ) {
1296 state.clone_from(available_access);
1300 state.clear_writes();
1302 state.remove_conflicting_access(access);
1304 access.extend(state);
1307 }
1308
1309 #[inline(always)]
1310 unsafe fn fetch<'w, 's>(
1311 access: &'s Self::State,
1312 fetch: &mut Self::Fetch<'w>,
1313 entity: Entity,
1314 _table_row: TableRow,
1315 ) -> Option<Self::Item<'w, 's>> {
1316 let cell = unsafe {
1318 fetch
1319 .world
1320 .get_entity_with_ticks(entity, fetch.last_run, fetch.this_run)
1321 .debug_checked_unwrap()
1322 };
1323 Some(unsafe { FilteredEntityRef::new(cell, access) })
1325 }
1326
1327 fn iter_access(state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
1328 iter::once(EcsAccessType::Access(state))
1329 }
1330}
1331
1332unsafe impl IterQueryData for FilteredEntityRef<'_, '_> {}
1334
1335unsafe impl ReadOnlyQueryData for FilteredEntityRef<'_, '_> {}
1337
1338unsafe impl SingleEntityQueryData for FilteredEntityRef<'_, '_> {}
1340
1341impl ArchetypeQueryData for FilteredEntityRef<'_, '_> {}
1342
1343unsafe impl WorldQuery for FilteredEntityMut<'_, '_> {
1345 type Fetch<'w> = EntityFetch<'w>;
1346 type State = Access;
1347
1348 fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
1349 fetch
1350 }
1351
1352 const IS_DENSE: bool = true;
1353
1354 unsafe fn init_fetch<'w, 's>(
1355 world: UnsafeWorldCell<'w>,
1356 _state: &'s Self::State,
1357 last_run: Tick,
1358 this_run: Tick,
1359 ) -> Self::Fetch<'w> {
1360 EntityFetch {
1361 world,
1362 last_run,
1363 this_run,
1364 }
1365 }
1366
1367 #[inline]
1368 unsafe fn set_archetype<'w, 's>(
1369 _fetch: &mut Self::Fetch<'w>,
1370 _state: &'s Self::State,
1371 _: &'w Archetype,
1372 _table: &Table,
1373 ) {
1374 }
1375
1376 #[inline]
1377 unsafe fn set_table<'w, 's>(
1378 _fetch: &mut Self::Fetch<'w>,
1379 _state: &'s Self::State,
1380 _: &'w Table,
1381 ) {
1382 }
1383
1384 fn update_component_access(state: &Self::State, filtered_access: &mut FilteredAccess) {
1385 assert!(
1386 filtered_access.access().is_compatible(state),
1387 "FilteredEntityMut conflicts with a previous access in this query. Exclusive access cannot coincide with any other accesses.",
1388 );
1389 filtered_access.access.extend(state);
1390 }
1391
1392 fn init_nested_access(
1393 _state: &Self::State,
1394 _system_name: Option<&str>,
1395 _component_access_set: &mut FilteredAccessSet,
1396 _world: UnsafeWorldCell,
1397 ) {
1398 }
1399
1400 fn init_state(_world: &mut World) -> Self::State {
1401 Access::default()
1402 }
1403
1404 fn get_state(_components: &Components) -> Option<Self::State> {
1405 Some(Access::default())
1406 }
1407
1408 fn matches_component_set(
1409 _state: &Self::State,
1410 _set_contains_id: &impl Fn(ComponentId) -> bool,
1411 ) -> bool {
1412 true
1413 }
1414
1415 fn update_archetypes(_state: &mut Self::State, _world: UnsafeWorldCell) {}
1416}
1417
1418unsafe impl<'a, 'b> QueryData for FilteredEntityMut<'a, 'b> {
1420 const IS_READ_ONLY: bool = false;
1421 const IS_ARCHETYPAL: bool = true;
1422 type ReadOnly = FilteredEntityRef<'a, 'b>;
1423 type Item<'w, 's> = FilteredEntityMut<'w, 's>;
1424
1425 fn shrink<'wlong: 'wshort, 'wshort, 's>(
1426 item: Self::Item<'wlong, 's>,
1427 ) -> Self::Item<'wshort, 's> {
1428 item
1429 }
1430
1431 #[inline]
1432 fn provide_extra_access(
1433 state: &mut Self::State,
1434 access: &mut Access,
1435 available_access: &Access,
1436 ) {
1437 state.clone_from(available_access);
1441 state.remove_conflicting_access(access);
1443 access.extend(state);
1446 }
1447
1448 #[inline(always)]
1449 unsafe fn fetch<'w, 's>(
1450 access: &'s Self::State,
1451 fetch: &mut Self::Fetch<'w>,
1452 entity: Entity,
1453 _table_row: TableRow,
1454 ) -> Option<Self::Item<'w, 's>> {
1455 let cell = unsafe {
1457 fetch
1458 .world
1459 .get_entity_with_ticks(entity, fetch.last_run, fetch.this_run)
1460 .debug_checked_unwrap()
1461 };
1462 Some(unsafe { FilteredEntityMut::new(cell, access) })
1464 }
1465
1466 fn iter_access(state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
1467 iter::once(EcsAccessType::Access(state))
1468 }
1469}
1470
1471unsafe impl IterQueryData for FilteredEntityMut<'_, '_> {}
1473
1474unsafe impl SingleEntityQueryData for FilteredEntityMut<'_, '_> {}
1476
1477impl ArchetypeQueryData for FilteredEntityMut<'_, '_> {}
1478
1479unsafe impl<'a, 'b, B> WorldQuery for EntityRefExcept<'a, 'b, B>
1483where
1484 B: Bundle,
1485{
1486 type Fetch<'w> = EntityFetch<'w>;
1487 type State = Access;
1488
1489 fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
1490 fetch
1491 }
1492
1493 unsafe fn init_fetch<'w, 's>(
1494 world: UnsafeWorldCell<'w>,
1495 _: &'s Self::State,
1496 last_run: Tick,
1497 this_run: Tick,
1498 ) -> Self::Fetch<'w> {
1499 EntityFetch {
1500 world,
1501 last_run,
1502 this_run,
1503 }
1504 }
1505
1506 const IS_DENSE: bool = true;
1507
1508 unsafe fn set_archetype<'w, 's>(
1509 _: &mut Self::Fetch<'w>,
1510 _: &'s Self::State,
1511 _: &'w Archetype,
1512 _: &'w Table,
1513 ) {
1514 }
1515
1516 unsafe fn set_table<'w, 's>(_: &mut Self::Fetch<'w>, _: &'s Self::State, _: &'w Table) {}
1517
1518 fn update_component_access(state: &Self::State, filtered_access: &mut FilteredAccess) {
1519 let access = filtered_access.access_mut();
1520 assert!(
1521 access.is_compatible(state),
1522 "`EntityRefExcept<{}>` conflicts with a previous access in this query.",
1523 DebugName::type_name::<B>(),
1524 );
1525 access.extend(state);
1526 }
1527
1528 fn init_nested_access(
1529 _state: &Self::State,
1530 _system_name: Option<&str>,
1531 _component_access_set: &mut FilteredAccessSet,
1532 _world: UnsafeWorldCell,
1533 ) {
1534 }
1535
1536 fn init_state(world: &mut World) -> Self::State {
1537 let mut access = Access::new();
1538 access.read_all();
1539 for id in B::component_ids(&mut world.components_registrator()) {
1540 access.remove_read(id);
1541 }
1542 access
1543 }
1544
1545 fn get_state(components: &Components) -> Option<Self::State> {
1546 let mut access = Access::new();
1547 access.read_all();
1548 for id in B::get_component_ids(components).flatten() {
1555 access.remove_read(id);
1556 }
1557 Some(access)
1558 }
1559
1560 fn matches_component_set(_: &Self::State, _: &impl Fn(ComponentId) -> bool) -> bool {
1561 true
1562 }
1563
1564 fn update_archetypes(_state: &mut Self::State, _world: UnsafeWorldCell) {}
1565}
1566
1567unsafe impl<'a, 'b, B> QueryData for EntityRefExcept<'a, 'b, B>
1569where
1570 B: Bundle,
1571{
1572 const IS_READ_ONLY: bool = true;
1573 const IS_ARCHETYPAL: bool = true;
1574 type ReadOnly = Self;
1575 type Item<'w, 's> = EntityRefExcept<'w, 's, B>;
1576
1577 fn shrink<'wlong: 'wshort, 'wshort, 's>(
1578 item: Self::Item<'wlong, 's>,
1579 ) -> Self::Item<'wshort, 's> {
1580 item
1581 }
1582
1583 unsafe fn fetch<'w, 's>(
1584 access: &'s Self::State,
1585 fetch: &mut Self::Fetch<'w>,
1586 entity: Entity,
1587 _: TableRow,
1588 ) -> Option<Self::Item<'w, 's>> {
1589 let cell = fetch
1590 .world
1591 .get_entity_with_ticks(entity, fetch.last_run, fetch.this_run)
1592 .unwrap();
1593 Some(EntityRefExcept::new(cell, access))
1594 }
1595
1596 fn iter_access(state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
1597 iter::once(EcsAccessType::Access(state))
1598 }
1599}
1600
1601unsafe impl<B> IterQueryData for EntityRefExcept<'_, '_, B> where B: Bundle {}
1603
1604unsafe impl<B> ReadOnlyQueryData for EntityRefExcept<'_, '_, B> where B: Bundle {}
1606
1607unsafe impl<B> SingleEntityQueryData for EntityRefExcept<'_, '_, B> where B: Bundle {}
1609
1610impl<B: Bundle> ArchetypeQueryData for EntityRefExcept<'_, '_, B> {}
1611
1612unsafe impl<'a, 'b, B> WorldQuery for EntityMutExcept<'a, 'b, B>
1616where
1617 B: Bundle,
1618{
1619 type Fetch<'w> = EntityFetch<'w>;
1620 type State = Access;
1621
1622 fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
1623 fetch
1624 }
1625
1626 unsafe fn init_fetch<'w, 's>(
1627 world: UnsafeWorldCell<'w>,
1628 _: &'s Self::State,
1629 last_run: Tick,
1630 this_run: Tick,
1631 ) -> Self::Fetch<'w> {
1632 EntityFetch {
1633 world,
1634 last_run,
1635 this_run,
1636 }
1637 }
1638
1639 const IS_DENSE: bool = true;
1640
1641 unsafe fn set_archetype<'w, 's>(
1642 _: &mut Self::Fetch<'w>,
1643 _: &'s Self::State,
1644 _: &'w Archetype,
1645 _: &'w Table,
1646 ) {
1647 }
1648
1649 unsafe fn set_table<'w, 's>(_: &mut Self::Fetch<'w>, _: &'s Self::State, _: &'w Table) {}
1650
1651 fn update_component_access(state: &Self::State, filtered_access: &mut FilteredAccess) {
1652 let access = filtered_access.access_mut();
1653 assert!(
1654 access.is_compatible(state),
1655 "`EntityMutExcept<{}>` conflicts with a previous access in this query.",
1656 DebugName::type_name::<B>()
1657 );
1658 access.extend(state);
1659 }
1660
1661 fn init_nested_access(
1662 _state: &Self::State,
1663 _system_name: Option<&str>,
1664 _component_access_set: &mut FilteredAccessSet,
1665 _world: UnsafeWorldCell,
1666 ) {
1667 }
1668
1669 fn init_state(world: &mut World) -> Self::State {
1670 let mut access = Access::new();
1671 access.write_all();
1672 for id in B::component_ids(&mut world.components_registrator()) {
1673 access.remove_read(id);
1674 }
1675 access
1676 }
1677
1678 fn get_state(components: &Components) -> Option<Self::State> {
1679 let mut access = Access::new();
1680 access.write_all();
1681 for id in B::get_component_ids(components).flatten() {
1688 access.remove_read(id);
1689 }
1690 Some(access)
1691 }
1692
1693 fn matches_component_set(_: &Self::State, _: &impl Fn(ComponentId) -> bool) -> bool {
1694 true
1695 }
1696
1697 fn update_archetypes(_state: &mut Self::State, _world: UnsafeWorldCell) {}
1698}
1699
1700unsafe impl<'a, 'b, B> QueryData for EntityMutExcept<'a, 'b, B>
1703where
1704 B: Bundle,
1705{
1706 const IS_READ_ONLY: bool = false;
1707 const IS_ARCHETYPAL: bool = true;
1708 type ReadOnly = EntityRefExcept<'a, 'b, B>;
1709 type Item<'w, 's> = EntityMutExcept<'w, 's, B>;
1710
1711 fn shrink<'wlong: 'wshort, 'wshort, 's>(
1712 item: Self::Item<'wlong, 's>,
1713 ) -> Self::Item<'wshort, 's> {
1714 item
1715 }
1716
1717 unsafe fn fetch<'w, 's>(
1718 access: &'s Self::State,
1719 fetch: &mut Self::Fetch<'w>,
1720 entity: Entity,
1721 _: TableRow,
1722 ) -> Option<Self::Item<'w, 's>> {
1723 let cell = fetch
1724 .world
1725 .get_entity_with_ticks(entity, fetch.last_run, fetch.this_run)
1726 .unwrap();
1727 Some(EntityMutExcept::new(cell, access))
1728 }
1729
1730 fn iter_access(state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
1731 iter::once(EcsAccessType::Access(state))
1732 }
1733}
1734
1735unsafe impl<B> IterQueryData for EntityMutExcept<'_, '_, B> where B: Bundle {}
1737
1738unsafe impl<B> SingleEntityQueryData for EntityMutExcept<'_, '_, B> where B: Bundle {}
1740
1741impl<B: Bundle> ArchetypeQueryData for EntityMutExcept<'_, '_, B> {}
1742
1743unsafe impl WorldQuery for &Archetype {
1747 type Fetch<'w> = (&'w Entities, &'w Archetypes);
1748 type State = ();
1749
1750 fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
1751 fetch
1752 }
1753
1754 unsafe fn init_fetch<'w, 's>(
1755 world: UnsafeWorldCell<'w>,
1756 _state: &'s Self::State,
1757 _last_run: Tick,
1758 _this_run: Tick,
1759 ) -> Self::Fetch<'w> {
1760 (world.entities(), world.archetypes())
1761 }
1762
1763 const IS_DENSE: bool = true;
1766
1767 #[inline]
1768 unsafe fn set_archetype<'w, 's>(
1769 _fetch: &mut Self::Fetch<'w>,
1770 _state: &'s Self::State,
1771 _archetype: &'w Archetype,
1772 _table: &Table,
1773 ) {
1774 }
1775
1776 #[inline]
1777 unsafe fn set_table<'w, 's>(
1778 _fetch: &mut Self::Fetch<'w>,
1779 _state: &'s Self::State,
1780 _table: &'w Table,
1781 ) {
1782 }
1783
1784 fn update_component_access(_state: &Self::State, _access: &mut FilteredAccess) {}
1785
1786 fn init_nested_access(
1787 _state: &Self::State,
1788 _system_name: Option<&str>,
1789 _component_access_set: &mut FilteredAccessSet,
1790 _world: UnsafeWorldCell,
1791 ) {
1792 }
1793
1794 fn init_state(_world: &mut World) {}
1795
1796 fn get_state(_components: &Components) -> Option<()> {
1797 Some(())
1798 }
1799
1800 fn matches_component_set(
1801 _state: &Self::State,
1802 _set_contains_id: &impl Fn(ComponentId) -> bool,
1803 ) -> bool {
1804 true
1805 }
1806
1807 fn update_archetypes(_state: &mut Self::State, _world: UnsafeWorldCell) {}
1808}
1809
1810unsafe impl QueryData for &Archetype {
1812 const IS_READ_ONLY: bool = true;
1813 const IS_ARCHETYPAL: bool = true;
1814 type ReadOnly = Self;
1815 type Item<'w, 's> = &'w Archetype;
1816
1817 fn shrink<'wlong: 'wshort, 'wshort, 's>(
1818 item: Self::Item<'wlong, 's>,
1819 ) -> Self::Item<'wshort, 's> {
1820 item
1821 }
1822
1823 #[inline(always)]
1824 unsafe fn fetch<'w, 's>(
1825 _state: &'s Self::State,
1826 fetch: &mut Self::Fetch<'w>,
1827 entity: Entity,
1828 _table_row: TableRow,
1829 ) -> Option<Self::Item<'w, 's>> {
1830 let (entities, archetypes) = *fetch;
1831 let location = unsafe { entities.get_spawned(entity).debug_checked_unwrap() };
1833 Some(unsafe { archetypes.get(location.archetype_id).debug_checked_unwrap() })
1835 }
1836
1837 fn iter_access(_state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
1838 iter::empty()
1839 }
1840}
1841
1842unsafe impl IterQueryData for &Archetype {}
1844
1845unsafe impl ReadOnlyQueryData for &Archetype {}
1847
1848unsafe impl SingleEntityQueryData for &Archetype {}
1850
1851impl ReleaseStateQueryData for &Archetype {
1852 fn release_state<'w>(item: Self::Item<'w, '_>) -> Self::Item<'w, 'static> {
1853 item
1854 }
1855}
1856
1857impl ArchetypeQueryData for &Archetype {}
1858
1859pub struct ReadFetch<'w, T: Component> {
1861 components: StorageSwitch<
1862 T,
1863 Option<ThinSlicePtr<'w, UnsafeCell<T>>>,
1865 Option<&'w ComponentSparseSet>,
1867 >,
1868}
1869
1870impl<T: Component> Clone for ReadFetch<'_, T> {
1871 fn clone(&self) -> Self {
1872 *self
1873 }
1874}
1875
1876impl<T: Component> Copy for ReadFetch<'_, T> {}
1877
1878unsafe impl<T: Component> WorldQuery for &T {
1884 type Fetch<'w> = ReadFetch<'w, T>;
1885 type State = ComponentId;
1886
1887 fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
1888 fetch
1889 }
1890
1891 #[inline]
1892 unsafe fn init_fetch<'w, 's>(
1893 world: UnsafeWorldCell<'w>,
1894 &component_id: &ComponentId,
1895 _last_run: Tick,
1896 _this_run: Tick,
1897 ) -> ReadFetch<'w, T> {
1898 ReadFetch {
1899 components: StorageSwitch::new(
1900 || None,
1901 || {
1902 unsafe { world.storages().sparse_sets.get(component_id) }
1907 },
1908 ),
1909 }
1910 }
1911
1912 const IS_DENSE: bool = {
1913 match T::STORAGE_TYPE {
1914 StorageType::Table => true,
1915 StorageType::SparseSet => false,
1916 }
1917 };
1918
1919 #[inline]
1920 unsafe fn set_archetype<'w>(
1921 fetch: &mut ReadFetch<'w, T>,
1922 component_id: &ComponentId,
1923 _archetype: &'w Archetype,
1924 table: &'w Table,
1925 ) {
1926 if Self::IS_DENSE {
1927 unsafe {
1929 Self::set_table(fetch, component_id, table);
1930 }
1931 }
1932 }
1933
1934 #[inline]
1935 unsafe fn set_table<'w>(
1936 fetch: &mut ReadFetch<'w, T>,
1937 &component_id: &ComponentId,
1938 table: &'w Table,
1939 ) {
1940 let table_data = Some(
1941 table
1942 .get_data_slice_for(component_id)
1943 .debug_checked_unwrap()
1944 .into(),
1945 );
1946 unsafe { fetch.components.set_table(table_data) };
1948 }
1949
1950 fn update_component_access(&component_id: &ComponentId, access: &mut FilteredAccess) {
1951 assert!(
1952 !access.access().has_write(component_id),
1953 "&{} conflicts with a previous access in this query. Shared access cannot coincide with exclusive access.",
1954 DebugName::type_name::<T>(),
1955 );
1956 access.add_read(component_id);
1957 }
1958
1959 fn init_nested_access(
1960 _state: &Self::State,
1961 _system_name: Option<&str>,
1962 _component_access_set: &mut FilteredAccessSet,
1963 _world: UnsafeWorldCell,
1964 ) {
1965 }
1966
1967 fn init_state(world: &mut World) -> ComponentId {
1968 world.register_component::<T>()
1969 }
1970
1971 fn get_state(components: &Components) -> Option<Self::State> {
1972 components.component_id::<T>()
1973 }
1974
1975 fn matches_component_set(
1976 &state: &ComponentId,
1977 set_contains_id: &impl Fn(ComponentId) -> bool,
1978 ) -> bool {
1979 set_contains_id(state)
1980 }
1981
1982 fn update_archetypes(_state: &mut Self::State, _world: UnsafeWorldCell) {}
1983}
1984
1985unsafe impl<T: Component> QueryData for &T {
1987 const IS_READ_ONLY: bool = true;
1988 const IS_ARCHETYPAL: bool = true;
1989 type ReadOnly = Self;
1990 type Item<'w, 's> = &'w T;
1991
1992 fn shrink<'wlong: 'wshort, 'wshort, 's>(
1993 item: Self::Item<'wlong, 's>,
1994 ) -> Self::Item<'wshort, 's> {
1995 item
1996 }
1997
1998 #[inline(always)]
1999 unsafe fn fetch<'w, 's>(
2000 _state: &'s Self::State,
2001 fetch: &mut Self::Fetch<'w>,
2002 entity: Entity,
2003 table_row: TableRow,
2004 ) -> Option<Self::Item<'w, 's>> {
2005 Some(fetch.components.extract(
2006 |table| {
2007 let table = unsafe { table.debug_checked_unwrap() };
2009 let item = unsafe { table.get_unchecked(table_row.index()) };
2011 item.deref()
2012 },
2013 |sparse_set| {
2014 let item = unsafe {
2016 sparse_set
2017 .debug_checked_unwrap()
2018 .get(entity)
2019 .debug_checked_unwrap()
2020 };
2021 item.deref()
2022 },
2023 ))
2024 }
2025
2026 fn iter_access(state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
2027 iter::once(EcsAccessType::Component(EcsAccessLevel::Read(*state)))
2028 }
2029}
2030
2031impl<T: Component> ContiguousQueryData for &T {
2032 type Contiguous<'w, 's> = &'w [T];
2033
2034 unsafe fn fetch_contiguous<'w, 's>(
2035 _state: &'s Self::State,
2036 fetch: &mut Self::Fetch<'w>,
2037 entities: &'w [Entity],
2038 range: Range<u32>,
2039 ) -> Self::Contiguous<'w, 's> {
2040 fetch.components.extract(
2041 |table| {
2042 let table = unsafe { table.debug_checked_unwrap() };
2044 let slice = unsafe {
2050 table
2051 .cast()
2052 .slice_unchecked((range.start as usize)..(range.end as usize))
2053 };
2054 debug_assert_eq!(slice.len(), entities.len());
2055 slice
2056 },
2057 |_| {
2058 #[cfg(debug_assertions)]
2059 unreachable!();
2060 #[cfg(not(debug_assertions))]
2062 core::hint::unreachable_unchecked();
2063 },
2064 )
2065 }
2066}
2067
2068unsafe impl<T: Component> IterQueryData for &T {}
2070
2071unsafe impl<T: Component> ReadOnlyQueryData for &T {}
2073
2074unsafe impl<T: Component> SingleEntityQueryData for &T {}
2076
2077impl<T: Component> ReleaseStateQueryData for &T {
2078 fn release_state<'w>(item: Self::Item<'w, '_>) -> Self::Item<'w, 'static> {
2079 item
2080 }
2081}
2082
2083impl<T: Component> ArchetypeQueryData for &T {}
2084
2085#[doc(hidden)]
2086pub struct RefFetch<'w, T: Component> {
2087 components: StorageSwitch<
2088 T,
2089 Option<(
2091 ThinSlicePtr<'w, UnsafeCell<T>>,
2092 ThinSlicePtr<'w, UnsafeCell<Tick>>,
2093 ThinSlicePtr<'w, UnsafeCell<Tick>>,
2094 Option<&'w AtomicTick>,
2095 MaybeLocation<ThinSlicePtr<'w, UnsafeCell<&'static Location<'static>>>>,
2096 )>,
2097 Option<&'w ComponentSparseSet>,
2100 >,
2101 last_run: Tick,
2102 this_run: Tick,
2103}
2104
2105impl<T: Component> Clone for RefFetch<'_, T> {
2106 fn clone(&self) -> Self {
2107 *self
2108 }
2109}
2110
2111impl<T: Component> Copy for RefFetch<'_, T> {}
2112
2113unsafe impl<'__w, T: Component> WorldQuery for Ref<'__w, T> {
2119 type Fetch<'w> = RefFetch<'w, T>;
2120 type State = ComponentId;
2121
2122 fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
2123 fetch
2124 }
2125
2126 #[inline]
2127 unsafe fn init_fetch<'w, 's>(
2128 world: UnsafeWorldCell<'w>,
2129 &component_id: &ComponentId,
2130 last_run: Tick,
2131 this_run: Tick,
2132 ) -> RefFetch<'w, T> {
2133 RefFetch {
2134 components: StorageSwitch::new(
2135 || None,
2136 || {
2137 unsafe { world.storages().sparse_sets.get(component_id) }
2142 },
2143 ),
2144 last_run,
2145 this_run,
2146 }
2147 }
2148
2149 const IS_DENSE: bool = {
2150 match T::STORAGE_TYPE {
2151 StorageType::Table => true,
2152 StorageType::SparseSet => false,
2153 }
2154 };
2155
2156 #[inline]
2157 unsafe fn set_archetype<'w>(
2158 fetch: &mut RefFetch<'w, T>,
2159 component_id: &ComponentId,
2160 _archetype: &'w Archetype,
2161 table: &'w Table,
2162 ) {
2163 if Self::IS_DENSE {
2164 unsafe {
2166 Self::set_table(fetch, component_id, table);
2167 }
2168 }
2169 }
2170
2171 #[inline]
2172 unsafe fn set_table<'w>(
2173 fetch: &mut RefFetch<'w, T>,
2174 &component_id: &ComponentId,
2175 table: &'w Table,
2176 ) {
2177 let column = table.get_column(component_id).debug_checked_unwrap();
2178 let table_data = Some((
2179 column.get_data_slice(table.entity_count() as usize).into(),
2180 column
2181 .get_added_ticks_slice(table.entity_count() as usize)
2182 .into(),
2183 column
2184 .get_changed_ticks_slice(table.entity_count() as usize)
2185 .into(),
2186 column.get_summary_tick(),
2187 column
2188 .get_changed_by_slice(table.entity_count() as usize)
2189 .map(Into::into),
2190 ));
2191 unsafe { fetch.components.set_table(table_data) };
2193 }
2194
2195 fn update_component_access(&component_id: &ComponentId, access: &mut FilteredAccess) {
2196 assert!(
2197 !access.access().has_write(component_id),
2198 "&{} conflicts with a previous access in this query. Shared access cannot coincide with exclusive access.",
2199 DebugName::type_name::<T>(),
2200 );
2201 access.add_read(component_id);
2202 }
2203
2204 fn init_nested_access(
2205 _state: &Self::State,
2206 _system_name: Option<&str>,
2207 _component_access_set: &mut FilteredAccessSet,
2208 _world: UnsafeWorldCell,
2209 ) {
2210 }
2211
2212 fn init_state(world: &mut World) -> ComponentId {
2213 world.register_component::<T>()
2214 }
2215
2216 fn get_state(components: &Components) -> Option<Self::State> {
2217 components.component_id::<T>()
2218 }
2219
2220 fn matches_component_set(
2221 &state: &ComponentId,
2222 set_contains_id: &impl Fn(ComponentId) -> bool,
2223 ) -> bool {
2224 set_contains_id(state)
2225 }
2226
2227 fn update_archetypes(_state: &mut Self::State, _world: UnsafeWorldCell) {}
2228}
2229
2230unsafe impl<'__w, T: Component> QueryData for Ref<'__w, T> {
2232 const IS_READ_ONLY: bool = true;
2233 const IS_ARCHETYPAL: bool = true;
2234 type ReadOnly = Self;
2235 type Item<'w, 's> = Ref<'w, T>;
2236
2237 fn shrink<'wlong: 'wshort, 'wshort, 's>(
2238 item: Self::Item<'wlong, 's>,
2239 ) -> Self::Item<'wshort, 's> {
2240 item
2241 }
2242
2243 #[inline(always)]
2244 unsafe fn fetch<'w, 's>(
2245 _state: &'s Self::State,
2246 fetch: &mut Self::Fetch<'w>,
2247 entity: Entity,
2248 table_row: TableRow,
2249 ) -> Option<Self::Item<'w, 's>> {
2250 Some(fetch.components.extract(
2251 |table| {
2252 let (table_components, added_ticks, changed_ticks, _summary_tick, callers) =
2254 unsafe { table.debug_checked_unwrap() };
2255
2256 let component = unsafe { table_components.get_unchecked(table_row.index()) };
2258 let added = unsafe { added_ticks.get_unchecked(table_row.index()) };
2260 let changed = unsafe { changed_ticks.get_unchecked(table_row.index()) };
2262 let caller =
2264 callers.map(|callers| unsafe { callers.get_unchecked(table_row.index()) });
2265
2266 Ref {
2267 value: component.deref(),
2268 ticks: ComponentTicksRef {
2269 added: added.deref(),
2270 changed: changed.deref(),
2271 changed_by: caller.map(|caller| caller.deref()),
2272 this_run: fetch.this_run,
2273 last_run: fetch.last_run,
2274 },
2275 }
2276 },
2277 |sparse_set| {
2278 let (component, ticks) = unsafe {
2280 sparse_set
2281 .debug_checked_unwrap()
2282 .get_with_ticks(entity)
2283 .debug_checked_unwrap()
2284 };
2285
2286 Ref {
2287 value: component.deref(),
2288 ticks: ComponentTicksRef::from_tick_cells(
2289 ticks,
2290 fetch.last_run,
2291 fetch.this_run,
2292 ),
2293 }
2294 },
2295 ))
2296 }
2297
2298 fn iter_access(state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
2299 iter::once(EcsAccessType::Component(EcsAccessLevel::Read(*state)))
2300 }
2301}
2302
2303unsafe impl<'__w, T: Component> IterQueryData for Ref<'__w, T> {}
2305
2306unsafe impl<'__w, T: Component> ReadOnlyQueryData for Ref<'__w, T> {}
2308
2309unsafe impl<'__w, T: Component> SingleEntityQueryData for Ref<'__w, T> {}
2311
2312impl<T: Component> ReleaseStateQueryData for Ref<'_, T> {
2313 fn release_state<'w>(item: Self::Item<'w, '_>) -> Self::Item<'w, 'static> {
2314 item
2315 }
2316}
2317
2318impl<T: Component> ArchetypeQueryData for Ref<'_, T> {}
2319
2320impl<T: Component> ContiguousQueryData for Ref<'_, T> {
2321 type Contiguous<'w, 's> = ContiguousRef<'w, T>;
2322
2323 unsafe fn fetch_contiguous<'w, 's>(
2324 _state: &'s Self::State,
2325 fetch: &mut Self::Fetch<'w>,
2326 entities: &'w [Entity],
2327 range: Range<u32>,
2328 ) -> Self::Contiguous<'w, 's> {
2329 fetch.components.extract(
2330 |table| {
2331 let (table_components, added_ticks, changed_ticks, summary_tick, callers) =
2333 unsafe { table.debug_checked_unwrap() };
2334
2335 let range = (range.start as usize)..(range.end as usize);
2336
2337 let contiguous_ref = ContiguousRef {
2338 value: unsafe { table_components.cast().slice_unchecked(range.clone()) },
2340 ticks: unsafe {
2345 ContiguousComponentTicksRef::from_slice_ptrs(
2346 added_ticks,
2347 changed_ticks,
2348 summary_tick,
2349 callers,
2350 range,
2351 fetch.this_run,
2352 fetch.last_run,
2353 )
2354 },
2355 };
2356
2357 debug_assert_eq!(entities.len(), contiguous_ref.value.len());
2358
2359 contiguous_ref
2360 },
2361 |_| {
2362 #[cfg(debug_assertions)]
2363 unreachable!();
2364 #[cfg(not(debug_assertions))]
2366 core::hint::unreachable_unchecked();
2367 },
2368 )
2369 }
2370}
2371
2372pub struct WriteFetch<'w, T: Component> {
2374 components: StorageSwitch<
2375 T,
2376 Option<(
2378 ThinSlicePtr<'w, UnsafeCell<T>>,
2379 ThinSlicePtr<'w, UnsafeCell<Tick>>,
2380 ThinSlicePtr<'w, UnsafeCell<Tick>>,
2381 Option<&'w AtomicTick>,
2382 MaybeLocation<ThinSlicePtr<'w, UnsafeCell<&'static Location<'static>>>>,
2383 )>,
2384 Option<&'w ComponentSparseSet>,
2387 >,
2388 last_run: Tick,
2389 this_run: Tick,
2390}
2391
2392impl<T: Component> Clone for WriteFetch<'_, T> {
2393 fn clone(&self) -> Self {
2394 *self
2395 }
2396}
2397
2398impl<T: Component> Copy for WriteFetch<'_, T> {}
2399
2400unsafe impl<'__w, T: Component> WorldQuery for &'__w mut T {
2406 type Fetch<'w> = WriteFetch<'w, T>;
2407 type State = ComponentId;
2408
2409 fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
2410 fetch
2411 }
2412
2413 #[inline]
2414 unsafe fn init_fetch<'w, 's>(
2415 world: UnsafeWorldCell<'w>,
2416 &component_id: &ComponentId,
2417 last_run: Tick,
2418 this_run: Tick,
2419 ) -> WriteFetch<'w, T> {
2420 WriteFetch {
2421 components: StorageSwitch::new(
2422 || None,
2423 || {
2424 unsafe { world.storages().sparse_sets.get(component_id) }
2429 },
2430 ),
2431 last_run,
2432 this_run,
2433 }
2434 }
2435
2436 const IS_DENSE: bool = {
2437 match T::STORAGE_TYPE {
2438 StorageType::Table => true,
2439 StorageType::SparseSet => false,
2440 }
2441 };
2442
2443 #[inline]
2444 unsafe fn set_archetype<'w>(
2445 fetch: &mut WriteFetch<'w, T>,
2446 component_id: &ComponentId,
2447 _archetype: &'w Archetype,
2448 table: &'w Table,
2449 ) {
2450 if Self::IS_DENSE {
2451 unsafe {
2453 Self::set_table(fetch, component_id, table);
2454 }
2455 }
2456 }
2457
2458 #[inline]
2459 unsafe fn set_table<'w>(
2460 fetch: &mut WriteFetch<'w, T>,
2461 &component_id: &ComponentId,
2462 table: &'w Table,
2463 ) {
2464 let column = table.get_column(component_id).debug_checked_unwrap();
2465 let table_data = Some((
2466 column.get_data_slice(table.entity_count() as usize).into(),
2467 column
2468 .get_added_ticks_slice(table.entity_count() as usize)
2469 .into(),
2470 column
2471 .get_changed_ticks_slice(table.entity_count() as usize)
2472 .into(),
2473 column.get_summary_tick(),
2474 column
2475 .get_changed_by_slice(table.entity_count() as usize)
2476 .map(Into::into),
2477 ));
2478 unsafe { fetch.components.set_table(table_data) };
2480 }
2481
2482 fn update_component_access(&component_id: &ComponentId, access: &mut FilteredAccess) {
2483 assert!(
2484 !access.access().has_read(component_id),
2485 "&mut {} conflicts with a previous access in this query. Mutable component access must be unique.",
2486 DebugName::type_name::<T>(),
2487 );
2488 access.add_write(component_id);
2489 }
2490
2491 fn init_nested_access(
2492 _state: &Self::State,
2493 _system_name: Option<&str>,
2494 _component_access_set: &mut FilteredAccessSet,
2495 _world: UnsafeWorldCell,
2496 ) {
2497 }
2498
2499 fn init_state(world: &mut World) -> ComponentId {
2500 world.register_component::<T>()
2501 }
2502
2503 fn get_state(components: &Components) -> Option<Self::State> {
2504 components.component_id::<T>()
2505 }
2506
2507 fn matches_component_set(
2508 &state: &ComponentId,
2509 set_contains_id: &impl Fn(ComponentId) -> bool,
2510 ) -> bool {
2511 set_contains_id(state)
2512 }
2513
2514 fn update_archetypes(_state: &mut Self::State, _world: UnsafeWorldCell) {}
2515}
2516
2517unsafe impl<'__w, T: Component<Mutability = Mutable>> QueryData for &'__w mut T {
2519 const IS_READ_ONLY: bool = false;
2520 const IS_ARCHETYPAL: bool = true;
2521 type ReadOnly = &'__w T;
2522 type Item<'w, 's> = Mut<'w, T>;
2523
2524 fn shrink<'wlong: 'wshort, 'wshort, 's>(
2525 item: Self::Item<'wlong, 's>,
2526 ) -> Self::Item<'wshort, 's> {
2527 item
2528 }
2529
2530 #[inline(always)]
2531 unsafe fn fetch<'w, 's>(
2532 _state: &'s Self::State,
2533 fetch: &mut Self::Fetch<'w>,
2534 entity: Entity,
2535 table_row: TableRow,
2536 ) -> Option<Self::Item<'w, 's>> {
2537 Some(fetch.components.extract(
2538 |table| {
2539 let (table_components, added_ticks, changed_ticks, summary_tick, callers) =
2541 unsafe { table.debug_checked_unwrap() };
2542
2543 let component = unsafe { table_components.get_unchecked(table_row.index()) };
2545 let added = unsafe { added_ticks.get_unchecked(table_row.index()) };
2547 let changed = unsafe { changed_ticks.get_unchecked(table_row.index()) };
2549 let caller =
2551 callers.map(|callers| unsafe { callers.get_unchecked(table_row.index()) });
2552 let summary_tick = if T::HAS_SUMMARY_TICK {
2554 Some(unsafe { summary_tick.debug_checked_unwrap() })
2556 } else {
2557 None
2558 };
2559
2560 Mut {
2561 value: component.deref_mut(),
2562 ticks: ComponentTicksMut {
2563 added: added.deref_mut(),
2564 changed: changed.deref_mut(),
2565 changed_by: caller.map(|caller| caller.deref_mut()),
2566 this_run: fetch.this_run,
2567 last_run: fetch.last_run,
2568 summary_tick,
2569 },
2570 }
2571 },
2572 |sparse_set| {
2573 let (component, ticks) = unsafe {
2575 sparse_set
2576 .debug_checked_unwrap()
2577 .get_with_ticks(entity)
2578 .debug_checked_unwrap()
2579 };
2580
2581 Mut {
2582 value: component.assert_unique().deref_mut(),
2583 ticks: ComponentTicksMut::from_tick_cells(
2584 ticks,
2585 fetch.last_run,
2586 fetch.this_run,
2587 ),
2588 }
2589 },
2590 ))
2591 }
2592
2593 fn iter_access(state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
2594 iter::once(EcsAccessType::Component(EcsAccessLevel::Write(*state)))
2595 }
2596}
2597
2598unsafe impl<T: Component<Mutability = Mutable>> IterQueryData for &mut T {}
2600
2601unsafe impl<T: Component<Mutability = Mutable>> SingleEntityQueryData for &mut T {}
2603
2604impl<T: Component<Mutability = Mutable>> ReleaseStateQueryData for &mut T {
2605 fn release_state<'w>(item: Self::Item<'w, '_>) -> Self::Item<'w, 'static> {
2606 item
2607 }
2608}
2609
2610impl<T: Component<Mutability = Mutable>> ArchetypeQueryData for &mut T {}
2611
2612impl<T: Component<Mutability = Mutable>> ContiguousQueryData for &mut T {
2613 type Contiguous<'w, 's> = ContiguousMut<'w, T>;
2614
2615 unsafe fn fetch_contiguous<'w, 's>(
2616 _state: &'s Self::State,
2617 fetch: &mut Self::Fetch<'w>,
2618 _entities: &'w [Entity],
2619 range: Range<u32>,
2620 ) -> Self::Contiguous<'w, 's> {
2621 fetch.components.extract(
2622 |table| {
2623 let (table_components, added_ticks, changed_ticks, summary_tick, callers) =
2625 unsafe { table.debug_checked_unwrap() };
2626
2627 let range = (range.start as usize)..(range.end as usize);
2628
2629 ContiguousMut {
2630 value: unsafe { table_components.slice_mut_unchecked(range.clone()) },
2632 ticks: unsafe {
2637 ContiguousComponentTicksMut::from_slice_ptrs(
2638 added_ticks,
2639 changed_ticks,
2640 summary_tick,
2641 callers,
2642 range,
2643 fetch.this_run,
2644 fetch.last_run,
2645 )
2646 },
2647 }
2648 },
2649 |_| {
2650 #[cfg(debug_assertions)]
2651 unreachable!();
2652 #[cfg(not(debug_assertions))]
2654 core::hint::unreachable_unchecked();
2655 },
2656 )
2657 }
2658}
2659
2660unsafe impl<'__w, T: Component> WorldQuery for Mut<'__w, T> {
2670 type Fetch<'w> = WriteFetch<'w, T>;
2671 type State = ComponentId;
2672
2673 fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
2674 fetch
2675 }
2676
2677 #[inline]
2678 unsafe fn init_fetch<'w, 's>(
2680 world: UnsafeWorldCell<'w>,
2681 state: &ComponentId,
2682 last_run: Tick,
2683 this_run: Tick,
2684 ) -> WriteFetch<'w, T> {
2685 <&mut T as WorldQuery>::init_fetch(world, state, last_run, this_run)
2686 }
2687
2688 const IS_DENSE: bool = <&mut T as WorldQuery>::IS_DENSE;
2690
2691 #[inline]
2692 unsafe fn set_archetype<'w>(
2694 fetch: &mut WriteFetch<'w, T>,
2695 state: &ComponentId,
2696 archetype: &'w Archetype,
2697 table: &'w Table,
2698 ) {
2699 <&mut T as WorldQuery>::set_archetype(fetch, state, archetype, table);
2700 }
2701
2702 #[inline]
2703 unsafe fn set_table<'w>(fetch: &mut WriteFetch<'w, T>, state: &ComponentId, table: &'w Table) {
2705 <&mut T as WorldQuery>::set_table(fetch, state, table);
2706 }
2707
2708 fn update_component_access(&component_id: &ComponentId, access: &mut FilteredAccess) {
2710 assert!(
2713 !access.access().has_read(component_id),
2714 "Mut<{}> conflicts with a previous access in this query. Mutable component access mut be unique.",
2715 DebugName::type_name::<T>(),
2716 );
2717 access.add_write(component_id);
2718 }
2719
2720 fn init_nested_access(
2721 _state: &Self::State,
2722 _system_name: Option<&str>,
2723 _component_access_set: &mut FilteredAccessSet,
2724 _world: UnsafeWorldCell,
2725 ) {
2726 }
2727
2728 fn init_state(world: &mut World) -> ComponentId {
2730 <&mut T as WorldQuery>::init_state(world)
2731 }
2732
2733 fn get_state(components: &Components) -> Option<ComponentId> {
2735 <&mut T as WorldQuery>::get_state(components)
2736 }
2737
2738 fn matches_component_set(
2740 state: &ComponentId,
2741 set_contains_id: &impl Fn(ComponentId) -> bool,
2742 ) -> bool {
2743 <&mut T as WorldQuery>::matches_component_set(state, set_contains_id)
2744 }
2745
2746 fn update_archetypes(_state: &mut Self::State, _world: UnsafeWorldCell) {}
2747}
2748
2749unsafe impl<'__w, T: Component<Mutability = Mutable>> QueryData for Mut<'__w, T> {
2751 const IS_READ_ONLY: bool = false;
2752 const IS_ARCHETYPAL: bool = true;
2753 type ReadOnly = Ref<'__w, T>;
2754 type Item<'w, 's> = Mut<'w, T>;
2755
2756 fn shrink<'wlong: 'wshort, 'wshort, 's>(
2758 item: Self::Item<'wlong, 's>,
2759 ) -> Self::Item<'wshort, 's> {
2760 <&mut T as QueryData>::shrink(item)
2761 }
2762
2763 #[inline(always)]
2764 unsafe fn fetch<'w, 's>(
2766 state: &'s Self::State,
2767 fetch: &mut Self::Fetch<'w>,
2770 entity: Entity,
2771 table_row: TableRow,
2772 ) -> Option<Self::Item<'w, 's>> {
2773 <&mut T as QueryData>::fetch(state, fetch, entity, table_row)
2774 }
2775
2776 fn iter_access(state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
2777 iter::once(EcsAccessType::Component(EcsAccessLevel::Write(*state)))
2778 }
2779}
2780
2781unsafe impl<T: Component<Mutability = Mutable>> IterQueryData for Mut<'_, T> {}
2783
2784unsafe impl<T: Component<Mutability = Mutable>> SingleEntityQueryData for Mut<'_, T> {}
2786
2787impl<T: Component<Mutability = Mutable>> ReleaseStateQueryData for Mut<'_, T> {
2788 fn release_state<'w>(item: Self::Item<'w, '_>) -> Self::Item<'w, 'static> {
2789 item
2790 }
2791}
2792
2793impl<T: Component<Mutability = Mutable>> ArchetypeQueryData for Mut<'_, T> {}
2794
2795impl<'__w, T: Component<Mutability = Mutable>> ContiguousQueryData for Mut<'__w, T> {
2796 type Contiguous<'w, 's> = ContiguousMut<'w, T>;
2797
2798 unsafe fn fetch_contiguous<'w, 's>(
2799 state: &'s Self::State,
2800 fetch: &mut Self::Fetch<'w>,
2801 entities: &'w [Entity],
2802 range: Range<u32>,
2803 ) -> Self::Contiguous<'w, 's> {
2804 <&mut T as ContiguousQueryData>::fetch_contiguous(state, fetch, entities, range)
2805 }
2806}
2807
2808pub struct NestedQuery<D: QueryData + 'static, F: QueryFilter + 'static = ()>(
3038 PhantomData<Query<'static, 'static, D, F>>,
3039);
3040
3041#[doc(hidden)]
3042#[derive(Clone)]
3043pub struct NestedQueryFetch<'w> {
3044 world: UnsafeWorldCell<'w>,
3045 last_run: Tick,
3046 this_run: Tick,
3047}
3048
3049unsafe impl<D: ReadOnlyQueryData + 'static, F: QueryFilter + 'static> WorldQuery
3053 for NestedQuery<D, F>
3054{
3055 type Fetch<'w> = NestedQueryFetch<'w>;
3056 type State = QueryState<D, F>;
3057
3058 fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
3059 fetch
3060 }
3061
3062 #[inline]
3063 unsafe fn init_fetch<'w, 's>(
3064 world: UnsafeWorldCell<'w>,
3065 _state: &'s Self::State,
3066 last_run: Tick,
3067 this_run: Tick,
3068 ) -> Self::Fetch<'w> {
3069 NestedQueryFetch {
3070 world,
3071 last_run,
3072 this_run,
3073 }
3074 }
3075
3076 const IS_DENSE: bool = true;
3077
3078 #[inline]
3079 unsafe fn set_archetype<'w>(
3080 _fetch: &mut Self::Fetch<'w>,
3081 _state: &Self::State,
3082 _archetype: &'w Archetype,
3083 _table: &'w Table,
3084 ) {
3085 }
3086
3087 #[inline]
3088 unsafe fn set_table<'w>(_fetch: &mut Self::Fetch<'w>, _state: &Self::State, _table: &'w Table) {
3089 }
3090
3091 fn update_component_access(_state: &Self::State, _access: &mut FilteredAccess) {
3092 }
3095
3096 fn init_nested_access(
3097 state: &Self::State,
3098 system_name: Option<&str>,
3099 component_access_set: &mut FilteredAccessSet,
3100 world: UnsafeWorldCell,
3101 ) {
3102 state.init_access(system_name, component_access_set, world);
3103 }
3104
3105 fn init_state(world: &mut World) -> Self::State {
3106 unsafe { QueryState::<D, F>::new_unchecked(world) }
3111 }
3112
3113 fn get_state(_components: &Components) -> Option<Self::State> {
3114 None
3119 }
3120
3121 fn matches_component_set(
3122 _state: &Self::State,
3123 _set_contains_id: &impl Fn(ComponentId) -> bool,
3124 ) -> bool {
3125 true
3126 }
3127
3128 fn update_archetypes(state: &mut Self::State, world: UnsafeWorldCell) {
3129 state.update_archetypes_unsafe_world_cell(world);
3130 }
3131}
3132
3133unsafe impl<D: ReadOnlyQueryData + 'static, F: QueryFilter + 'static> QueryData
3137 for NestedQuery<D, F>
3138{
3139 const IS_READ_ONLY: bool = D::IS_READ_ONLY;
3140 const IS_ARCHETYPAL: bool = true;
3145 type ReadOnly = NestedQuery<D, F>;
3146 type Item<'w, 's> = Query<'w, 's, D, F>;
3147
3148 fn shrink<'wlong: 'wshort, 'wshort, 's>(
3149 item: Self::Item<'wlong, 's>,
3150 ) -> Self::Item<'wshort, 's> {
3151 item
3152 }
3153
3154 #[inline(always)]
3155 unsafe fn fetch<'w, 's>(
3156 state: &'s Self::State,
3157 fetch: &mut Self::Fetch<'w>,
3158 _entity: Entity,
3159 _table_row: TableRow,
3160 ) -> Option<Self::Item<'w, 's>> {
3161 unsafe {
3167 Some(state.query_unchecked_manual_with_ticks(
3168 fetch.world,
3169 fetch.last_run,
3170 fetch.this_run,
3171 ))
3172 }
3173 }
3174
3175 fn iter_access(_state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
3176 iter::empty()
3179 }
3180}
3181
3182unsafe impl<D: ReadOnlyQueryData, F: QueryFilter> ReadOnlyQueryData for NestedQuery<D, F> {}
3184
3185unsafe impl<D: ReadOnlyQueryData, F: QueryFilter> IterQueryData for NestedQuery<D, F> {}
3189
3190impl<D: ReadOnlyQueryData, F: QueryFilter> ArchetypeQueryData for NestedQuery<D, F> {}
3195
3196#[doc(hidden)]
3197pub struct OptionFetch<'w, T: WorldQuery> {
3198 fetch: T::Fetch<'w>,
3199 matches: bool,
3200}
3201
3202impl<T: WorldQuery> Clone for OptionFetch<'_, T> {
3203 fn clone(&self) -> Self {
3204 Self {
3205 fetch: self.fetch.clone(),
3206 matches: self.matches,
3207 }
3208 }
3209}
3210
3211unsafe impl<T: WorldQuery> WorldQuery for Option<T> {
3216 type Fetch<'w> = OptionFetch<'w, T>;
3217 type State = T::State;
3218
3219 fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
3220 OptionFetch {
3221 fetch: T::shrink_fetch(fetch.fetch),
3222 matches: fetch.matches,
3223 }
3224 }
3225
3226 #[inline]
3227 unsafe fn init_fetch<'w, 's>(
3228 world: UnsafeWorldCell<'w>,
3229 state: &'s T::State,
3230 last_run: Tick,
3231 this_run: Tick,
3232 ) -> OptionFetch<'w, T> {
3233 OptionFetch {
3234 fetch: unsafe { T::init_fetch(world, state, last_run, this_run) },
3236 matches: false,
3237 }
3238 }
3239
3240 const IS_DENSE: bool = T::IS_DENSE;
3241
3242 #[inline]
3243 unsafe fn set_archetype<'w, 's>(
3244 fetch: &mut OptionFetch<'w, T>,
3245 state: &'s T::State,
3246 archetype: &'w Archetype,
3247 table: &'w Table,
3248 ) {
3249 fetch.matches = T::matches_component_set(state, &|id| archetype.contains(id));
3250 if fetch.matches {
3251 unsafe {
3253 T::set_archetype(&mut fetch.fetch, state, archetype, table);
3254 }
3255 }
3256 }
3257
3258 #[inline]
3259 unsafe fn set_table<'w, 's>(
3260 fetch: &mut OptionFetch<'w, T>,
3261 state: &'s T::State,
3262 table: &'w Table,
3263 ) {
3264 fetch.matches = T::matches_component_set(state, &|id| table.has_column(id));
3265 if fetch.matches {
3266 unsafe {
3268 T::set_table(&mut fetch.fetch, state, table);
3269 }
3270 }
3271 }
3272
3273 fn update_component_access(state: &T::State, access: &mut FilteredAccess) {
3274 let mut intermediate = access.clone();
3284 T::update_component_access(state, &mut intermediate);
3285 access.extend_access(&intermediate);
3286 }
3287
3288 fn init_nested_access(
3289 state: &Self::State,
3290 system_name: Option<&str>,
3291 component_access_set: &mut FilteredAccessSet,
3292 world: UnsafeWorldCell,
3293 ) {
3294 T::init_nested_access(state, system_name, component_access_set, world);
3295 }
3296
3297 fn init_state(world: &mut World) -> T::State {
3298 T::init_state(world)
3299 }
3300
3301 fn get_state(components: &Components) -> Option<Self::State> {
3302 T::get_state(components)
3303 }
3304
3305 fn matches_component_set(
3306 _state: &T::State,
3307 _set_contains_id: &impl Fn(ComponentId) -> bool,
3308 ) -> bool {
3309 true
3310 }
3311
3312 fn update_archetypes(state: &mut Self::State, world: UnsafeWorldCell) {
3313 T::update_archetypes(state, world);
3314 }
3315}
3316
3317unsafe impl<T: QueryData> QueryData for Option<T> {
3319 const IS_READ_ONLY: bool = T::IS_READ_ONLY;
3320 const IS_ARCHETYPAL: bool = true;
3323 type ReadOnly = Option<T::ReadOnly>;
3324 type Item<'w, 's> = Option<T::Item<'w, 's>>;
3325
3326 fn shrink<'wlong: 'wshort, 'wshort, 's>(
3327 item: Self::Item<'wlong, 's>,
3328 ) -> Self::Item<'wshort, 's> {
3329 item.map(T::shrink)
3330 }
3331
3332 #[inline(always)]
3333 unsafe fn fetch<'w, 's>(
3334 state: &'s Self::State,
3335 fetch: &mut Self::Fetch<'w>,
3336 entity: Entity,
3337 table_row: TableRow,
3338 ) -> Option<Self::Item<'w, 's>> {
3339 Some(
3340 fetch
3341 .matches
3342 .then(|| unsafe { T::fetch(state, &mut fetch.fetch, entity, table_row) })
3344 .flatten(),
3345 )
3346 }
3347
3348 fn iter_access(state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
3349 T::iter_access(state)
3350 }
3351}
3352
3353unsafe impl<T: IterQueryData> IterQueryData for Option<T> {}
3355
3356unsafe impl<T: ReadOnlyQueryData> ReadOnlyQueryData for Option<T> {}
3358
3359unsafe impl<T: SingleEntityQueryData> SingleEntityQueryData for Option<T> {}
3361
3362impl<T: ReleaseStateQueryData> ReleaseStateQueryData for Option<T> {
3363 fn release_state<'w>(item: Self::Item<'w, '_>) -> Self::Item<'w, 'static> {
3364 item.map(T::release_state)
3365 }
3366}
3367
3368impl<T: QueryData> ArchetypeQueryData for Option<T> {}
3371
3372impl<T: ContiguousQueryData> ContiguousQueryData for Option<T> {
3373 type Contiguous<'w, 's> = Option<T::Contiguous<'w, 's>>;
3374
3375 unsafe fn fetch_contiguous<'w, 's>(
3376 state: &'s Self::State,
3377 fetch: &mut Self::Fetch<'w>,
3378 entities: &'w [Entity],
3379 range: Range<u32>,
3380 ) -> Self::Contiguous<'w, 's> {
3381 fetch
3382 .matches
3383 .then(|| unsafe { T::fetch_contiguous(state, &mut fetch.fetch, entities, range) })
3385 }
3386}
3387
3388pub struct Has<T>(PhantomData<T>);
3452
3453impl<T> core::fmt::Debug for Has<T> {
3454 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> {
3455 write!(f, "Has<{}>", DebugName::type_name::<T>())
3456 }
3457}
3458
3459unsafe impl<T: Component> WorldQuery for Has<T> {
3463 type Fetch<'w> = bool;
3464 type State = ComponentId;
3465
3466 fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
3467 fetch
3468 }
3469
3470 #[inline]
3471 unsafe fn init_fetch<'w, 's>(
3472 _world: UnsafeWorldCell<'w>,
3473 _state: &'s Self::State,
3474 _last_run: Tick,
3475 _this_run: Tick,
3476 ) -> Self::Fetch<'w> {
3477 false
3478 }
3479
3480 const IS_DENSE: bool = {
3481 match T::STORAGE_TYPE {
3482 StorageType::Table => true,
3483 StorageType::SparseSet => false,
3484 }
3485 };
3486
3487 #[inline]
3488 unsafe fn set_archetype<'w, 's>(
3489 fetch: &mut Self::Fetch<'w>,
3490 state: &'s Self::State,
3491 archetype: &'w Archetype,
3492 _table: &Table,
3493 ) {
3494 *fetch = archetype.contains(*state);
3495 }
3496
3497 #[inline]
3498 unsafe fn set_table<'w, 's>(
3499 fetch: &mut Self::Fetch<'w>,
3500 state: &'s Self::State,
3501 table: &'w Table,
3502 ) {
3503 *fetch = table.has_column(*state);
3504 }
3505
3506 fn update_component_access(&component_id: &Self::State, access: &mut FilteredAccess) {
3507 access.access_mut().add_archetypal(component_id);
3508 }
3509
3510 fn init_nested_access(
3511 _state: &Self::State,
3512 _system_name: Option<&str>,
3513 _component_access_set: &mut FilteredAccessSet,
3514 _world: UnsafeWorldCell,
3515 ) {
3516 }
3517
3518 fn init_state(world: &mut World) -> ComponentId {
3519 world.register_component::<T>()
3520 }
3521
3522 fn get_state(components: &Components) -> Option<Self::State> {
3523 components.component_id::<T>()
3524 }
3525
3526 fn matches_component_set(
3527 _state: &Self::State,
3528 _set_contains_id: &impl Fn(ComponentId) -> bool,
3529 ) -> bool {
3530 true
3532 }
3533
3534 fn update_archetypes(_state: &mut Self::State, _world: UnsafeWorldCell) {}
3535}
3536
3537unsafe impl<T: Component> QueryData for Has<T> {
3539 const IS_READ_ONLY: bool = true;
3540 const IS_ARCHETYPAL: bool = true;
3541 type ReadOnly = Self;
3542 type Item<'w, 's> = bool;
3543
3544 fn shrink<'wlong: 'wshort, 'wshort, 's>(
3545 item: Self::Item<'wlong, 's>,
3546 ) -> Self::Item<'wshort, 's> {
3547 item
3548 }
3549
3550 #[inline(always)]
3551 unsafe fn fetch<'w, 's>(
3552 _state: &'s Self::State,
3553 fetch: &mut Self::Fetch<'w>,
3554 _entity: Entity,
3555 _table_row: TableRow,
3556 ) -> Option<Self::Item<'w, 's>> {
3557 Some(*fetch)
3558 }
3559
3560 fn iter_access(_state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
3561 iter::empty()
3562 }
3563}
3564
3565unsafe impl<T: Component> IterQueryData for Has<T> {}
3567
3568unsafe impl<T: Component> ReadOnlyQueryData for Has<T> {}
3570
3571unsafe impl<T: Component> SingleEntityQueryData for Has<T> {}
3573
3574impl<T: Component> ReleaseStateQueryData for Has<T> {
3575 fn release_state<'w>(item: Self::Item<'w, '_>) -> Self::Item<'w, 'static> {
3576 item
3577 }
3578}
3579
3580impl<T: Component> ArchetypeQueryData for Has<T> {}
3581
3582impl<T: Component> ContiguousQueryData for Has<T> {
3583 type Contiguous<'w, 's> = bool;
3584
3585 unsafe fn fetch_contiguous<'w, 's>(
3586 _state: &'s Self::State,
3587 fetch: &mut Self::Fetch<'w>,
3588 _entities: &'w [Entity],
3589 _range: Range<u32>,
3590 ) -> Self::Contiguous<'w, 's> {
3591 *fetch
3592 }
3593}
3594
3595pub struct AnyOf<T>(PhantomData<T>);
3601
3602macro_rules! impl_tuple_query_data {
3603 ($(#[$meta:meta])* $(($name: ident, $item: ident, $state: ident)),*) => {
3604 #[expect(
3605 clippy::allow_attributes,
3606 reason = "This is a tuple-related macro; as such the lints below may not always apply."
3607 )]
3608 #[allow(
3609 non_snake_case,
3610 reason = "The names of some variables are provided by the macro's caller, not by us."
3611 )]
3612 #[allow(
3613 unused_variables,
3614 reason = "Zero-length tuples won't use any of the parameters."
3615 )]
3616 #[allow(
3617 clippy::unused_unit,
3618 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."
3619 )]
3620 $(#[$meta])*
3621 unsafe impl<$($name: QueryData),*> QueryData for ($($name,)*) {
3623 const IS_READ_ONLY: bool = true $(&& $name::IS_READ_ONLY)*;
3624 const IS_ARCHETYPAL: bool = true $(&& $name::IS_ARCHETYPAL)*;
3625 type ReadOnly = ($($name::ReadOnly,)*);
3626 type Item<'w, 's> = ($($name::Item<'w, 's>,)*);
3627
3628 fn shrink<'wlong: 'wshort, 'wshort, 's>(item: Self::Item<'wlong, 's>) -> Self::Item<'wshort, 's> {
3629 let ($($name,)*) = item;
3630 ($(
3631 $name::shrink($name),
3632 )*)
3633 }
3634
3635 #[inline]
3636 fn provide_extra_access(
3637 state: &mut Self::State,
3638 access: &mut Access,
3639 available_access: &Access,
3640 ) {
3641 let ($($name,)*) = state;
3642 $($name::provide_extra_access($name, access, available_access);)*
3643 }
3644
3645 #[inline(always)]
3646 unsafe fn fetch<'w, 's>(
3647 state: &'s Self::State,
3648 fetch: &mut Self::Fetch<'w>,
3649 entity: Entity,
3650 table_row: TableRow
3651 ) -> Option<Self::Item<'w, 's>> {
3652 let ($($state,)*) = state;
3653 let ($($name,)*) = fetch;
3654 Some(($(unsafe { $name::fetch($state, $name, entity, table_row) }?,)*))
3656 }
3657
3658 fn iter_access(state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
3659 let ($($name,)*) = state;
3660 iter::empty()$(.chain($name::iter_access($name)))*
3661 }
3662 }
3663
3664 $(#[$meta])*
3665 unsafe impl<$($name: IterQueryData),*> IterQueryData for ($($name,)*) {}
3667
3668 $(#[$meta])*
3669 unsafe impl<$($name: ReadOnlyQueryData),*> ReadOnlyQueryData for ($($name,)*) {}
3671
3672 $(#[$meta])*
3673 unsafe impl<$($name: SingleEntityQueryData),*> SingleEntityQueryData for ($($name,)*) {}
3675
3676 #[expect(
3677 clippy::allow_attributes,
3678 reason = "This is a tuple-related macro; as such the lints below may not always apply."
3679 )]
3680 #[allow(
3681 clippy::unused_unit,
3682 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."
3683 )]
3684 $(#[$meta])*
3685 impl<$($name: ReleaseStateQueryData),*> ReleaseStateQueryData for ($($name,)*) {
3686 fn release_state<'w>(($($item,)*): Self::Item<'w, '_>) -> Self::Item<'w, 'static> {
3687 ($($name::release_state($item),)*)
3688 }
3689 }
3690
3691 $(#[$meta])*
3692 impl<$($name: ArchetypeQueryData),*> ArchetypeQueryData for ($($name,)*) {}
3693
3694 #[expect(
3695 clippy::allow_attributes,
3696 reason = "This is a tuple-related macro; as such the lints below may not always apply."
3697 )]
3698 #[allow(
3699 non_snake_case,
3700 reason = "The names of some variables are provided by the macro's caller, not by us."
3701 )]
3702 #[allow(
3703 unused_variables,
3704 reason = "Zero-length tuples won't use any of the parameters."
3705 )]
3706 #[allow(
3707 clippy::unused_unit,
3708 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."
3709 )]
3710 $(#[$meta])*
3711 impl<$($name: ContiguousQueryData),*> ContiguousQueryData for ($($name,)*) {
3712 type Contiguous<'w, 's> = ($($name::Contiguous::<'w, 's>,)*);
3713
3714 unsafe fn fetch_contiguous<'w, 's>(
3715 state: &'s Self::State,
3716 fetch: &mut Self::Fetch<'w>,
3717 entities: &'w [Entity],
3718 range: Range<u32>,
3719 ) -> Self::Contiguous<'w, 's> {
3720 let ($($state,)*) = state;
3721 let ($($name,)*) = fetch;
3722 ($(unsafe {
3724 $name::fetch_contiguous($state, $name, entities, range.clone())
3725 },)*)
3726 }
3727 }
3728 };
3729}
3730
3731macro_rules! impl_anytuple_fetch {
3732 ($(#[$meta:meta])* $(($name: ident, $state: ident, $item: ident)),*) => {
3733 $(#[$meta])*
3734 #[expect(
3735 clippy::allow_attributes,
3736 reason = "This is a tuple-related macro; as such the lints below may not always apply."
3737 )]
3738 #[allow(
3739 non_snake_case,
3740 reason = "The names of some variables are provided by the macro's caller, not by us."
3741 )]
3742 #[allow(
3743 unused_variables,
3744 reason = "Zero-length tuples won't use any of the parameters."
3745 )]
3746 #[allow(
3747 clippy::unused_unit,
3748 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."
3749 )]
3750 unsafe impl<$($name: WorldQuery),*> WorldQuery for AnyOf<($($name,)*)> {
3756 type Fetch<'w> = ($(($name::Fetch<'w>, bool),)*);
3757 type State = ($($name::State,)*);
3758
3759 fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
3760 let ($($name,)*) = fetch;
3761 ($(
3762 ($name::shrink_fetch($name.0), $name.1),
3763 )*)
3764 }
3765
3766 #[inline]
3767 unsafe fn init_fetch<'w, 's>(_world: UnsafeWorldCell<'w>, state: &'s Self::State, _last_run: Tick, _this_run: Tick) -> Self::Fetch<'w> {
3768 let ($($name,)*) = state;
3769 ($(( unsafe { $name::init_fetch(_world, $name, _last_run, _this_run) }, false),)*)
3771 }
3772
3773 const IS_DENSE: bool = true $(&& $name::IS_DENSE)*;
3774
3775 #[inline]
3776 unsafe fn set_archetype<'w, 's>(
3777 _fetch: &mut Self::Fetch<'w>,
3778 _state: &'s Self::State,
3779 _archetype: &'w Archetype,
3780 _table: &'w Table
3781 ) {
3782 let ($($name,)*) = _fetch;
3783 let ($($state,)*) = _state;
3784 $(
3785 $name.1 = $name::matches_component_set($state, &|id| _archetype.contains(id));
3786 if $name.1 {
3787 unsafe { $name::set_archetype(&mut $name.0, $state, _archetype, _table); }
3789 }
3790 )*
3791 }
3792
3793 #[inline]
3794 unsafe fn set_table<'w, 's>(_fetch: &mut Self::Fetch<'w>, _state: &'s Self::State, _table: &'w Table) {
3795 let ($($name,)*) = _fetch;
3796 let ($($state,)*) = _state;
3797 $(
3798 $name.1 = $name::matches_component_set($state, &|id| _table.has_column(id));
3799 if $name.1 {
3800 unsafe { $name::set_table(&mut $name.0, $state, _table); }
3802 }
3803 )*
3804 }
3805
3806 fn update_component_access(state: &Self::State, access: &mut FilteredAccess) {
3807 let ($($name,)*) = state;
3809
3810 let mut _new_access = FilteredAccess::matches_nothing();
3811
3812 $(
3813 let mut intermediate = access.clone();
3817 $name::update_component_access($name, &mut intermediate);
3818 _new_access.append_or(&intermediate);
3819 )*
3820
3821 access.filter_sets = _new_access.filter_sets;
3823
3824 <($(Option<$name>,)*)>::update_component_access(state, access);
3830
3831 }
3832
3833 fn init_nested_access(
3834 state: &Self::State,
3835 system_name: Option<&str>,
3836 component_access_set: &mut FilteredAccessSet,
3837 world: UnsafeWorldCell,
3838 ) {
3839 <($(Option<$name>,)*)>::init_nested_access(state, system_name, component_access_set, world);
3840 }
3841
3842 fn init_state(world: &mut World) -> Self::State {
3843 ($($name::init_state(world),)*)
3844 }
3845 fn get_state(components: &Components) -> Option<Self::State> {
3846 Some(($($name::get_state(components)?,)*))
3847 }
3848
3849 fn matches_component_set(_state: &Self::State, _set_contains_id: &impl Fn(ComponentId) -> bool) -> bool {
3850 let ($($name,)*) = _state;
3851 false $(|| $name::matches_component_set($name, _set_contains_id))*
3852 }
3853
3854 fn update_archetypes(state: &mut Self::State, world: UnsafeWorldCell) {
3855 <($(Option<$name>,)*)>::update_archetypes(state, world);
3856 }
3857 }
3858
3859 #[expect(
3860 clippy::allow_attributes,
3861 reason = "This is a tuple-related macro; as such the lints below may not always apply."
3862 )]
3863 #[allow(
3864 non_snake_case,
3865 reason = "The names of some variables are provided by the macro's caller, not by us."
3866 )]
3867 #[allow(
3868 unused_variables,
3869 reason = "Zero-length tuples won't use any of the parameters."
3870 )]
3871 #[allow(
3872 clippy::unused_unit,
3873 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."
3874 )]
3875 $(#[$meta])*
3876 unsafe impl<$($name: QueryData),*> QueryData for AnyOf<($($name,)*)> {
3878 const IS_READ_ONLY: bool = true $(&& $name::IS_READ_ONLY)*;
3879 const IS_ARCHETYPAL: bool = true $(&& $name::IS_ARCHETYPAL)*;
3880 type ReadOnly = AnyOf<($($name::ReadOnly,)*)>;
3881 type Item<'w, 's> = ($(Option<$name::Item<'w, 's>>,)*);
3882
3883 fn shrink<'wlong: 'wshort, 'wshort, 's>(item: Self::Item<'wlong, 's>) -> Self::Item<'wshort, 's> {
3884 let ($($name,)*) = item;
3885 ($(
3886 $name.map($name::shrink),
3887 )*)
3888 }
3889
3890 #[inline(always)]
3891 unsafe fn fetch<'w, 's>(
3892 _state: &'s Self::State,
3893 _fetch: &mut Self::Fetch<'w>,
3894 _entity: Entity,
3895 _table_row: TableRow
3896 ) -> Option<Self::Item<'w, 's>> {
3897 let ($($name,)*) = _fetch;
3898 let ($($state,)*) = _state;
3899 let result = ($(
3900 $name.1.then(|| unsafe { $name::fetch($state, &mut $name.0, _entity, _table_row) }).flatten(),
3902 )*);
3903 (Self::IS_ARCHETYPAL
3906 || !matches!(result, ($(Option::<QueryItem<$name>>::None,)*))
3910 || !(false $(|| $name.1)*))
3914 .then_some(result)
3915 }
3916
3917 fn iter_access(state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
3918 let ($($name,)*) = state;
3919 iter::empty()$(.chain($name::iter_access($name)))*
3920 }
3921 }
3922
3923 $(#[$meta])*
3924 unsafe impl<$($name: IterQueryData),*> IterQueryData for AnyOf<($($name,)*)> {}
3926
3927 $(#[$meta])*
3928 unsafe impl<$($name: ReadOnlyQueryData),*> ReadOnlyQueryData for AnyOf<($($name,)*)> {}
3930
3931 $(#[$meta])*
3932 unsafe impl<$($name: SingleEntityQueryData),*> SingleEntityQueryData for AnyOf<($($name,)*)> {}
3934
3935 #[expect(
3936 clippy::allow_attributes,
3937 reason = "This is a tuple-related macro; as such the lints below may not always apply."
3938 )]
3939 #[allow(
3940 clippy::unused_unit,
3941 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."
3942 )]
3943 impl<$($name: ReleaseStateQueryData),*> ReleaseStateQueryData for AnyOf<($($name,)*)> {
3944 fn release_state<'w>(($($item,)*): Self::Item<'w, '_>) -> Self::Item<'w, 'static> {
3945 ($($item.map(|$item| $name::release_state($item)),)*)
3946 }
3947 }
3948
3949 $(#[$meta])*
3950 impl<$($name: ArchetypeQueryData),*> ArchetypeQueryData for AnyOf<($($name,)*)> {}
3951
3952
3953 #[expect(
3954 clippy::allow_attributes,
3955 reason = "This is a tuple-related macro; as such the lints below may not always apply."
3956 )]
3957 #[allow(
3958 non_snake_case,
3959 reason = "The names of some variables are provided by the macro's caller, not by us."
3960 )]
3961 #[allow(
3962 unused_variables,
3963 reason = "Zero-length tuples won't use any of the parameters."
3964 )]
3965 #[allow(
3966 clippy::unused_unit,
3967 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."
3968 )]
3969 $(#[$meta])*
3970 impl<$($name: ContiguousQueryData),*> ContiguousQueryData for AnyOf<($($name,)*)> {
3971 type Contiguous<'w, 's> = ($(Option<$name::Contiguous<'w,'s>>,)*);
3972
3973 unsafe fn fetch_contiguous<'w, 's>(
3974 state: &'s Self::State,
3975 fetch: &mut Self::Fetch<'w>,
3976 entities: &'w [Entity],
3977 range: Range<u32>,
3978 ) -> Self::Contiguous<'w, 's> {
3979 let ($($name,)*) = fetch;
3980 let ($($state,)*) = state;
3981 ($(
3983 $name.1.then(|| unsafe {
3985 $name::fetch_contiguous($state, &mut $name.0, entities, range.clone())
3986 }),
3987 )*)
3988 }
3989 }
3990 };
3991}
3992
3993all_tuples!(
3994 #[doc(fake_variadic)]
3995 impl_tuple_query_data,
3996 0,
3997 15,
3998 F,
3999 i,
4000 s
4001);
4002all_tuples!(
4003 #[doc(fake_variadic)]
4004 impl_anytuple_fetch,
4005 0,
4006 15,
4007 F,
4008 S,
4009 i
4010);
4011
4012pub(crate) struct NopWorldQuery<D: QueryData>(PhantomData<D>);
4016
4017unsafe impl<D: QueryData> WorldQuery for NopWorldQuery<D> {
4021 type Fetch<'w> = ();
4022 type State = D::State;
4023
4024 fn shrink_fetch<'wlong: 'wshort, 'wshort>(_fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
4025 }
4026
4027 #[inline(always)]
4028 unsafe fn init_fetch(
4029 _world: UnsafeWorldCell,
4030 _state: &D::State,
4031 _last_run: Tick,
4032 _this_run: Tick,
4033 ) {
4034 }
4035
4036 const IS_DENSE: bool = D::IS_DENSE;
4037
4038 #[inline(always)]
4039 unsafe fn set_archetype(
4040 _fetch: &mut (),
4041 _state: &D::State,
4042 _archetype: &Archetype,
4043 _tables: &Table,
4044 ) {
4045 }
4046
4047 #[inline(always)]
4048 unsafe fn set_table<'w>(_fetch: &mut (), _state: &D::State, _table: &Table) {}
4049
4050 fn update_component_access(_state: &D::State, _access: &mut FilteredAccess) {}
4051
4052 fn init_nested_access(
4053 _state: &Self::State,
4054 _system_name: Option<&str>,
4055 _component_access_set: &mut FilteredAccessSet,
4056 _world: UnsafeWorldCell,
4057 ) {
4058 }
4059
4060 fn init_state(world: &mut World) -> Self::State {
4061 D::init_state(world)
4062 }
4063
4064 fn get_state(components: &Components) -> Option<Self::State> {
4065 D::get_state(components)
4066 }
4067
4068 fn matches_component_set(
4069 state: &Self::State,
4070 set_contains_id: &impl Fn(ComponentId) -> bool,
4071 ) -> bool {
4072 D::matches_component_set(state, set_contains_id)
4073 }
4074
4075 fn update_archetypes(state: &mut Self::State, world: UnsafeWorldCell) {
4076 D::update_archetypes(state, world);
4077 }
4078}
4079
4080unsafe impl<D: QueryData> QueryData for NopWorldQuery<D> {
4082 const IS_READ_ONLY: bool = true;
4083 const IS_ARCHETYPAL: bool = true;
4084 type ReadOnly = Self;
4085 type Item<'w, 's> = ();
4086
4087 fn shrink<'wlong: 'wshort, 'wshort, 's>(
4088 _item: Self::Item<'wlong, 's>,
4089 ) -> Self::Item<'wshort, 's> {
4090 }
4091
4092 #[inline(always)]
4093 unsafe fn fetch<'w, 's>(
4094 _state: &'s Self::State,
4095 _fetch: &mut Self::Fetch<'w>,
4096 _entity: Entity,
4097 _table_row: TableRow,
4098 ) -> Option<Self::Item<'w, 's>> {
4099 Some(())
4100 }
4101
4102 fn iter_access(_state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
4103 iter::empty()
4104 }
4105}
4106
4107unsafe impl<D: QueryData> IterQueryData for NopWorldQuery<D> {}
4109
4110unsafe impl<D: QueryData> ReadOnlyQueryData for NopWorldQuery<D> {}
4112
4113unsafe impl<D: QueryData> SingleEntityQueryData for NopWorldQuery<D> {}
4115
4116impl<D: QueryData> ReleaseStateQueryData for NopWorldQuery<D> {
4117 fn release_state<'w>(_item: Self::Item<'w, '_>) -> Self::Item<'w, 'static> {}
4118}
4119
4120impl<D: QueryData> ArchetypeQueryData for NopWorldQuery<D> {}
4121
4122unsafe impl<T: ?Sized> WorldQuery for PhantomData<T> {
4126 type Fetch<'w> = ();
4127
4128 type State = ();
4129
4130 fn shrink_fetch<'wlong: 'wshort, 'wshort>(_fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
4131 }
4132
4133 unsafe fn init_fetch<'w, 's>(
4134 _world: UnsafeWorldCell<'w>,
4135 _state: &'s Self::State,
4136 _last_run: Tick,
4137 _this_run: Tick,
4138 ) -> Self::Fetch<'w> {
4139 }
4140
4141 const IS_DENSE: bool = true;
4144
4145 unsafe fn set_archetype<'w, 's>(
4146 _fetch: &mut Self::Fetch<'w>,
4147 _state: &'s Self::State,
4148 _archetype: &'w Archetype,
4149 _table: &'w Table,
4150 ) {
4151 }
4152
4153 unsafe fn set_table<'w, 's>(
4154 _fetch: &mut Self::Fetch<'w>,
4155 _state: &'s Self::State,
4156 _table: &'w Table,
4157 ) {
4158 }
4159
4160 fn update_component_access(_state: &Self::State, _access: &mut FilteredAccess) {}
4161
4162 fn init_nested_access(
4163 _state: &Self::State,
4164 _system_name: Option<&str>,
4165 _component_access_set: &mut FilteredAccessSet,
4166 _world: UnsafeWorldCell,
4167 ) {
4168 }
4169
4170 fn init_state(_world: &mut World) -> Self::State {}
4171
4172 fn get_state(_components: &Components) -> Option<Self::State> {
4173 Some(())
4174 }
4175
4176 fn matches_component_set(
4177 _state: &Self::State,
4178 _set_contains_id: &impl Fn(ComponentId) -> bool,
4179 ) -> bool {
4180 true
4181 }
4182
4183 fn update_archetypes(_state: &mut Self::State, _world: UnsafeWorldCell) {}
4184}
4185
4186unsafe impl<T: ?Sized> QueryData for PhantomData<T> {
4188 const IS_READ_ONLY: bool = true;
4189 const IS_ARCHETYPAL: bool = true;
4190 type ReadOnly = Self;
4191 type Item<'w, 's> = ();
4192
4193 fn shrink<'wlong: 'wshort, 'wshort, 's>(
4194 _item: Self::Item<'wlong, 's>,
4195 ) -> Self::Item<'wshort, 's> {
4196 }
4197
4198 unsafe fn fetch<'w, 's>(
4199 _state: &'s Self::State,
4200 _fetch: &mut Self::Fetch<'w>,
4201 _entity: Entity,
4202 _table_row: TableRow,
4203 ) -> Option<Self::Item<'w, 's>> {
4204 Some(())
4205 }
4206
4207 fn iter_access(_state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
4208 iter::empty()
4209 }
4210}
4211
4212unsafe impl<T: ?Sized> IterQueryData for PhantomData<T> {}
4214
4215unsafe impl<T: ?Sized> ReadOnlyQueryData for PhantomData<T> {}
4217
4218unsafe impl<T: ?Sized> SingleEntityQueryData for PhantomData<T> {}
4220
4221impl<T: ?Sized> ReleaseStateQueryData for PhantomData<T> {
4222 fn release_state<'w>(_item: Self::Item<'w, '_>) -> Self::Item<'w, 'static> {}
4223}
4224
4225impl<T: ?Sized> ArchetypeQueryData for PhantomData<T> {}
4226
4227pub(super) union StorageSwitch<C: Component, T: Copy, S: Copy> {
4230 table: T,
4232 sparse_set: S,
4234 _marker: PhantomData<C>,
4235}
4236
4237impl<C: Component, T: Copy, S: Copy> StorageSwitch<C, T, S> {
4238 pub fn new(table: impl FnOnce() -> T, sparse_set: impl FnOnce() -> S) -> Self {
4241 match C::STORAGE_TYPE {
4242 StorageType::Table => Self { table: table() },
4243 StorageType::SparseSet => Self {
4244 sparse_set: sparse_set(),
4245 },
4246 }
4247 }
4248
4249 #[inline]
4259 pub unsafe fn set_table(&mut self, table: T) {
4260 match C::STORAGE_TYPE {
4261 StorageType::Table => self.table = table,
4262 _ => {
4263 #[cfg(debug_assertions)]
4264 unreachable!();
4265 #[cfg(not(debug_assertions))]
4266 core::hint::unreachable_unchecked()
4267 }
4268 }
4269 }
4270
4271 pub fn extract<R>(&self, table: impl FnOnce(T) -> R, sparse_set: impl FnOnce(S) -> R) -> R {
4274 match C::STORAGE_TYPE {
4275 StorageType::Table => table(
4276 unsafe { self.table },
4278 ),
4279 StorageType::SparseSet => sparse_set(
4280 unsafe { self.sparse_set },
4282 ),
4283 }
4284 }
4285}
4286
4287impl<C: Component, T: Copy, S: Copy> Clone for StorageSwitch<C, T, S> {
4288 fn clone(&self) -> Self {
4289 *self
4290 }
4291}
4292
4293impl<C: Component, T: Copy, S: Copy> Copy for StorageSwitch<C, T, S> {}
4294
4295#[cfg(test)]
4296mod tests {
4297 use core::sync::atomic::{AtomicUsize, Ordering};
4298 use std::sync::Mutex;
4299
4300 use super::*;
4301 use crate::batching::BatchingStrategy;
4302 use crate::change_detection::DetectChanges;
4303 use crate::query::{QueryNotDenseError, Without};
4304 use crate::system::{assert_is_system, Query};
4305 use alloc::sync::Arc;
4306 use alloc::{vec, vec::Vec};
4307 use bevy_ecs::prelude::Schedule;
4308 use bevy_ecs_macros::QueryData;
4309 use fixedbitset::FixedBitSet;
4310
4311 #[derive(Component)]
4312 pub struct A;
4313
4314 #[derive(Component)]
4315 pub struct B;
4316
4317 #[test]
4319 fn world_query_struct_variants() {
4320 #[derive(QueryData)]
4321 pub struct NamedQuery {
4322 id: Entity,
4323 a: &'static A,
4324 }
4325
4326 #[derive(QueryData)]
4327 pub struct TupleQuery(&'static A, &'static B);
4328
4329 #[derive(QueryData)]
4330 pub struct UnitQuery;
4331
4332 fn my_system(_: Query<(NamedQuery, TupleQuery, UnitQuery)>) {}
4333
4334 assert_is_system(my_system);
4335 }
4336
4337 #[test]
4339 fn world_query_phantom_data() {
4340 #[derive(QueryData)]
4341 pub struct IgnoredQuery<Marker> {
4342 id: Entity,
4343 _marker: PhantomData<Marker>,
4344 }
4345
4346 fn ignored_system(_: Query<IgnoredQuery<()>>) {}
4347
4348 assert_is_system(ignored_system);
4349 }
4350
4351 #[test]
4352 fn derive_release_state() {
4353 struct NonReleaseQueryData;
4354
4355 unsafe impl WorldQuery for NonReleaseQueryData {
4359 type Fetch<'w> = ();
4360 type State = ();
4361
4362 fn shrink_fetch<'wlong: 'wshort, 'wshort>(
4363 _: Self::Fetch<'wlong>,
4364 ) -> Self::Fetch<'wshort> {
4365 }
4366
4367 unsafe fn init_fetch<'w, 's>(
4368 _world: UnsafeWorldCell<'w>,
4369 _state: &'s Self::State,
4370 _last_run: Tick,
4371 _this_run: Tick,
4372 ) -> Self::Fetch<'w> {
4373 }
4374
4375 const IS_DENSE: bool = true;
4376
4377 #[inline]
4378 unsafe fn set_archetype<'w, 's>(
4379 _fetch: &mut Self::Fetch<'w>,
4380 _state: &'s Self::State,
4381 _archetype: &'w Archetype,
4382 _table: &Table,
4383 ) {
4384 }
4385
4386 #[inline]
4387 unsafe fn set_table<'w, 's>(
4388 _fetch: &mut Self::Fetch<'w>,
4389 _state: &'s Self::State,
4390 _table: &'w Table,
4391 ) {
4392 }
4393
4394 fn update_component_access(_state: &Self::State, _access: &mut FilteredAccess) {}
4395
4396 fn init_nested_access(
4397 _state: &Self::State,
4398 _system_name: Option<&str>,
4399 _component_access_set: &mut FilteredAccessSet,
4400 _world: UnsafeWorldCell,
4401 ) {
4402 }
4403
4404 fn init_state(_world: &mut World) {}
4405
4406 fn get_state(_components: &Components) -> Option<()> {
4407 Some(())
4408 }
4409
4410 fn matches_component_set(
4411 _state: &Self::State,
4412 _set_contains_id: &impl Fn(ComponentId) -> bool,
4413 ) -> bool {
4414 true
4415 }
4416
4417 fn update_archetypes(_state: &mut Self::State, _world: UnsafeWorldCell) {}
4418 }
4419
4420 unsafe impl QueryData for NonReleaseQueryData {
4422 type ReadOnly = Self;
4423 const IS_READ_ONLY: bool = true;
4424 const IS_ARCHETYPAL: bool = true;
4425
4426 type Item<'w, 's> = ();
4427
4428 fn shrink<'wlong: 'wshort, 'wshort, 's>(
4429 _item: Self::Item<'wlong, 's>,
4430 ) -> Self::Item<'wshort, 's> {
4431 }
4432
4433 #[inline(always)]
4434 unsafe fn fetch<'w, 's>(
4435 _state: &'s Self::State,
4436 _fetch: &mut Self::Fetch<'w>,
4437 _entity: Entity,
4438 _table_row: TableRow,
4439 ) -> Option<Self::Item<'w, 's>> {
4440 Some(())
4441 }
4442
4443 fn iter_access(_state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
4444 iter::empty()
4445 }
4446 }
4447
4448 unsafe impl ReadOnlyQueryData for NonReleaseQueryData {}
4450
4451 unsafe impl IterQueryData for NonReleaseQueryData {}
4453
4454 impl ArchetypeQueryData for NonReleaseQueryData {}
4455
4456 #[derive(QueryData)]
4457 pub struct DerivedNonReleaseRead {
4458 non_release: NonReleaseQueryData,
4459 a: &'static A,
4460 }
4461
4462 #[derive(QueryData)]
4463 #[query_data(mutable)]
4464 pub struct DerivedNonReleaseMutable {
4465 non_release: NonReleaseQueryData,
4466 a: &'static mut A,
4467 }
4468
4469 #[derive(QueryData)]
4470 pub struct DerivedReleaseRead {
4471 a: &'static A,
4472 }
4473
4474 #[derive(QueryData)]
4475 #[query_data(mutable)]
4476 pub struct DerivedReleaseMutable {
4477 a: &'static mut A,
4478 }
4479
4480 fn assert_is_release_state<Q: ReleaseStateQueryData>() {}
4481
4482 assert_is_release_state::<DerivedReleaseRead>();
4483 assert_is_release_state::<DerivedReleaseMutable>();
4484 }
4485
4486 #[test]
4489 fn read_only_field_visibility() {
4490 mod private {
4491 use super::*;
4492
4493 #[derive(QueryData)]
4494 #[query_data(mutable)]
4495 pub struct D {
4496 pub a: &'static mut A,
4497 }
4498 }
4499
4500 let _ = private::DReadOnly { a: &A };
4501
4502 fn my_system(query: Query<private::D>) {
4503 for q in &query {
4504 let _ = &q.a;
4505 }
4506 }
4507
4508 assert_is_system(my_system);
4509 }
4510
4511 #[test]
4515 fn world_query_metadata_collision() {
4516 #[derive(QueryData)]
4519 pub struct Client<S: ClientState> {
4520 pub state: &'static S,
4521 pub fetch: &'static ClientFetch,
4522 }
4523
4524 pub trait ClientState: Component {}
4525
4526 #[derive(Component)]
4527 pub struct ClientFetch;
4528
4529 #[derive(Component)]
4530 pub struct C;
4531
4532 impl ClientState for C {}
4533
4534 fn client_system(_: Query<Client<C>>) {}
4535
4536 assert_is_system(client_system);
4537 }
4538
4539 #[test]
4543 fn test_entity_ref_query_with_ticks() {
4544 #[derive(Component)]
4545 pub struct C;
4546
4547 fn system(query: Query<EntityRef>) {
4548 for entity_ref in &query {
4549 if let Some(c) = entity_ref.get_ref::<C>()
4550 && !c.is_added()
4551 {
4552 panic!("Expected C to be added");
4553 }
4554 }
4555 }
4556
4557 let mut world = World::new();
4558 let mut schedule = Schedule::default();
4559 schedule.add_systems(system);
4560 world.spawn(C);
4561
4562 world.clear_trackers();
4564
4565 schedule.run(&mut world);
4567 }
4568
4569 #[test]
4570 fn test_contiguous_query_data() {
4571 #[derive(Component, PartialEq, Eq, Debug)]
4572 pub struct C(i32);
4573
4574 #[derive(Component, PartialEq, Eq, Debug)]
4575 pub struct D(bool);
4576
4577 let mut world = World::new();
4578 world.spawn((C(0), D(true)));
4579 world.spawn((C(1), D(false)));
4580 world.spawn(C(2));
4581
4582 let mut query = world.query::<(&C, &D)>();
4583 let mut iter = query.contiguous_iter(&world).unwrap();
4584 let c = iter.next().unwrap();
4585 assert_eq!(c.0, [C(0), C(1)].as_slice());
4586 assert_eq!(c.1, [D(true), D(false)].as_slice());
4587 assert!(iter.next().is_none());
4588
4589 let mut query = world.query::<&C>();
4590 let mut iter = query.contiguous_iter(&world).unwrap();
4591 let mut present = [false; 3];
4592 let mut len = 0;
4593 for _ in 0..2 {
4594 let c = iter.next().unwrap();
4595 for c in c {
4596 present[c.0 as usize] = true;
4597 len += 1;
4598 }
4599 }
4600 assert!(iter.next().is_none());
4601 assert_eq!(len, 3);
4602 assert_eq!(present, [true; 3]);
4603
4604 let mut query = world.query::<&mut C>();
4605 let mut iter = query.contiguous_iter_mut(&mut world).unwrap();
4606 for _ in 0..2 {
4607 let c = iter.next().unwrap();
4608 for c in c {
4609 c.0 *= 2;
4610 }
4611 }
4612 assert!(iter.next().is_none());
4613 let mut iter = query.contiguous_iter(&world).unwrap();
4614 let mut present = [false; 6];
4615 let mut len = 0;
4616 for _ in 0..2 {
4617 let c = iter.next().unwrap();
4618 for c in c {
4619 present[c.0 as usize] = true;
4620 len += 1;
4621 }
4622 }
4623 assert_eq!(present, [true, false, true, false, true, false]);
4624 assert_eq!(len, 3);
4625
4626 let mut query = world.query_filtered::<&C, Without<D>>();
4627 let mut iter = query.contiguous_iter(&world).unwrap();
4628 assert_eq!(iter.next().unwrap(), &[C(4)]);
4629 assert!(iter.next().is_none());
4630 }
4631
4632 #[test]
4633 fn sparse_set_contiguous_query() {
4634 #[derive(Component, Debug, PartialEq, Eq)]
4635 #[component(storage = "SparseSet")]
4636 pub struct S(i32);
4637
4638 let mut world = World::new();
4639 world.spawn(S(0));
4640
4641 let mut query = world.query::<&mut S>();
4642 let iter = query.contiguous_iter_mut(&mut world);
4643 assert!(iter.is_err());
4644 }
4645
4646 #[test]
4647 fn any_of_contiguous_test() {
4648 #[derive(Component, Debug, Clone, Copy)]
4649 pub struct C(i32);
4650
4651 #[derive(Component, Debug, Clone, Copy)]
4652 pub struct D(i32);
4653
4654 let mut world = World::new();
4655 world.spawn((C(0), D(1)));
4656 world.spawn(C(2));
4657 world.spawn(D(3));
4658 world.spawn(());
4659
4660 let mut query = world.query::<AnyOf<(&C, &D)>>();
4661 let iter = query.contiguous_iter(&world).unwrap();
4662 let mut present = [false; 4];
4663
4664 for (c, d) in iter {
4665 assert!(c.is_some() || d.is_some());
4666 let c = c.unwrap_or_default();
4667 let d = d.unwrap_or_default();
4668 for i in 0..c.len().max(d.len()) {
4669 let c = c.get(i).cloned();
4670 let d = d.get(i).cloned();
4671 if let Some(C(c)) = c {
4672 assert!(!present[c as usize]);
4673 present[c as usize] = true;
4674 }
4675 if let Some(D(d)) = d {
4676 assert!(!present[d as usize]);
4677 present[d as usize] = true;
4678 }
4679 }
4680 }
4681
4682 assert_eq!(present, [true; 4]);
4683 }
4684
4685 #[test]
4686 fn option_contiguous_test() {
4687 #[derive(Component, Clone, Copy)]
4688 struct C(i32);
4689
4690 #[derive(Component, Clone, Copy)]
4691 struct D(i32);
4692
4693 let mut world = World::new();
4694 world.spawn((C(0), D(1)));
4695 world.spawn(D(2));
4696 world.spawn(C(3));
4697
4698 let mut query = world.query::<(Option<&C>, &D)>();
4699 let iter = query.contiguous_iter(&world).unwrap();
4700 let mut present = [false; 3];
4701
4702 for (c, d) in iter {
4703 let c = c.unwrap_or_default();
4704 for i in 0..d.len() {
4705 let c = c.get(i).cloned();
4706 let D(d) = d[i];
4707 if let Some(C(c)) = c {
4708 assert!(!present[c as usize]);
4709 present[c as usize] = true;
4710 }
4711 assert!(!present[d as usize]);
4712 present[d as usize] = true;
4713 }
4714 }
4715
4716 assert_eq!(present, [true; 3]);
4717 }
4718
4719 #[test]
4722 fn contiguous_par_iter_basic_test() {
4723 #[derive(Component, PartialEq, Eq, Debug)]
4726 pub struct C {
4727 id: i32,
4728 found: bool,
4729 }
4730
4731 #[derive(Component, PartialEq, Eq, Debug)]
4732 pub struct D(i32);
4733
4734 bevy_tasks::ComputeTaskPool::get_or_init(bevy_tasks::TaskPool::new);
4736
4737 let mut world = World::new();
4739 for id in 0..100 {
4740 world.spawn(C { id, found: false });
4741 }
4742 for id in 100..150 {
4743 world.spawn((C { id, found: false }, D(id)));
4744 }
4745
4746 let total_found = AtomicUsize::new(0);
4749 let mut contiguous_query = world.query::<&mut C>();
4750 contiguous_query
4751 .contiguous_par_iter_mut(&mut world)
4752 .unwrap()
4753 .for_each(|cs| {
4754 for c in cs {
4755 c.found = true;
4756 total_found.fetch_add(1, Ordering::Relaxed);
4757 }
4758 });
4759 assert_eq!(total_found.load(Ordering::Relaxed), 150);
4760
4761 let mut check_query = world.query::<&C>();
4763 assert!(check_query.iter(&world).all(|c| c.found));
4764 }
4765
4766 #[cfg(all(feature = "multi_threaded", feature = "std"))]
4769 #[test]
4770 fn contiguous_par_iter_single_table_scheduling_test() {
4771 #[derive(Clone, Copy, PartialEq, Eq, Debug, Component)]
4773 struct C(i32);
4774
4775 bevy_tasks::ComputeTaskPool::get_or_init(bevy_tasks::TaskPool::new);
4777
4778 let mut world = World::new();
4780 for id in 0..1000 {
4781 world.spawn(C(id));
4782 }
4783
4784 let (total_chunks, total_rows) = (AtomicUsize::new(0), AtomicUsize::new(0));
4789 let mut contiguous_query = world.query::<&mut C>();
4790 contiguous_query
4791 .contiguous_par_iter_mut(&mut world)
4792 .unwrap()
4793 .batching_strategy(BatchingStrategy::fixed(64))
4794 .for_each(|cs| {
4795 total_chunks.fetch_add(1, Ordering::Relaxed);
4796 for c in cs {
4797 c.0 += 1;
4798 total_rows.fetch_add(1, Ordering::Relaxed);
4799 }
4800 });
4801
4802 assert_eq!(total_rows.load(Ordering::Relaxed), 1000);
4804
4805 assert!(total_chunks.load(Ordering::Relaxed) > 1);
4807
4808 let mut query = world.query::<&C>();
4810 let mut all_ids = query.iter(&world).map(|c| c.0).collect::<Vec<_>>();
4811 all_ids.sort_unstable();
4812 assert_eq!(all_ids, (1..1001).collect::<Vec<_>>());
4813 }
4814
4815 #[cfg(all(feature = "multi_threaded", feature = "std"))]
4818 #[test]
4819 fn contiguous_par_iter_multi_table_scheduling_test() {
4820 #[derive(Clone, Copy, PartialEq, Eq, Debug, Component)]
4822 struct CMain(i32);
4823
4824 #[derive(Clone, Copy, PartialEq, Eq, Debug, Component)]
4827 struct CExtra0;
4828 #[derive(Clone, Copy, PartialEq, Eq, Debug, Component)]
4829 struct CExtra1;
4830 #[derive(Clone, Copy, PartialEq, Eq, Debug, Component)]
4831 struct CExtra2;
4832
4833 bevy_tasks::ComputeTaskPool::get_or_init(bevy_tasks::TaskPool::new);
4835
4836 let mut world = World::new();
4842 for id in 0..120 {
4843 world.spawn(CMain(id));
4844 }
4845 for id in 120..125 {
4846 world.spawn((CMain(id), CExtra0));
4847 }
4848 for id in 125..130 {
4849 world.spawn((CMain(id), CExtra1));
4850 }
4851 for id in 130..135 {
4852 world.spawn((CMain(id), CExtra2));
4853 }
4854
4855 let mut contiguous_query = world.query::<&mut CMain>();
4861 let all_jobs = Mutex::new(vec![]);
4862 contiguous_query
4863 .contiguous_par_iter_mut(&mut world)
4864 .unwrap()
4865 .batching_strategy(BatchingStrategy::fixed(50))
4866 .for_each_init(
4867 || {
4868 let job = Arc::new(Mutex::new(FixedBitSet::with_capacity(135)));
4869 all_jobs.lock().unwrap().push(job.clone());
4870 job
4871 },
4872 |job, components| {
4873 let mut job = job.lock().unwrap();
4874 for component in components {
4875 assert!(!job[component.0 as usize]);
4876 job.insert(component.0 as usize);
4877 }
4878 },
4879 );
4880
4881 let all_jobs = all_jobs
4883 .into_inner()
4884 .unwrap()
4885 .into_iter()
4886 .map(|job| Arc::try_unwrap(job).unwrap().into_inner().unwrap())
4887 .collect::<Vec<_>>();
4888
4889 assert!(all_jobs
4891 .iter()
4892 .fold(FixedBitSet::with_capacity(135), |mut acc, item| {
4893 acc.union_with(item);
4894 acc
4895 })
4896 .is_full());
4897
4898 assert_eq!(
4900 all_jobs.iter().map(|job| job.count_ones(..)).sum::<usize>(),
4901 135
4902 );
4903
4904 assert!(all_jobs.iter().all(|job| job.count_ones(..) <= 50));
4906
4907 assert!(
4909 all_jobs
4910 .iter()
4911 .filter(|job| job.contains_any_in_range(0..120))
4912 .count()
4913 >= 2
4914 );
4915
4916 assert!(all_jobs.iter().any(|job| {
4918 let has_main_table = job.contains_any_in_range(0..120);
4919 let has_extra_table_0 = job.contains_any_in_range(120..125);
4920 let has_extra_table_1 = job.contains_any_in_range(125..130);
4921 let has_extra_table_2 = job.contains_any_in_range(130..135);
4922 ((has_main_table as u32)
4923 + (has_extra_table_0 as u32)
4924 + (has_extra_table_1 as u32)
4925 + (has_extra_table_2 as u32))
4926 >= 2
4927 }));
4928 }
4929
4930 #[cfg(all(feature = "multi_threaded", feature = "std"))]
4933 #[test]
4934 fn contiguous_par_iter_table_job_limit_test() {
4935 #[derive(Clone, Copy, PartialEq, Eq, Debug, Component)]
4937 struct CMain(i32);
4938
4939 #[derive(Clone, Copy, PartialEq, Eq, Debug, Component)]
4944 struct CExtra0;
4945 #[derive(Clone, Copy, PartialEq, Eq, Debug, Component)]
4946 struct CExtra1;
4947 #[derive(Clone, Copy, PartialEq, Eq, Debug, Component)]
4948 struct CExtra2;
4949 #[derive(Clone, Copy, PartialEq, Eq, Debug, Component)]
4950 struct CExtra3;
4951 #[derive(Clone, Copy, PartialEq, Eq, Debug, Component)]
4952 struct CExtra4;
4953 #[derive(Clone, Copy, PartialEq, Eq, Debug, Component)]
4954 struct CExtra5;
4955 #[derive(Clone, Copy, PartialEq, Eq, Debug, Component)]
4956 struct CExtra6;
4957 #[derive(Clone, Copy, PartialEq, Eq, Debug, Component)]
4958 struct CExtra7;
4959
4960 bevy_tasks::ComputeTaskPool::get_or_init(bevy_tasks::TaskPool::new);
4962
4963 let mut world = World::new();
4966 for id in 0..256 {
4967 let mut entity = world.spawn(CMain(id));
4968 if id & (1 << 0) != 0 {
4969 entity.insert(CExtra0);
4970 }
4971 if id & (1 << 1) != 0 {
4972 entity.insert(CExtra1);
4973 }
4974 if id & (1 << 2) != 0 {
4975 entity.insert(CExtra2);
4976 }
4977 if id & (1 << 3) != 0 {
4978 entity.insert(CExtra3);
4979 }
4980 if id & (1 << 4) != 0 {
4981 entity.insert(CExtra4);
4982 }
4983 if id & (1 << 5) != 0 {
4984 entity.insert(CExtra5);
4985 }
4986 if id & (1 << 6) != 0 {
4987 entity.insert(CExtra6);
4988 }
4989 if id & (1 << 7) != 0 {
4990 entity.insert(CExtra7);
4991 }
4992 }
4993
4994 let mut contiguous_query = world.query::<&mut CMain>();
4998 let all_jobs = Mutex::new(vec![]);
4999 contiguous_query
5000 .contiguous_par_iter_mut(&mut world)
5001 .unwrap()
5002 .batching_strategy(BatchingStrategy::fixed(1024))
5003 .for_each_init(
5004 || {
5005 let job = Arc::new(Mutex::new(FixedBitSet::with_capacity(256)));
5006 all_jobs.lock().unwrap().push(job.clone());
5007 job
5008 },
5009 |job, components| {
5010 let mut job = job.lock().unwrap();
5011 for component in components {
5012 assert!(!job[component.0 as usize]);
5013 job.insert(component.0 as usize);
5014 }
5015 },
5016 );
5017
5018 let all_jobs = all_jobs
5020 .into_inner()
5021 .unwrap()
5022 .into_iter()
5023 .map(|job| Arc::try_unwrap(job).unwrap().into_inner().unwrap())
5024 .collect::<Vec<_>>();
5025
5026 assert!(all_jobs
5028 .iter()
5029 .fold(FixedBitSet::with_capacity(256), |mut acc, item| {
5030 acc.union_with(item);
5031 acc
5032 })
5033 .is_full());
5034
5035 assert_eq!(
5037 all_jobs.iter().map(|job| job.count_ones(..)).sum::<usize>(),
5038 256
5039 );
5040
5041 assert!(all_jobs.len() >= 2);
5043 }
5044
5045 #[cfg(all(feature = "multi_threaded", feature = "std"))]
5048 #[test]
5049 fn contiguous_par_iter_failure_test() {
5050 #[derive(Component, Clone, Copy)]
5053 struct C;
5054
5055 #[derive(Component, Clone, Copy)]
5056 #[component(storage = "SparseSet")]
5057 struct S;
5058
5059 bevy_tasks::ComputeTaskPool::get_or_init(bevy_tasks::TaskPool::new);
5061
5062 let mut world = World::new();
5064 for _ in 0..100 {
5065 world.spawn((C, S));
5066 }
5067
5068 let mut sparse_query = world.query::<(&C, &S)>();
5070 assert!(matches!(
5071 sparse_query.contiguous_par_iter(&world),
5072 Err(QueryNotDenseError(_))
5073 ));
5074 }
5075}