1use crate::{
2 archetype::{Archetype, Archetypes},
3 bundle::Bundle,
4 change_detection::{MaybeLocation, Ticks, TicksMut},
5 component::{Component, ComponentId, Components, Mutable, StorageType, Tick},
6 entity::{Entities, Entity, EntityLocation},
7 query::{Access, DebugCheckedUnwrap, FilteredAccess, WorldQuery},
8 storage::{ComponentSparseSet, Table, TableRow},
9 world::{
10 unsafe_world_cell::UnsafeWorldCell, EntityMut, EntityMutExcept, EntityRef, EntityRefExcept,
11 FilteredEntityMut, FilteredEntityRef, Mut, Ref, World,
12 },
13};
14use bevy_ptr::{ThinSlicePtr, UnsafeCellDeref};
15use bevy_utils::prelude::DebugName;
16use core::{cell::UnsafeCell, marker::PhantomData, panic::Location};
17use variadics_please::all_tuples;
18
19#[diagnostic::on_unimplemented(
279 message = "`{Self}` is not valid to request as data in a `Query`",
280 label = "invalid `Query` data",
281 note = "if `{Self}` is a component type, try using `&{Self}` or `&mut {Self}`"
282)]
283pub unsafe trait QueryData: WorldQuery {
284 const IS_READ_ONLY: bool;
286
287 type ReadOnly: ReadOnlyQueryData<State = <Self as WorldQuery>::State>;
289
290 type Item<'w, 's>;
294
295 fn shrink<'wlong: 'wshort, 'wshort, 's>(
297 item: Self::Item<'wlong, 's>,
298 ) -> Self::Item<'wshort, 's>;
299
300 fn provide_extra_access(
310 _state: &mut Self::State,
311 _access: &mut Access,
312 _available_access: &Access,
313 ) {
314 }
315
316 unsafe fn fetch<'w, 's>(
328 state: &'s Self::State,
329 fetch: &mut Self::Fetch<'w>,
330 entity: Entity,
331 table_row: TableRow,
332 ) -> Self::Item<'w, 's>;
333}
334
335pub unsafe trait ReadOnlyQueryData: QueryData<ReadOnly = Self> {}
341
342pub type QueryItem<'w, 's, Q> = <Q as QueryData>::Item<'w, 's>;
344pub type ROQueryItem<'w, 's, D> = QueryItem<'w, 's, <D as QueryData>::ReadOnly>;
346
347pub trait ReleaseStateQueryData: QueryData {
354 fn release_state<'w>(item: Self::Item<'w, '_>) -> Self::Item<'w, 'static>;
356}
357
358unsafe impl WorldQuery for Entity {
362 type Fetch<'w> = ();
363 type State = ();
364
365 fn shrink_fetch<'wlong: 'wshort, 'wshort>(_: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {}
366
367 unsafe fn init_fetch<'w, 's>(
368 _world: UnsafeWorldCell<'w>,
369 _state: &'s Self::State,
370 _last_run: Tick,
371 _this_run: Tick,
372 ) -> Self::Fetch<'w> {
373 }
374
375 const IS_DENSE: bool = true;
376
377 #[inline]
378 unsafe fn set_archetype<'w, 's>(
379 _fetch: &mut Self::Fetch<'w>,
380 _state: &'s Self::State,
381 _archetype: &'w Archetype,
382 _table: &Table,
383 ) {
384 }
385
386 #[inline]
387 unsafe fn set_table<'w, 's>(
388 _fetch: &mut Self::Fetch<'w>,
389 _state: &'s Self::State,
390 _table: &'w Table,
391 ) {
392 }
393
394 fn update_component_access(_state: &Self::State, _access: &mut FilteredAccess) {}
395
396 fn init_state(_world: &mut World) {}
397
398 fn get_state(_components: &Components) -> Option<()> {
399 Some(())
400 }
401
402 fn matches_component_set(
403 _state: &Self::State,
404 _set_contains_id: &impl Fn(ComponentId) -> bool,
405 ) -> bool {
406 true
407 }
408}
409
410unsafe impl QueryData for Entity {
412 const IS_READ_ONLY: bool = true;
413 type ReadOnly = Self;
414
415 type Item<'w, 's> = Entity;
416
417 fn shrink<'wlong: 'wshort, 'wshort, 's>(
418 item: Self::Item<'wlong, 's>,
419 ) -> Self::Item<'wshort, 's> {
420 item
421 }
422
423 #[inline(always)]
424 unsafe fn fetch<'w, 's>(
425 _state: &'s Self::State,
426 _fetch: &mut Self::Fetch<'w>,
427 entity: Entity,
428 _table_row: TableRow,
429 ) -> Self::Item<'w, 's> {
430 entity
431 }
432}
433
434unsafe impl ReadOnlyQueryData for Entity {}
436
437impl ReleaseStateQueryData for Entity {
438 fn release_state<'w>(item: Self::Item<'w, '_>) -> Self::Item<'w, 'static> {
439 item
440 }
441}
442
443unsafe impl WorldQuery for EntityLocation {
447 type Fetch<'w> = &'w Entities;
448 type State = ();
449
450 fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
451 fetch
452 }
453
454 unsafe fn init_fetch<'w, 's>(
455 world: UnsafeWorldCell<'w>,
456 _state: &'s Self::State,
457 _last_run: Tick,
458 _this_run: Tick,
459 ) -> Self::Fetch<'w> {
460 world.entities()
461 }
462
463 const IS_DENSE: bool = true;
466
467 #[inline]
468 unsafe fn set_archetype<'w, 's>(
469 _fetch: &mut Self::Fetch<'w>,
470 _state: &'s Self::State,
471 _archetype: &'w Archetype,
472 _table: &Table,
473 ) {
474 }
475
476 #[inline]
477 unsafe fn set_table<'w, 's>(
478 _fetch: &mut Self::Fetch<'w>,
479 _state: &'s Self::State,
480 _table: &'w Table,
481 ) {
482 }
483
484 fn update_component_access(_state: &Self::State, _access: &mut FilteredAccess) {}
485
486 fn init_state(_world: &mut World) {}
487
488 fn get_state(_components: &Components) -> Option<()> {
489 Some(())
490 }
491
492 fn matches_component_set(
493 _state: &Self::State,
494 _set_contains_id: &impl Fn(ComponentId) -> bool,
495 ) -> bool {
496 true
497 }
498}
499
500unsafe impl QueryData for EntityLocation {
502 const IS_READ_ONLY: bool = true;
503 type ReadOnly = Self;
504 type Item<'w, 's> = EntityLocation;
505
506 fn shrink<'wlong: 'wshort, 'wshort, 's>(
507 item: Self::Item<'wlong, 's>,
508 ) -> Self::Item<'wshort, 's> {
509 item
510 }
511
512 #[inline(always)]
513 unsafe fn fetch<'w, 's>(
514 _state: &'s Self::State,
515 fetch: &mut Self::Fetch<'w>,
516 entity: Entity,
517 _table_row: TableRow,
518 ) -> Self::Item<'w, 's> {
519 unsafe { fetch.get(entity).debug_checked_unwrap() }
521 }
522}
523
524unsafe impl ReadOnlyQueryData for EntityLocation {}
526
527impl ReleaseStateQueryData for EntityLocation {
528 fn release_state<'w>(item: Self::Item<'w, '_>) -> Self::Item<'w, 'static> {
529 item
530 }
531}
532
533#[derive(Clone, Copy, Debug)]
570pub struct SpawnDetails {
571 spawned_by: MaybeLocation,
572 spawn_tick: Tick,
573 last_run: Tick,
574 this_run: Tick,
575}
576
577impl SpawnDetails {
578 pub fn is_spawned(self) -> bool {
581 self.spawn_tick.is_newer_than(self.last_run, self.this_run)
582 }
583
584 pub fn spawn_tick(self) -> Tick {
586 self.spawn_tick
587 }
588
589 pub fn spawned_by(self) -> MaybeLocation {
591 self.spawned_by
592 }
593}
594
595#[doc(hidden)]
596#[derive(Clone)]
597pub struct SpawnDetailsFetch<'w> {
598 entities: &'w Entities,
599 last_run: Tick,
600 this_run: Tick,
601}
602
603unsafe impl WorldQuery for SpawnDetails {
606 type Fetch<'w> = SpawnDetailsFetch<'w>;
607 type State = ();
608
609 fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
610 fetch
611 }
612
613 unsafe fn init_fetch<'w, 's>(
614 world: UnsafeWorldCell<'w>,
615 _state: &'s Self::State,
616 last_run: Tick,
617 this_run: Tick,
618 ) -> Self::Fetch<'w> {
619 SpawnDetailsFetch {
620 entities: world.entities(),
621 last_run,
622 this_run,
623 }
624 }
625
626 const IS_DENSE: bool = true;
627
628 #[inline]
629 unsafe fn set_archetype<'w, 's>(
630 _fetch: &mut Self::Fetch<'w>,
631 _state: &'s Self::State,
632 _archetype: &'w Archetype,
633 _table: &'w Table,
634 ) {
635 }
636
637 #[inline]
638 unsafe fn set_table<'w, 's>(
639 _fetch: &mut Self::Fetch<'w>,
640 _state: &'s Self::State,
641 _table: &'w Table,
642 ) {
643 }
644
645 fn update_component_access(_state: &Self::State, _access: &mut FilteredAccess) {}
646
647 fn init_state(_world: &mut World) {}
648
649 fn get_state(_components: &Components) -> Option<()> {
650 Some(())
651 }
652
653 fn matches_component_set(
654 _state: &Self::State,
655 _set_contains_id: &impl Fn(ComponentId) -> bool,
656 ) -> bool {
657 true
658 }
659}
660
661unsafe impl QueryData for SpawnDetails {
665 const IS_READ_ONLY: bool = true;
666 type ReadOnly = Self;
667 type Item<'w, 's> = Self;
668
669 fn shrink<'wlong: 'wshort, 'wshort, 's>(
670 item: Self::Item<'wlong, 's>,
671 ) -> Self::Item<'wshort, 's> {
672 item
673 }
674
675 #[inline(always)]
676 unsafe fn fetch<'w, 's>(
677 _state: &'s Self::State,
678 fetch: &mut Self::Fetch<'w>,
679 entity: Entity,
680 _table_row: TableRow,
681 ) -> Self::Item<'w, 's> {
682 let (spawned_by, spawn_tick) = unsafe {
684 fetch
685 .entities
686 .entity_get_spawned_or_despawned_unchecked(entity)
687 };
688 Self {
689 spawned_by,
690 spawn_tick,
691 last_run: fetch.last_run,
692 this_run: fetch.this_run,
693 }
694 }
695}
696
697unsafe impl ReadOnlyQueryData for SpawnDetails {}
699
700impl ReleaseStateQueryData for SpawnDetails {
701 fn release_state<'w>(item: Self::Item<'w, '_>) -> Self::Item<'w, 'static> {
702 item
703 }
704}
705
706#[derive(Copy, Clone)]
709#[doc(hidden)]
710pub struct EntityFetch<'w> {
711 world: UnsafeWorldCell<'w>,
712 last_run: Tick,
713 this_run: Tick,
714}
715
716unsafe impl<'a> WorldQuery for EntityRef<'a> {
721 type Fetch<'w> = EntityFetch<'w>;
722 type State = ();
723
724 fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
725 fetch
726 }
727
728 unsafe fn init_fetch<'w, 's>(
729 world: UnsafeWorldCell<'w>,
730 _state: &'s Self::State,
731 last_run: Tick,
732 this_run: Tick,
733 ) -> Self::Fetch<'w> {
734 EntityFetch {
735 world,
736 last_run,
737 this_run,
738 }
739 }
740
741 const IS_DENSE: bool = true;
742
743 #[inline]
744 unsafe fn set_archetype<'w, 's>(
745 _fetch: &mut Self::Fetch<'w>,
746 _state: &'s Self::State,
747 _archetype: &'w Archetype,
748 _table: &Table,
749 ) {
750 }
751
752 #[inline]
753 unsafe fn set_table<'w, 's>(
754 _fetch: &mut Self::Fetch<'w>,
755 _state: &'s Self::State,
756 _table: &'w Table,
757 ) {
758 }
759
760 fn update_component_access(_state: &Self::State, access: &mut FilteredAccess) {
761 assert!(
762 !access.access().has_any_component_write(),
763 "EntityRef conflicts with a previous access in this query. Shared access cannot coincide with exclusive access.",
764 );
765 access.read_all_components();
766 }
767
768 fn init_state(_world: &mut World) {}
769
770 fn get_state(_components: &Components) -> Option<()> {
771 Some(())
772 }
773
774 fn matches_component_set(
775 _state: &Self::State,
776 _set_contains_id: &impl Fn(ComponentId) -> bool,
777 ) -> bool {
778 true
779 }
780}
781
782unsafe impl<'a> QueryData for EntityRef<'a> {
784 const IS_READ_ONLY: bool = true;
785 type ReadOnly = Self;
786 type Item<'w, 's> = EntityRef<'w>;
787
788 fn shrink<'wlong: 'wshort, 'wshort, 's>(
789 item: Self::Item<'wlong, 's>,
790 ) -> Self::Item<'wshort, 's> {
791 item
792 }
793
794 #[inline(always)]
795 unsafe fn fetch<'w, 's>(
796 _state: &'s Self::State,
797 fetch: &mut Self::Fetch<'w>,
798 entity: Entity,
799 _table_row: TableRow,
800 ) -> Self::Item<'w, 's> {
801 let cell = unsafe {
803 fetch
804 .world
805 .get_entity_with_ticks(entity, fetch.last_run, fetch.this_run)
806 .debug_checked_unwrap()
807 };
808 unsafe { EntityRef::new(cell) }
810 }
811}
812
813unsafe impl ReadOnlyQueryData for EntityRef<'_> {}
815
816impl ReleaseStateQueryData for EntityRef<'_> {
817 fn release_state<'w>(item: Self::Item<'w, '_>) -> Self::Item<'w, 'static> {
818 item
819 }
820}
821
822unsafe impl<'a> WorldQuery for EntityMut<'a> {
824 type Fetch<'w> = EntityFetch<'w>;
825 type State = ();
826
827 fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
828 fetch
829 }
830
831 unsafe fn init_fetch<'w, 's>(
832 world: UnsafeWorldCell<'w>,
833 _state: &'s Self::State,
834 last_run: Tick,
835 this_run: Tick,
836 ) -> Self::Fetch<'w> {
837 EntityFetch {
838 world,
839 last_run,
840 this_run,
841 }
842 }
843
844 const IS_DENSE: bool = true;
845
846 #[inline]
847 unsafe fn set_archetype<'w, 's>(
848 _fetch: &mut Self::Fetch<'w>,
849 _state: &'s Self::State,
850 _archetype: &'w Archetype,
851 _table: &Table,
852 ) {
853 }
854
855 #[inline]
856 unsafe fn set_table<'w, 's>(
857 _fetch: &mut Self::Fetch<'w>,
858 _state: &'s Self::State,
859 _table: &'w Table,
860 ) {
861 }
862
863 fn update_component_access(_state: &Self::State, access: &mut FilteredAccess) {
864 assert!(
865 !access.access().has_any_component_read(),
866 "EntityMut conflicts with a previous access in this query. Exclusive access cannot coincide with any other accesses.",
867 );
868 access.write_all_components();
869 }
870
871 fn init_state(_world: &mut World) {}
872
873 fn get_state(_components: &Components) -> Option<()> {
874 Some(())
875 }
876
877 fn matches_component_set(
878 _state: &Self::State,
879 _set_contains_id: &impl Fn(ComponentId) -> bool,
880 ) -> bool {
881 true
882 }
883}
884
885unsafe impl<'a> QueryData for EntityMut<'a> {
887 const IS_READ_ONLY: bool = false;
888 type ReadOnly = EntityRef<'a>;
889 type Item<'w, 's> = EntityMut<'w>;
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 ) -> Self::Item<'w, 's> {
904 let cell = unsafe {
906 fetch
907 .world
908 .get_entity_with_ticks(entity, fetch.last_run, fetch.this_run)
909 .debug_checked_unwrap()
910 };
911 unsafe { EntityMut::new(cell) }
913 }
914}
915
916impl ReleaseStateQueryData for EntityMut<'_> {
917 fn release_state<'w>(item: Self::Item<'w, '_>) -> Self::Item<'w, 'static> {
918 item
919 }
920}
921
922unsafe impl WorldQuery for FilteredEntityRef<'_, '_> {
924 type Fetch<'w> = EntityFetch<'w>;
925 type State = Access;
926
927 fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
928 fetch
929 }
930
931 const IS_DENSE: bool = false;
932
933 unsafe fn init_fetch<'w, 's>(
934 world: UnsafeWorldCell<'w>,
935 _state: &'s Self::State,
936 last_run: Tick,
937 this_run: Tick,
938 ) -> Self::Fetch<'w> {
939 EntityFetch {
940 world,
941 last_run,
942 this_run,
943 }
944 }
945
946 #[inline]
947 unsafe fn set_archetype<'w, 's>(
948 _fetch: &mut Self::Fetch<'w>,
949 _state: &'s Self::State,
950 _: &'w Archetype,
951 _table: &Table,
952 ) {
953 }
954
955 #[inline]
956 unsafe fn set_table<'w, 's>(
957 _fetch: &mut Self::Fetch<'w>,
958 _state: &'s Self::State,
959 _: &'w Table,
960 ) {
961 }
962
963 fn update_component_access(state: &Self::State, filtered_access: &mut FilteredAccess) {
964 assert!(
965 filtered_access.access().is_compatible(state),
966 "FilteredEntityRef conflicts with a previous access in this query. Exclusive access cannot coincide with any other accesses.",
967 );
968 filtered_access.access.extend(state);
969 }
970
971 fn init_state(_world: &mut World) -> Self::State {
972 Access::default()
973 }
974
975 fn get_state(_components: &Components) -> Option<Self::State> {
976 Some(Access::default())
977 }
978
979 fn matches_component_set(
980 _state: &Self::State,
981 _set_contains_id: &impl Fn(ComponentId) -> bool,
982 ) -> bool {
983 true
984 }
985}
986
987unsafe impl QueryData for FilteredEntityRef<'_, '_> {
989 const IS_READ_ONLY: bool = true;
990 type ReadOnly = Self;
991 type Item<'w, 's> = FilteredEntityRef<'w, 's>;
992
993 fn shrink<'wlong: 'wshort, 'wshort, 's>(
994 item: Self::Item<'wlong, 's>,
995 ) -> Self::Item<'wshort, 's> {
996 item
997 }
998
999 #[inline]
1000 fn provide_extra_access(
1001 state: &mut Self::State,
1002 access: &mut Access,
1003 available_access: &Access,
1004 ) {
1005 state.clone_from(available_access);
1009 state.clear_writes();
1011 state.remove_conflicting_access(access);
1013 access.extend(state);
1016 }
1017
1018 #[inline(always)]
1019 unsafe fn fetch<'w, 's>(
1020 access: &'s Self::State,
1021 fetch: &mut Self::Fetch<'w>,
1022 entity: Entity,
1023 _table_row: TableRow,
1024 ) -> Self::Item<'w, 's> {
1025 let cell = unsafe {
1027 fetch
1028 .world
1029 .get_entity_with_ticks(entity, fetch.last_run, fetch.this_run)
1030 .debug_checked_unwrap()
1031 };
1032 unsafe { FilteredEntityRef::new(cell, access) }
1034 }
1035}
1036
1037unsafe impl ReadOnlyQueryData for FilteredEntityRef<'_, '_> {}
1039
1040unsafe impl WorldQuery for FilteredEntityMut<'_, '_> {
1042 type Fetch<'w> = EntityFetch<'w>;
1043 type State = Access;
1044
1045 fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
1046 fetch
1047 }
1048
1049 const IS_DENSE: bool = false;
1050
1051 unsafe fn init_fetch<'w, 's>(
1052 world: UnsafeWorldCell<'w>,
1053 _state: &'s Self::State,
1054 last_run: Tick,
1055 this_run: Tick,
1056 ) -> Self::Fetch<'w> {
1057 EntityFetch {
1058 world,
1059 last_run,
1060 this_run,
1061 }
1062 }
1063
1064 #[inline]
1065 unsafe fn set_archetype<'w, 's>(
1066 _fetch: &mut Self::Fetch<'w>,
1067 _state: &'s Self::State,
1068 _: &'w Archetype,
1069 _table: &Table,
1070 ) {
1071 }
1072
1073 #[inline]
1074 unsafe fn set_table<'w, 's>(
1075 _fetch: &mut Self::Fetch<'w>,
1076 _state: &'s Self::State,
1077 _: &'w Table,
1078 ) {
1079 }
1080
1081 fn update_component_access(state: &Self::State, filtered_access: &mut FilteredAccess) {
1082 assert!(
1083 filtered_access.access().is_compatible(state),
1084 "FilteredEntityMut conflicts with a previous access in this query. Exclusive access cannot coincide with any other accesses.",
1085 );
1086 filtered_access.access.extend(state);
1087 }
1088
1089 fn init_state(_world: &mut World) -> Self::State {
1090 Access::default()
1091 }
1092
1093 fn get_state(_components: &Components) -> Option<Self::State> {
1094 Some(Access::default())
1095 }
1096
1097 fn matches_component_set(
1098 _state: &Self::State,
1099 _set_contains_id: &impl Fn(ComponentId) -> bool,
1100 ) -> bool {
1101 true
1102 }
1103}
1104
1105unsafe impl<'a, 'b> QueryData for FilteredEntityMut<'a, 'b> {
1107 const IS_READ_ONLY: bool = false;
1108 type ReadOnly = FilteredEntityRef<'a, 'b>;
1109 type Item<'w, 's> = FilteredEntityMut<'w, 's>;
1110
1111 fn shrink<'wlong: 'wshort, 'wshort, 's>(
1112 item: Self::Item<'wlong, 's>,
1113 ) -> Self::Item<'wshort, 's> {
1114 item
1115 }
1116
1117 #[inline]
1118 fn provide_extra_access(
1119 state: &mut Self::State,
1120 access: &mut Access,
1121 available_access: &Access,
1122 ) {
1123 state.clone_from(available_access);
1127 state.remove_conflicting_access(access);
1129 access.extend(state);
1132 }
1133
1134 #[inline(always)]
1135 unsafe fn fetch<'w, 's>(
1136 access: &'s Self::State,
1137 fetch: &mut Self::Fetch<'w>,
1138 entity: Entity,
1139 _table_row: TableRow,
1140 ) -> Self::Item<'w, 's> {
1141 let cell = unsafe {
1143 fetch
1144 .world
1145 .get_entity_with_ticks(entity, fetch.last_run, fetch.this_run)
1146 .debug_checked_unwrap()
1147 };
1148 unsafe { FilteredEntityMut::new(cell, access) }
1150 }
1151}
1152
1153unsafe impl<'a, 'b, B> WorldQuery for EntityRefExcept<'a, 'b, B>
1157where
1158 B: Bundle,
1159{
1160 type Fetch<'w> = EntityFetch<'w>;
1161 type State = Access;
1162
1163 fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
1164 fetch
1165 }
1166
1167 unsafe fn init_fetch<'w, 's>(
1168 world: UnsafeWorldCell<'w>,
1169 _: &'s Self::State,
1170 last_run: Tick,
1171 this_run: Tick,
1172 ) -> Self::Fetch<'w> {
1173 EntityFetch {
1174 world,
1175 last_run,
1176 this_run,
1177 }
1178 }
1179
1180 const IS_DENSE: bool = true;
1181
1182 unsafe fn set_archetype<'w, 's>(
1183 _: &mut Self::Fetch<'w>,
1184 _: &'s Self::State,
1185 _: &'w Archetype,
1186 _: &'w Table,
1187 ) {
1188 }
1189
1190 unsafe fn set_table<'w, 's>(_: &mut Self::Fetch<'w>, _: &'s Self::State, _: &'w Table) {}
1191
1192 fn update_component_access(state: &Self::State, filtered_access: &mut FilteredAccess) {
1193 let access = filtered_access.access_mut();
1194 assert!(
1195 access.is_compatible(state),
1196 "`EntityRefExcept<{}>` conflicts with a previous access in this query.",
1197 DebugName::type_name::<B>(),
1198 );
1199 access.extend(state);
1200 }
1201
1202 fn init_state(world: &mut World) -> Self::State {
1203 let mut access = Access::new();
1204 access.read_all_components();
1205 B::component_ids(&mut world.components_registrator(), &mut |id| {
1206 access.remove_component_read(id);
1207 });
1208 access
1209 }
1210
1211 fn get_state(components: &Components) -> Option<Self::State> {
1212 let mut access = Access::new();
1213 access.read_all_components();
1214 B::get_component_ids(components, &mut |maybe_id| {
1215 if let Some(id) = maybe_id {
1222 access.remove_component_read(id);
1223 }
1224 });
1225 Some(access)
1226 }
1227
1228 fn matches_component_set(_: &Self::State, _: &impl Fn(ComponentId) -> bool) -> bool {
1229 true
1230 }
1231}
1232
1233unsafe impl<'a, 'b, B> QueryData for EntityRefExcept<'a, 'b, B>
1235where
1236 B: Bundle,
1237{
1238 const IS_READ_ONLY: bool = true;
1239 type ReadOnly = Self;
1240 type Item<'w, 's> = EntityRefExcept<'w, 's, B>;
1241
1242 fn shrink<'wlong: 'wshort, 'wshort, 's>(
1243 item: Self::Item<'wlong, 's>,
1244 ) -> Self::Item<'wshort, 's> {
1245 item
1246 }
1247
1248 unsafe fn fetch<'w, 's>(
1249 access: &'s Self::State,
1250 fetch: &mut Self::Fetch<'w>,
1251 entity: Entity,
1252 _: TableRow,
1253 ) -> Self::Item<'w, 's> {
1254 let cell = fetch
1255 .world
1256 .get_entity_with_ticks(entity, fetch.last_run, fetch.this_run)
1257 .unwrap();
1258 EntityRefExcept::new(cell, access)
1259 }
1260}
1261
1262unsafe impl<B> ReadOnlyQueryData for EntityRefExcept<'_, '_, B> where B: Bundle {}
1265
1266unsafe impl<'a, 'b, B> WorldQuery for EntityMutExcept<'a, 'b, B>
1270where
1271 B: Bundle,
1272{
1273 type Fetch<'w> = EntityFetch<'w>;
1274 type State = Access;
1275
1276 fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
1277 fetch
1278 }
1279
1280 unsafe fn init_fetch<'w, 's>(
1281 world: UnsafeWorldCell<'w>,
1282 _: &'s Self::State,
1283 last_run: Tick,
1284 this_run: Tick,
1285 ) -> Self::Fetch<'w> {
1286 EntityFetch {
1287 world,
1288 last_run,
1289 this_run,
1290 }
1291 }
1292
1293 const IS_DENSE: bool = true;
1294
1295 unsafe fn set_archetype<'w, 's>(
1296 _: &mut Self::Fetch<'w>,
1297 _: &'s Self::State,
1298 _: &'w Archetype,
1299 _: &'w Table,
1300 ) {
1301 }
1302
1303 unsafe fn set_table<'w, 's>(_: &mut Self::Fetch<'w>, _: &'s Self::State, _: &'w Table) {}
1304
1305 fn update_component_access(state: &Self::State, filtered_access: &mut FilteredAccess) {
1306 let access = filtered_access.access_mut();
1307 assert!(
1308 access.is_compatible(state),
1309 "`EntityMutExcept<{}>` conflicts with a previous access in this query.",
1310 DebugName::type_name::<B>()
1311 );
1312 access.extend(state);
1313 }
1314
1315 fn init_state(world: &mut World) -> Self::State {
1316 let mut access = Access::new();
1317 access.write_all_components();
1318 B::component_ids(&mut world.components_registrator(), &mut |id| {
1319 access.remove_component_read(id);
1320 });
1321 access
1322 }
1323
1324 fn get_state(components: &Components) -> Option<Self::State> {
1325 let mut access = Access::new();
1326 access.write_all_components();
1327 B::get_component_ids(components, &mut |maybe_id| {
1328 if let Some(id) = maybe_id {
1335 access.remove_component_read(id);
1336 }
1337 });
1338 Some(access)
1339 }
1340
1341 fn matches_component_set(_: &Self::State, _: &impl Fn(ComponentId) -> bool) -> bool {
1342 true
1343 }
1344}
1345
1346unsafe impl<'a, 'b, B> QueryData for EntityMutExcept<'a, 'b, B>
1349where
1350 B: Bundle,
1351{
1352 const IS_READ_ONLY: bool = false;
1353 type ReadOnly = EntityRefExcept<'a, 'b, B>;
1354 type Item<'w, 's> = EntityMutExcept<'w, 's, B>;
1355
1356 fn shrink<'wlong: 'wshort, 'wshort, 's>(
1357 item: Self::Item<'wlong, 's>,
1358 ) -> Self::Item<'wshort, 's> {
1359 item
1360 }
1361
1362 unsafe fn fetch<'w, 's>(
1363 access: &'s Self::State,
1364 fetch: &mut Self::Fetch<'w>,
1365 entity: Entity,
1366 _: TableRow,
1367 ) -> Self::Item<'w, 's> {
1368 let cell = fetch
1369 .world
1370 .get_entity_with_ticks(entity, fetch.last_run, fetch.this_run)
1371 .unwrap();
1372 EntityMutExcept::new(cell, access)
1373 }
1374}
1375
1376unsafe impl WorldQuery for &Archetype {
1380 type Fetch<'w> = (&'w Entities, &'w Archetypes);
1381 type State = ();
1382
1383 fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
1384 fetch
1385 }
1386
1387 unsafe fn init_fetch<'w, 's>(
1388 world: UnsafeWorldCell<'w>,
1389 _state: &'s Self::State,
1390 _last_run: Tick,
1391 _this_run: Tick,
1392 ) -> Self::Fetch<'w> {
1393 (world.entities(), world.archetypes())
1394 }
1395
1396 const IS_DENSE: bool = true;
1399
1400 #[inline]
1401 unsafe fn set_archetype<'w, 's>(
1402 _fetch: &mut Self::Fetch<'w>,
1403 _state: &'s Self::State,
1404 _archetype: &'w Archetype,
1405 _table: &Table,
1406 ) {
1407 }
1408
1409 #[inline]
1410 unsafe fn set_table<'w, 's>(
1411 _fetch: &mut Self::Fetch<'w>,
1412 _state: &'s Self::State,
1413 _table: &'w Table,
1414 ) {
1415 }
1416
1417 fn update_component_access(_state: &Self::State, _access: &mut FilteredAccess) {}
1418
1419 fn init_state(_world: &mut World) {}
1420
1421 fn get_state(_components: &Components) -> Option<()> {
1422 Some(())
1423 }
1424
1425 fn matches_component_set(
1426 _state: &Self::State,
1427 _set_contains_id: &impl Fn(ComponentId) -> bool,
1428 ) -> bool {
1429 true
1430 }
1431}
1432
1433unsafe impl QueryData for &Archetype {
1435 const IS_READ_ONLY: bool = true;
1436 type ReadOnly = Self;
1437 type Item<'w, 's> = &'w Archetype;
1438
1439 fn shrink<'wlong: 'wshort, 'wshort, 's>(
1440 item: Self::Item<'wlong, 's>,
1441 ) -> Self::Item<'wshort, 's> {
1442 item
1443 }
1444
1445 #[inline(always)]
1446 unsafe fn fetch<'w, 's>(
1447 _state: &'s Self::State,
1448 fetch: &mut Self::Fetch<'w>,
1449 entity: Entity,
1450 _table_row: TableRow,
1451 ) -> Self::Item<'w, 's> {
1452 let (entities, archetypes) = *fetch;
1453 let location = unsafe { entities.get(entity).debug_checked_unwrap() };
1455 unsafe { archetypes.get(location.archetype_id).debug_checked_unwrap() }
1457 }
1458}
1459
1460unsafe impl ReadOnlyQueryData for &Archetype {}
1462
1463impl ReleaseStateQueryData for &Archetype {
1464 fn release_state<'w>(item: Self::Item<'w, '_>) -> Self::Item<'w, 'static> {
1465 item
1466 }
1467}
1468
1469pub struct ReadFetch<'w, T: Component> {
1471 components: StorageSwitch<
1472 T,
1473 Option<ThinSlicePtr<'w, UnsafeCell<T>>>,
1475 Option<&'w ComponentSparseSet>,
1477 >,
1478}
1479
1480impl<T: Component> Clone for ReadFetch<'_, T> {
1481 fn clone(&self) -> Self {
1482 *self
1483 }
1484}
1485
1486impl<T: Component> Copy for ReadFetch<'_, T> {}
1487
1488unsafe impl<T: Component> WorldQuery for &T {
1494 type Fetch<'w> = ReadFetch<'w, T>;
1495 type State = ComponentId;
1496
1497 fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
1498 fetch
1499 }
1500
1501 #[inline]
1502 unsafe fn init_fetch<'w, 's>(
1503 world: UnsafeWorldCell<'w>,
1504 &component_id: &ComponentId,
1505 _last_run: Tick,
1506 _this_run: Tick,
1507 ) -> ReadFetch<'w, T> {
1508 ReadFetch {
1509 components: StorageSwitch::new(
1510 || None,
1511 || {
1512 unsafe { world.storages().sparse_sets.get(component_id) }
1517 },
1518 ),
1519 }
1520 }
1521
1522 const IS_DENSE: bool = {
1523 match T::STORAGE_TYPE {
1524 StorageType::Table => true,
1525 StorageType::SparseSet => false,
1526 }
1527 };
1528
1529 #[inline]
1530 unsafe fn set_archetype<'w>(
1531 fetch: &mut ReadFetch<'w, T>,
1532 component_id: &ComponentId,
1533 _archetype: &'w Archetype,
1534 table: &'w Table,
1535 ) {
1536 if Self::IS_DENSE {
1537 unsafe {
1539 Self::set_table(fetch, component_id, table);
1540 }
1541 }
1542 }
1543
1544 #[inline]
1545 unsafe fn set_table<'w>(
1546 fetch: &mut ReadFetch<'w, T>,
1547 &component_id: &ComponentId,
1548 table: &'w Table,
1549 ) {
1550 let table_data = Some(
1551 table
1552 .get_data_slice_for(component_id)
1553 .debug_checked_unwrap()
1554 .into(),
1555 );
1556 unsafe { fetch.components.set_table(table_data) };
1558 }
1559
1560 fn update_component_access(&component_id: &ComponentId, access: &mut FilteredAccess) {
1561 assert!(
1562 !access.access().has_component_write(component_id),
1563 "&{} conflicts with a previous access in this query. Shared access cannot coincide with exclusive access.",
1564 DebugName::type_name::<T>(),
1565 );
1566 access.add_component_read(component_id);
1567 }
1568
1569 fn init_state(world: &mut World) -> ComponentId {
1570 world.register_component::<T>()
1571 }
1572
1573 fn get_state(components: &Components) -> Option<Self::State> {
1574 components.component_id::<T>()
1575 }
1576
1577 fn matches_component_set(
1578 &state: &ComponentId,
1579 set_contains_id: &impl Fn(ComponentId) -> bool,
1580 ) -> bool {
1581 set_contains_id(state)
1582 }
1583}
1584
1585unsafe impl<T: Component> QueryData for &T {
1587 const IS_READ_ONLY: bool = true;
1588 type ReadOnly = Self;
1589 type Item<'w, 's> = &'w T;
1590
1591 fn shrink<'wlong: 'wshort, 'wshort, 's>(
1592 item: Self::Item<'wlong, 's>,
1593 ) -> Self::Item<'wshort, 's> {
1594 item
1595 }
1596
1597 #[inline(always)]
1598 unsafe fn fetch<'w, 's>(
1599 _state: &'s Self::State,
1600 fetch: &mut Self::Fetch<'w>,
1601 entity: Entity,
1602 table_row: TableRow,
1603 ) -> Self::Item<'w, 's> {
1604 fetch.components.extract(
1605 |table| {
1606 let table = unsafe { table.debug_checked_unwrap() };
1608 let item = unsafe { table.get(table_row.index()) };
1610 item.deref()
1611 },
1612 |sparse_set| {
1613 let item = unsafe {
1615 sparse_set
1616 .debug_checked_unwrap()
1617 .get(entity)
1618 .debug_checked_unwrap()
1619 };
1620 item.deref()
1621 },
1622 )
1623 }
1624}
1625
1626unsafe impl<T: Component> ReadOnlyQueryData for &T {}
1628
1629impl<T: Component> ReleaseStateQueryData for &T {
1630 fn release_state<'w>(item: Self::Item<'w, '_>) -> Self::Item<'w, 'static> {
1631 item
1632 }
1633}
1634
1635#[doc(hidden)]
1636pub struct RefFetch<'w, T: Component> {
1637 components: StorageSwitch<
1638 T,
1639 Option<(
1641 ThinSlicePtr<'w, UnsafeCell<T>>,
1642 ThinSlicePtr<'w, UnsafeCell<Tick>>,
1643 ThinSlicePtr<'w, UnsafeCell<Tick>>,
1644 MaybeLocation<ThinSlicePtr<'w, UnsafeCell<&'static Location<'static>>>>,
1645 )>,
1646 Option<&'w ComponentSparseSet>,
1649 >,
1650 last_run: Tick,
1651 this_run: Tick,
1652}
1653
1654impl<T: Component> Clone for RefFetch<'_, T> {
1655 fn clone(&self) -> Self {
1656 *self
1657 }
1658}
1659
1660impl<T: Component> Copy for RefFetch<'_, T> {}
1661
1662unsafe impl<'__w, T: Component> WorldQuery for Ref<'__w, T> {
1668 type Fetch<'w> = RefFetch<'w, T>;
1669 type State = ComponentId;
1670
1671 fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
1672 fetch
1673 }
1674
1675 #[inline]
1676 unsafe fn init_fetch<'w, 's>(
1677 world: UnsafeWorldCell<'w>,
1678 &component_id: &ComponentId,
1679 last_run: Tick,
1680 this_run: Tick,
1681 ) -> RefFetch<'w, T> {
1682 RefFetch {
1683 components: StorageSwitch::new(
1684 || None,
1685 || {
1686 unsafe { world.storages().sparse_sets.get(component_id) }
1691 },
1692 ),
1693 last_run,
1694 this_run,
1695 }
1696 }
1697
1698 const IS_DENSE: bool = {
1699 match T::STORAGE_TYPE {
1700 StorageType::Table => true,
1701 StorageType::SparseSet => false,
1702 }
1703 };
1704
1705 #[inline]
1706 unsafe fn set_archetype<'w>(
1707 fetch: &mut RefFetch<'w, T>,
1708 component_id: &ComponentId,
1709 _archetype: &'w Archetype,
1710 table: &'w Table,
1711 ) {
1712 if Self::IS_DENSE {
1713 unsafe {
1715 Self::set_table(fetch, component_id, table);
1716 }
1717 }
1718 }
1719
1720 #[inline]
1721 unsafe fn set_table<'w>(
1722 fetch: &mut RefFetch<'w, T>,
1723 &component_id: &ComponentId,
1724 table: &'w Table,
1725 ) {
1726 let column = table.get_column(component_id).debug_checked_unwrap();
1727 let table_data = Some((
1728 column.get_data_slice(table.entity_count() as usize).into(),
1729 column
1730 .get_added_ticks_slice(table.entity_count() as usize)
1731 .into(),
1732 column
1733 .get_changed_ticks_slice(table.entity_count() as usize)
1734 .into(),
1735 column
1736 .get_changed_by_slice(table.entity_count() as usize)
1737 .map(Into::into),
1738 ));
1739 unsafe { fetch.components.set_table(table_data) };
1741 }
1742
1743 fn update_component_access(&component_id: &ComponentId, access: &mut FilteredAccess) {
1744 assert!(
1745 !access.access().has_component_write(component_id),
1746 "&{} conflicts with a previous access in this query. Shared access cannot coincide with exclusive access.",
1747 DebugName::type_name::<T>(),
1748 );
1749 access.add_component_read(component_id);
1750 }
1751
1752 fn init_state(world: &mut World) -> ComponentId {
1753 world.register_component::<T>()
1754 }
1755
1756 fn get_state(components: &Components) -> Option<Self::State> {
1757 components.component_id::<T>()
1758 }
1759
1760 fn matches_component_set(
1761 &state: &ComponentId,
1762 set_contains_id: &impl Fn(ComponentId) -> bool,
1763 ) -> bool {
1764 set_contains_id(state)
1765 }
1766}
1767
1768unsafe impl<'__w, T: Component> QueryData for Ref<'__w, T> {
1770 const IS_READ_ONLY: bool = true;
1771 type ReadOnly = Self;
1772 type Item<'w, 's> = Ref<'w, T>;
1773
1774 fn shrink<'wlong: 'wshort, 'wshort, 's>(
1775 item: Self::Item<'wlong, 's>,
1776 ) -> Self::Item<'wshort, 's> {
1777 item
1778 }
1779
1780 #[inline(always)]
1781 unsafe fn fetch<'w, 's>(
1782 _state: &'s Self::State,
1783 fetch: &mut Self::Fetch<'w>,
1784 entity: Entity,
1785 table_row: TableRow,
1786 ) -> Self::Item<'w, 's> {
1787 fetch.components.extract(
1788 |table| {
1789 let (table_components, added_ticks, changed_ticks, callers) =
1791 unsafe { table.debug_checked_unwrap() };
1792
1793 let component = unsafe { table_components.get(table_row.index()) };
1795 let added = unsafe { added_ticks.get(table_row.index()) };
1797 let changed = unsafe { changed_ticks.get(table_row.index()) };
1799 let caller = callers.map(|callers| unsafe { callers.get(table_row.index()) });
1801
1802 Ref {
1803 value: component.deref(),
1804 ticks: Ticks {
1805 added: added.deref(),
1806 changed: changed.deref(),
1807 this_run: fetch.this_run,
1808 last_run: fetch.last_run,
1809 },
1810 changed_by: caller.map(|caller| caller.deref()),
1811 }
1812 },
1813 |sparse_set| {
1814 let (component, ticks, caller) = unsafe {
1816 sparse_set
1817 .debug_checked_unwrap()
1818 .get_with_ticks(entity)
1819 .debug_checked_unwrap()
1820 };
1821
1822 Ref {
1823 value: component.deref(),
1824 ticks: Ticks::from_tick_cells(ticks, fetch.last_run, fetch.this_run),
1825 changed_by: caller.map(|caller| caller.deref()),
1826 }
1827 },
1828 )
1829 }
1830}
1831
1832unsafe impl<'__w, T: Component> ReadOnlyQueryData for Ref<'__w, T> {}
1834
1835impl<T: Component> ReleaseStateQueryData for Ref<'_, T> {
1836 fn release_state<'w>(item: Self::Item<'w, '_>) -> Self::Item<'w, 'static> {
1837 item
1838 }
1839}
1840
1841pub struct WriteFetch<'w, T: Component> {
1843 components: StorageSwitch<
1844 T,
1845 Option<(
1847 ThinSlicePtr<'w, UnsafeCell<T>>,
1848 ThinSlicePtr<'w, UnsafeCell<Tick>>,
1849 ThinSlicePtr<'w, UnsafeCell<Tick>>,
1850 MaybeLocation<ThinSlicePtr<'w, UnsafeCell<&'static Location<'static>>>>,
1851 )>,
1852 Option<&'w ComponentSparseSet>,
1855 >,
1856 last_run: Tick,
1857 this_run: Tick,
1858}
1859
1860impl<T: Component> Clone for WriteFetch<'_, T> {
1861 fn clone(&self) -> Self {
1862 *self
1863 }
1864}
1865
1866impl<T: Component> Copy for WriteFetch<'_, T> {}
1867
1868unsafe impl<'__w, T: Component> WorldQuery for &'__w mut T {
1874 type Fetch<'w> = WriteFetch<'w, T>;
1875 type State = ComponentId;
1876
1877 fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
1878 fetch
1879 }
1880
1881 #[inline]
1882 unsafe fn init_fetch<'w, 's>(
1883 world: UnsafeWorldCell<'w>,
1884 &component_id: &ComponentId,
1885 last_run: Tick,
1886 this_run: Tick,
1887 ) -> WriteFetch<'w, T> {
1888 WriteFetch {
1889 components: StorageSwitch::new(
1890 || None,
1891 || {
1892 unsafe { world.storages().sparse_sets.get(component_id) }
1897 },
1898 ),
1899 last_run,
1900 this_run,
1901 }
1902 }
1903
1904 const IS_DENSE: bool = {
1905 match T::STORAGE_TYPE {
1906 StorageType::Table => true,
1907 StorageType::SparseSet => false,
1908 }
1909 };
1910
1911 #[inline]
1912 unsafe fn set_archetype<'w>(
1913 fetch: &mut WriteFetch<'w, T>,
1914 component_id: &ComponentId,
1915 _archetype: &'w Archetype,
1916 table: &'w Table,
1917 ) {
1918 if Self::IS_DENSE {
1919 unsafe {
1921 Self::set_table(fetch, component_id, table);
1922 }
1923 }
1924 }
1925
1926 #[inline]
1927 unsafe fn set_table<'w>(
1928 fetch: &mut WriteFetch<'w, T>,
1929 &component_id: &ComponentId,
1930 table: &'w Table,
1931 ) {
1932 let column = table.get_column(component_id).debug_checked_unwrap();
1933 let table_data = Some((
1934 column.get_data_slice(table.entity_count() as usize).into(),
1935 column
1936 .get_added_ticks_slice(table.entity_count() as usize)
1937 .into(),
1938 column
1939 .get_changed_ticks_slice(table.entity_count() as usize)
1940 .into(),
1941 column
1942 .get_changed_by_slice(table.entity_count() as usize)
1943 .map(Into::into),
1944 ));
1945 unsafe { fetch.components.set_table(table_data) };
1947 }
1948
1949 fn update_component_access(&component_id: &ComponentId, access: &mut FilteredAccess) {
1950 assert!(
1951 !access.access().has_component_read(component_id),
1952 "&mut {} conflicts with a previous access in this query. Mutable component access must be unique.",
1953 DebugName::type_name::<T>(),
1954 );
1955 access.add_component_write(component_id);
1956 }
1957
1958 fn init_state(world: &mut World) -> ComponentId {
1959 world.register_component::<T>()
1960 }
1961
1962 fn get_state(components: &Components) -> Option<Self::State> {
1963 components.component_id::<T>()
1964 }
1965
1966 fn matches_component_set(
1967 &state: &ComponentId,
1968 set_contains_id: &impl Fn(ComponentId) -> bool,
1969 ) -> bool {
1970 set_contains_id(state)
1971 }
1972}
1973
1974unsafe impl<'__w, T: Component<Mutability = Mutable>> QueryData for &'__w mut T {
1976 const IS_READ_ONLY: bool = false;
1977 type ReadOnly = &'__w T;
1978 type Item<'w, 's> = Mut<'w, T>;
1979
1980 fn shrink<'wlong: 'wshort, 'wshort, 's>(
1981 item: Self::Item<'wlong, 's>,
1982 ) -> Self::Item<'wshort, 's> {
1983 item
1984 }
1985
1986 #[inline(always)]
1987 unsafe fn fetch<'w, 's>(
1988 _state: &'s Self::State,
1989 fetch: &mut Self::Fetch<'w>,
1990 entity: Entity,
1991 table_row: TableRow,
1992 ) -> Self::Item<'w, 's> {
1993 fetch.components.extract(
1994 |table| {
1995 let (table_components, added_ticks, changed_ticks, callers) =
1997 unsafe { table.debug_checked_unwrap() };
1998
1999 let component = unsafe { table_components.get(table_row.index()) };
2001 let added = unsafe { added_ticks.get(table_row.index()) };
2003 let changed = unsafe { changed_ticks.get(table_row.index()) };
2005 let caller = callers.map(|callers| unsafe { callers.get(table_row.index()) });
2007
2008 Mut {
2009 value: component.deref_mut(),
2010 ticks: TicksMut {
2011 added: added.deref_mut(),
2012 changed: changed.deref_mut(),
2013 this_run: fetch.this_run,
2014 last_run: fetch.last_run,
2015 },
2016 changed_by: caller.map(|caller| caller.deref_mut()),
2017 }
2018 },
2019 |sparse_set| {
2020 let (component, ticks, caller) = unsafe {
2022 sparse_set
2023 .debug_checked_unwrap()
2024 .get_with_ticks(entity)
2025 .debug_checked_unwrap()
2026 };
2027
2028 Mut {
2029 value: component.assert_unique().deref_mut(),
2030 ticks: TicksMut::from_tick_cells(ticks, fetch.last_run, fetch.this_run),
2031 changed_by: caller.map(|caller| caller.deref_mut()),
2032 }
2033 },
2034 )
2035 }
2036}
2037
2038impl<T: Component<Mutability = Mutable>> ReleaseStateQueryData for &mut T {
2039 fn release_state<'w>(item: Self::Item<'w, '_>) -> Self::Item<'w, 'static> {
2040 item
2041 }
2042}
2043
2044unsafe impl<'__w, T: Component> WorldQuery for Mut<'__w, T> {
2054 type Fetch<'w> = WriteFetch<'w, T>;
2055 type State = ComponentId;
2056
2057 fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
2058 fetch
2059 }
2060
2061 #[inline]
2062 unsafe fn init_fetch<'w, 's>(
2064 world: UnsafeWorldCell<'w>,
2065 state: &ComponentId,
2066 last_run: Tick,
2067 this_run: Tick,
2068 ) -> WriteFetch<'w, T> {
2069 <&mut T as WorldQuery>::init_fetch(world, state, last_run, this_run)
2070 }
2071
2072 const IS_DENSE: bool = <&mut T as WorldQuery>::IS_DENSE;
2074
2075 #[inline]
2076 unsafe fn set_archetype<'w>(
2078 fetch: &mut WriteFetch<'w, T>,
2079 state: &ComponentId,
2080 archetype: &'w Archetype,
2081 table: &'w Table,
2082 ) {
2083 <&mut T as WorldQuery>::set_archetype(fetch, state, archetype, table);
2084 }
2085
2086 #[inline]
2087 unsafe fn set_table<'w>(fetch: &mut WriteFetch<'w, T>, state: &ComponentId, table: &'w Table) {
2089 <&mut T as WorldQuery>::set_table(fetch, state, table);
2090 }
2091
2092 fn update_component_access(&component_id: &ComponentId, access: &mut FilteredAccess) {
2094 assert!(
2097 !access.access().has_component_read(component_id),
2098 "Mut<{}> conflicts with a previous access in this query. Mutable component access mut be unique.",
2099 DebugName::type_name::<T>(),
2100 );
2101 access.add_component_write(component_id);
2102 }
2103
2104 fn init_state(world: &mut World) -> ComponentId {
2106 <&mut T as WorldQuery>::init_state(world)
2107 }
2108
2109 fn get_state(components: &Components) -> Option<ComponentId> {
2111 <&mut T as WorldQuery>::get_state(components)
2112 }
2113
2114 fn matches_component_set(
2116 state: &ComponentId,
2117 set_contains_id: &impl Fn(ComponentId) -> bool,
2118 ) -> bool {
2119 <&mut T as WorldQuery>::matches_component_set(state, set_contains_id)
2120 }
2121}
2122
2123unsafe impl<'__w, T: Component<Mutability = Mutable>> QueryData for Mut<'__w, T> {
2125 const IS_READ_ONLY: bool = false;
2126 type ReadOnly = Ref<'__w, T>;
2127 type Item<'w, 's> = Mut<'w, T>;
2128
2129 fn shrink<'wlong: 'wshort, 'wshort, 's>(
2131 item: Self::Item<'wlong, 's>,
2132 ) -> Self::Item<'wshort, 's> {
2133 <&mut T as QueryData>::shrink(item)
2134 }
2135
2136 #[inline(always)]
2137 unsafe fn fetch<'w, 's>(
2139 state: &'s Self::State,
2140 fetch: &mut Self::Fetch<'w>,
2143 entity: Entity,
2144 table_row: TableRow,
2145 ) -> Self::Item<'w, 's> {
2146 <&mut T as QueryData>::fetch(state, fetch, entity, table_row)
2147 }
2148}
2149
2150impl<T: Component<Mutability = Mutable>> ReleaseStateQueryData for Mut<'_, T> {
2151 fn release_state<'w>(item: Self::Item<'w, '_>) -> Self::Item<'w, 'static> {
2152 item
2153 }
2154}
2155
2156#[doc(hidden)]
2157pub struct OptionFetch<'w, T: WorldQuery> {
2158 fetch: T::Fetch<'w>,
2159 matches: bool,
2160}
2161
2162impl<T: WorldQuery> Clone for OptionFetch<'_, T> {
2163 fn clone(&self) -> Self {
2164 Self {
2165 fetch: self.fetch.clone(),
2166 matches: self.matches,
2167 }
2168 }
2169}
2170
2171unsafe impl<T: WorldQuery> WorldQuery for Option<T> {
2176 type Fetch<'w> = OptionFetch<'w, T>;
2177 type State = T::State;
2178
2179 fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
2180 OptionFetch {
2181 fetch: T::shrink_fetch(fetch.fetch),
2182 matches: fetch.matches,
2183 }
2184 }
2185
2186 #[inline]
2187 unsafe fn init_fetch<'w, 's>(
2188 world: UnsafeWorldCell<'w>,
2189 state: &'s T::State,
2190 last_run: Tick,
2191 this_run: Tick,
2192 ) -> OptionFetch<'w, T> {
2193 OptionFetch {
2194 fetch: unsafe { T::init_fetch(world, state, last_run, this_run) },
2196 matches: false,
2197 }
2198 }
2199
2200 const IS_DENSE: bool = T::IS_DENSE;
2201
2202 #[inline]
2203 unsafe fn set_archetype<'w, 's>(
2204 fetch: &mut OptionFetch<'w, T>,
2205 state: &'s T::State,
2206 archetype: &'w Archetype,
2207 table: &'w Table,
2208 ) {
2209 fetch.matches = T::matches_component_set(state, &|id| archetype.contains(id));
2210 if fetch.matches {
2211 unsafe {
2213 T::set_archetype(&mut fetch.fetch, state, archetype, table);
2214 }
2215 }
2216 }
2217
2218 #[inline]
2219 unsafe fn set_table<'w, 's>(
2220 fetch: &mut OptionFetch<'w, T>,
2221 state: &'s T::State,
2222 table: &'w Table,
2223 ) {
2224 fetch.matches = T::matches_component_set(state, &|id| table.has_column(id));
2225 if fetch.matches {
2226 unsafe {
2228 T::set_table(&mut fetch.fetch, state, table);
2229 }
2230 }
2231 }
2232
2233 fn update_component_access(state: &T::State, access: &mut FilteredAccess) {
2234 let mut intermediate = access.clone();
2244 T::update_component_access(state, &mut intermediate);
2245 access.extend_access(&intermediate);
2246 }
2247
2248 fn init_state(world: &mut World) -> T::State {
2249 T::init_state(world)
2250 }
2251
2252 fn get_state(components: &Components) -> Option<Self::State> {
2253 T::get_state(components)
2254 }
2255
2256 fn matches_component_set(
2257 _state: &T::State,
2258 _set_contains_id: &impl Fn(ComponentId) -> bool,
2259 ) -> bool {
2260 true
2261 }
2262}
2263
2264unsafe impl<T: QueryData> QueryData for Option<T> {
2266 const IS_READ_ONLY: bool = T::IS_READ_ONLY;
2267 type ReadOnly = Option<T::ReadOnly>;
2268 type Item<'w, 's> = Option<T::Item<'w, 's>>;
2269
2270 fn shrink<'wlong: 'wshort, 'wshort, 's>(
2271 item: Self::Item<'wlong, 's>,
2272 ) -> Self::Item<'wshort, 's> {
2273 item.map(T::shrink)
2274 }
2275
2276 #[inline(always)]
2277 unsafe fn fetch<'w, 's>(
2278 state: &'s Self::State,
2279 fetch: &mut Self::Fetch<'w>,
2280 entity: Entity,
2281 table_row: TableRow,
2282 ) -> Self::Item<'w, 's> {
2283 fetch
2284 .matches
2285 .then(|| unsafe { T::fetch(state, &mut fetch.fetch, entity, table_row) })
2287 }
2288}
2289
2290unsafe impl<T: ReadOnlyQueryData> ReadOnlyQueryData for Option<T> {}
2292
2293impl<T: ReleaseStateQueryData> ReleaseStateQueryData for Option<T> {
2294 fn release_state<'w>(item: Self::Item<'w, '_>) -> Self::Item<'w, 'static> {
2295 item.map(T::release_state)
2296 }
2297}
2298
2299pub struct Has<T>(PhantomData<T>);
2363
2364impl<T> core::fmt::Debug for Has<T> {
2365 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> {
2366 write!(f, "Has<{}>", DebugName::type_name::<T>())
2367 }
2368}
2369
2370unsafe impl<T: Component> WorldQuery for Has<T> {
2374 type Fetch<'w> = bool;
2375 type State = ComponentId;
2376
2377 fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
2378 fetch
2379 }
2380
2381 #[inline]
2382 unsafe fn init_fetch<'w, 's>(
2383 _world: UnsafeWorldCell<'w>,
2384 _state: &'s Self::State,
2385 _last_run: Tick,
2386 _this_run: Tick,
2387 ) -> Self::Fetch<'w> {
2388 false
2389 }
2390
2391 const IS_DENSE: bool = {
2392 match T::STORAGE_TYPE {
2393 StorageType::Table => true,
2394 StorageType::SparseSet => false,
2395 }
2396 };
2397
2398 #[inline]
2399 unsafe fn set_archetype<'w, 's>(
2400 fetch: &mut Self::Fetch<'w>,
2401 state: &'s Self::State,
2402 archetype: &'w Archetype,
2403 _table: &Table,
2404 ) {
2405 *fetch = archetype.contains(*state);
2406 }
2407
2408 #[inline]
2409 unsafe fn set_table<'w, 's>(
2410 fetch: &mut Self::Fetch<'w>,
2411 state: &'s Self::State,
2412 table: &'w Table,
2413 ) {
2414 *fetch = table.has_column(*state);
2415 }
2416
2417 fn update_component_access(&component_id: &Self::State, access: &mut FilteredAccess) {
2418 access.access_mut().add_archetypal(component_id);
2419 }
2420
2421 fn init_state(world: &mut World) -> ComponentId {
2422 world.register_component::<T>()
2423 }
2424
2425 fn get_state(components: &Components) -> Option<Self::State> {
2426 components.component_id::<T>()
2427 }
2428
2429 fn matches_component_set(
2430 _state: &Self::State,
2431 _set_contains_id: &impl Fn(ComponentId) -> bool,
2432 ) -> bool {
2433 true
2435 }
2436}
2437
2438unsafe impl<T: Component> QueryData for Has<T> {
2440 const IS_READ_ONLY: bool = true;
2441 type ReadOnly = Self;
2442 type Item<'w, 's> = bool;
2443
2444 fn shrink<'wlong: 'wshort, 'wshort, 's>(
2445 item: Self::Item<'wlong, 's>,
2446 ) -> Self::Item<'wshort, 's> {
2447 item
2448 }
2449
2450 #[inline(always)]
2451 unsafe fn fetch<'w, 's>(
2452 _state: &'s Self::State,
2453 fetch: &mut Self::Fetch<'w>,
2454 _entity: Entity,
2455 _table_row: TableRow,
2456 ) -> Self::Item<'w, 's> {
2457 *fetch
2458 }
2459}
2460
2461unsafe impl<T: Component> ReadOnlyQueryData for Has<T> {}
2463
2464impl<T: Component> ReleaseStateQueryData for Has<T> {
2465 fn release_state<'w>(item: Self::Item<'w, '_>) -> Self::Item<'w, 'static> {
2466 item
2467 }
2468}
2469
2470pub struct AnyOf<T>(PhantomData<T>);
2476
2477macro_rules! impl_tuple_query_data {
2478 ($(#[$meta:meta])* $(($name: ident, $item: ident, $state: ident)),*) => {
2479 #[expect(
2480 clippy::allow_attributes,
2481 reason = "This is a tuple-related macro; as such the lints below may not always apply."
2482 )]
2483 #[allow(
2484 non_snake_case,
2485 reason = "The names of some variables are provided by the macro's caller, not by us."
2486 )]
2487 #[allow(
2488 unused_variables,
2489 reason = "Zero-length tuples won't use any of the parameters."
2490 )]
2491 #[allow(
2492 clippy::unused_unit,
2493 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."
2494 )]
2495 $(#[$meta])*
2496 unsafe impl<$($name: QueryData),*> QueryData for ($($name,)*) {
2498 const IS_READ_ONLY: bool = true $(&& $name::IS_READ_ONLY)*;
2499 type ReadOnly = ($($name::ReadOnly,)*);
2500 type Item<'w, 's> = ($($name::Item<'w, 's>,)*);
2501
2502 fn shrink<'wlong: 'wshort, 'wshort, 's>(item: Self::Item<'wlong, 's>) -> Self::Item<'wshort, 's> {
2503 let ($($name,)*) = item;
2504 ($(
2505 $name::shrink($name),
2506 )*)
2507 }
2508
2509 #[inline]
2510 fn provide_extra_access(
2511 state: &mut Self::State,
2512 access: &mut Access,
2513 available_access: &Access,
2514 ) {
2515 let ($($name,)*) = state;
2516 $($name::provide_extra_access($name, access, available_access);)*
2517 }
2518
2519 #[inline(always)]
2520 unsafe fn fetch<'w, 's>(
2521 state: &'s Self::State,
2522 fetch: &mut Self::Fetch<'w>,
2523 entity: Entity,
2524 table_row: TableRow
2525 ) -> Self::Item<'w, 's> {
2526 let ($($state,)*) = state;
2527 let ($($name,)*) = fetch;
2528 ($(unsafe { $name::fetch($state, $name, entity, table_row) },)*)
2530 }
2531 }
2532
2533 $(#[$meta])*
2534 unsafe impl<$($name: ReadOnlyQueryData),*> ReadOnlyQueryData for ($($name,)*) {}
2536
2537 #[expect(
2538 clippy::allow_attributes,
2539 reason = "This is a tuple-related macro; as such the lints below may not always apply."
2540 )]
2541 #[allow(
2542 clippy::unused_unit,
2543 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."
2544 )]
2545 $(#[$meta])*
2546 impl<$($name: ReleaseStateQueryData),*> ReleaseStateQueryData for ($($name,)*) {
2547 fn release_state<'w>(($($item,)*): Self::Item<'w, '_>) -> Self::Item<'w, 'static> {
2548 ($($name::release_state($item),)*)
2549 }
2550 }
2551 };
2552}
2553
2554macro_rules! impl_anytuple_fetch {
2555 ($(#[$meta:meta])* $(($name: ident, $state: ident, $item: ident)),*) => {
2556 $(#[$meta])*
2557 #[expect(
2558 clippy::allow_attributes,
2559 reason = "This is a tuple-related macro; as such the lints below may not always apply."
2560 )]
2561 #[allow(
2562 non_snake_case,
2563 reason = "The names of some variables are provided by the macro's caller, not by us."
2564 )]
2565 #[allow(
2566 unused_variables,
2567 reason = "Zero-length tuples won't use any of the parameters."
2568 )]
2569 #[allow(
2570 clippy::unused_unit,
2571 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."
2572 )]
2573 unsafe impl<$($name: WorldQuery),*> WorldQuery for AnyOf<($($name,)*)> {
2579 type Fetch<'w> = ($(($name::Fetch<'w>, bool),)*);
2580 type State = ($($name::State,)*);
2581
2582 fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
2583 let ($($name,)*) = fetch;
2584 ($(
2585 ($name::shrink_fetch($name.0), $name.1),
2586 )*)
2587 }
2588
2589 #[inline]
2590 unsafe fn init_fetch<'w, 's>(_world: UnsafeWorldCell<'w>, state: &'s Self::State, _last_run: Tick, _this_run: Tick) -> Self::Fetch<'w> {
2591 let ($($name,)*) = state;
2592 ($(( unsafe { $name::init_fetch(_world, $name, _last_run, _this_run) }, false),)*)
2594 }
2595
2596 const IS_DENSE: bool = true $(&& $name::IS_DENSE)*;
2597
2598 #[inline]
2599 unsafe fn set_archetype<'w, 's>(
2600 _fetch: &mut Self::Fetch<'w>,
2601 _state: &'s Self::State,
2602 _archetype: &'w Archetype,
2603 _table: &'w Table
2604 ) {
2605 let ($($name,)*) = _fetch;
2606 let ($($state,)*) = _state;
2607 $(
2608 $name.1 = $name::matches_component_set($state, &|id| _archetype.contains(id));
2609 if $name.1 {
2610 unsafe { $name::set_archetype(&mut $name.0, $state, _archetype, _table); }
2612 }
2613 )*
2614 }
2615
2616 #[inline]
2617 unsafe fn set_table<'w, 's>(_fetch: &mut Self::Fetch<'w>, _state: &'s Self::State, _table: &'w Table) {
2618 let ($($name,)*) = _fetch;
2619 let ($($state,)*) = _state;
2620 $(
2621 $name.1 = $name::matches_component_set($state, &|id| _table.has_column(id));
2622 if $name.1 {
2623 unsafe { $name::set_table(&mut $name.0, $state, _table); }
2625 }
2626 )*
2627 }
2628
2629 fn update_component_access(state: &Self::State, access: &mut FilteredAccess) {
2630 let ($($name,)*) = state;
2632
2633 let mut _new_access = FilteredAccess::matches_nothing();
2634
2635 $(
2636 let mut intermediate = access.clone();
2640 $name::update_component_access($name, &mut intermediate);
2641 _new_access.append_or(&intermediate);
2642 )*
2643
2644 access.filter_sets = _new_access.filter_sets;
2646
2647 <($(Option<$name>,)*)>::update_component_access(state, access);
2653
2654 }
2655 fn init_state(world: &mut World) -> Self::State {
2656 ($($name::init_state(world),)*)
2657 }
2658 fn get_state(components: &Components) -> Option<Self::State> {
2659 Some(($($name::get_state(components)?,)*))
2660 }
2661
2662 fn matches_component_set(_state: &Self::State, _set_contains_id: &impl Fn(ComponentId) -> bool) -> bool {
2663 let ($($name,)*) = _state;
2664 false $(|| $name::matches_component_set($name, _set_contains_id))*
2665 }
2666 }
2667
2668 #[expect(
2669 clippy::allow_attributes,
2670 reason = "This is a tuple-related macro; as such the lints below may not always apply."
2671 )]
2672 #[allow(
2673 non_snake_case,
2674 reason = "The names of some variables are provided by the macro's caller, not by us."
2675 )]
2676 #[allow(
2677 unused_variables,
2678 reason = "Zero-length tuples won't use any of the parameters."
2679 )]
2680 #[allow(
2681 clippy::unused_unit,
2682 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."
2683 )]
2684 $(#[$meta])*
2685 unsafe impl<$($name: QueryData),*> QueryData for AnyOf<($($name,)*)> {
2687 const IS_READ_ONLY: bool = true $(&& $name::IS_READ_ONLY)*;
2688 type ReadOnly = AnyOf<($($name::ReadOnly,)*)>;
2689 type Item<'w, 's> = ($(Option<$name::Item<'w, 's>>,)*);
2690
2691 fn shrink<'wlong: 'wshort, 'wshort, 's>(item: Self::Item<'wlong, 's>) -> Self::Item<'wshort, 's> {
2692 let ($($name,)*) = item;
2693 ($(
2694 $name.map($name::shrink),
2695 )*)
2696 }
2697
2698 #[inline(always)]
2699 unsafe fn fetch<'w, 's>(
2700 _state: &'s Self::State,
2701 _fetch: &mut Self::Fetch<'w>,
2702 _entity: Entity,
2703 _table_row: TableRow
2704 ) -> Self::Item<'w, 's> {
2705 let ($($name,)*) = _fetch;
2706 let ($($state,)*) = _state;
2707 ($(
2708 $name.1.then(|| unsafe { $name::fetch($state, &mut $name.0, _entity, _table_row) }),
2710 )*)
2711 }
2712 }
2713
2714 $(#[$meta])*
2715 unsafe impl<$($name: ReadOnlyQueryData),*> ReadOnlyQueryData for AnyOf<($($name,)*)> {}
2717
2718 #[expect(
2719 clippy::allow_attributes,
2720 reason = "This is a tuple-related macro; as such the lints below may not always apply."
2721 )]
2722 #[allow(
2723 clippy::unused_unit,
2724 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."
2725 )]
2726 impl<$($name: ReleaseStateQueryData),*> ReleaseStateQueryData for AnyOf<($($name,)*)> {
2727 fn release_state<'w>(($($item,)*): Self::Item<'w, '_>) -> Self::Item<'w, 'static> {
2728 ($($item.map(|$item| $name::release_state($item)),)*)
2729 }
2730 }
2731 };
2732}
2733
2734all_tuples!(
2735 #[doc(fake_variadic)]
2736 impl_tuple_query_data,
2737 0,
2738 15,
2739 F,
2740 i,
2741 s
2742);
2743all_tuples!(
2744 #[doc(fake_variadic)]
2745 impl_anytuple_fetch,
2746 0,
2747 15,
2748 F,
2749 S,
2750 i
2751);
2752
2753pub(crate) struct NopWorldQuery<D: QueryData>(PhantomData<D>);
2757
2758unsafe impl<D: QueryData> WorldQuery for NopWorldQuery<D> {
2762 type Fetch<'w> = ();
2763 type State = D::State;
2764
2765 fn shrink_fetch<'wlong: 'wshort, 'wshort>(_fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
2766 }
2767
2768 #[inline(always)]
2769 unsafe fn init_fetch(
2770 _world: UnsafeWorldCell,
2771 _state: &D::State,
2772 _last_run: Tick,
2773 _this_run: Tick,
2774 ) {
2775 }
2776
2777 const IS_DENSE: bool = D::IS_DENSE;
2778
2779 #[inline(always)]
2780 unsafe fn set_archetype(
2781 _fetch: &mut (),
2782 _state: &D::State,
2783 _archetype: &Archetype,
2784 _tables: &Table,
2785 ) {
2786 }
2787
2788 #[inline(always)]
2789 unsafe fn set_table<'w>(_fetch: &mut (), _state: &D::State, _table: &Table) {}
2790
2791 fn update_component_access(_state: &D::State, _access: &mut FilteredAccess) {}
2792
2793 fn init_state(world: &mut World) -> Self::State {
2794 D::init_state(world)
2795 }
2796
2797 fn get_state(components: &Components) -> Option<Self::State> {
2798 D::get_state(components)
2799 }
2800
2801 fn matches_component_set(
2802 state: &Self::State,
2803 set_contains_id: &impl Fn(ComponentId) -> bool,
2804 ) -> bool {
2805 D::matches_component_set(state, set_contains_id)
2806 }
2807}
2808
2809unsafe impl<D: QueryData> QueryData for NopWorldQuery<D> {
2811 const IS_READ_ONLY: bool = true;
2812 type ReadOnly = Self;
2813 type Item<'w, 's> = ();
2814
2815 fn shrink<'wlong: 'wshort, 'wshort, 's>(
2816 _item: Self::Item<'wlong, 's>,
2817 ) -> Self::Item<'wshort, 's> {
2818 }
2819
2820 #[inline(always)]
2821 unsafe fn fetch<'w, 's>(
2822 _state: &'s Self::State,
2823 _fetch: &mut Self::Fetch<'w>,
2824 _entity: Entity,
2825 _table_row: TableRow,
2826 ) -> Self::Item<'w, 's> {
2827 }
2828}
2829
2830unsafe impl<D: QueryData> ReadOnlyQueryData for NopWorldQuery<D> {}
2832
2833impl<D: QueryData> ReleaseStateQueryData for NopWorldQuery<D> {
2834 fn release_state<'w>(_item: Self::Item<'w, '_>) -> Self::Item<'w, 'static> {}
2835}
2836
2837unsafe impl<T: ?Sized> WorldQuery for PhantomData<T> {
2841 type Fetch<'w> = ();
2842
2843 type State = ();
2844
2845 fn shrink_fetch<'wlong: 'wshort, 'wshort>(_fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
2846 }
2847
2848 unsafe fn init_fetch<'w, 's>(
2849 _world: UnsafeWorldCell<'w>,
2850 _state: &'s Self::State,
2851 _last_run: Tick,
2852 _this_run: Tick,
2853 ) -> Self::Fetch<'w> {
2854 }
2855
2856 const IS_DENSE: bool = true;
2859
2860 unsafe fn set_archetype<'w, 's>(
2861 _fetch: &mut Self::Fetch<'w>,
2862 _state: &'s Self::State,
2863 _archetype: &'w Archetype,
2864 _table: &'w Table,
2865 ) {
2866 }
2867
2868 unsafe fn set_table<'w, 's>(
2869 _fetch: &mut Self::Fetch<'w>,
2870 _state: &'s Self::State,
2871 _table: &'w Table,
2872 ) {
2873 }
2874
2875 fn update_component_access(_state: &Self::State, _access: &mut FilteredAccess) {}
2876
2877 fn init_state(_world: &mut World) -> Self::State {}
2878
2879 fn get_state(_components: &Components) -> Option<Self::State> {
2880 Some(())
2881 }
2882
2883 fn matches_component_set(
2884 _state: &Self::State,
2885 _set_contains_id: &impl Fn(ComponentId) -> bool,
2886 ) -> bool {
2887 true
2888 }
2889}
2890
2891unsafe impl<T: ?Sized> QueryData for PhantomData<T> {
2893 const IS_READ_ONLY: bool = true;
2894 type ReadOnly = Self;
2895 type Item<'w, 's> = ();
2896
2897 fn shrink<'wlong: 'wshort, 'wshort, 's>(
2898 _item: Self::Item<'wlong, 's>,
2899 ) -> Self::Item<'wshort, 's> {
2900 }
2901
2902 unsafe fn fetch<'w, 's>(
2903 _state: &'s Self::State,
2904 _fetch: &mut Self::Fetch<'w>,
2905 _entity: Entity,
2906 _table_row: TableRow,
2907 ) -> Self::Item<'w, 's> {
2908 }
2909}
2910
2911unsafe impl<T: ?Sized> ReadOnlyQueryData for PhantomData<T> {}
2913
2914impl<T: ?Sized> ReleaseStateQueryData for PhantomData<T> {
2915 fn release_state<'w>(_item: Self::Item<'w, '_>) -> Self::Item<'w, 'static> {}
2916}
2917
2918pub(super) union StorageSwitch<C: Component, T: Copy, S: Copy> {
2921 table: T,
2923 sparse_set: S,
2925 _marker: PhantomData<C>,
2926}
2927
2928impl<C: Component, T: Copy, S: Copy> StorageSwitch<C, T, S> {
2929 pub fn new(table: impl FnOnce() -> T, sparse_set: impl FnOnce() -> S) -> Self {
2932 match C::STORAGE_TYPE {
2933 StorageType::Table => Self { table: table() },
2934 StorageType::SparseSet => Self {
2935 sparse_set: sparse_set(),
2936 },
2937 }
2938 }
2939
2940 #[inline]
2950 pub unsafe fn set_table(&mut self, table: T) {
2951 match C::STORAGE_TYPE {
2952 StorageType::Table => self.table = table,
2953 _ => {
2954 #[cfg(debug_assertions)]
2955 unreachable!();
2956 #[cfg(not(debug_assertions))]
2957 core::hint::unreachable_unchecked()
2958 }
2959 }
2960 }
2961
2962 pub fn extract<R>(&self, table: impl FnOnce(T) -> R, sparse_set: impl FnOnce(S) -> R) -> R {
2965 match C::STORAGE_TYPE {
2966 StorageType::Table => table(
2967 unsafe { self.table },
2969 ),
2970 StorageType::SparseSet => sparse_set(
2971 unsafe { self.sparse_set },
2973 ),
2974 }
2975 }
2976}
2977
2978impl<C: Component, T: Copy, S: Copy> Clone for StorageSwitch<C, T, S> {
2979 fn clone(&self) -> Self {
2980 *self
2981 }
2982}
2983
2984impl<C: Component, T: Copy, S: Copy> Copy for StorageSwitch<C, T, S> {}
2985
2986#[cfg(test)]
2987mod tests {
2988 use super::*;
2989 use crate::change_detection::DetectChanges;
2990 use crate::system::{assert_is_system, Query};
2991 use bevy_ecs::prelude::Schedule;
2992 use bevy_ecs_macros::QueryData;
2993
2994 #[derive(Component)]
2995 pub struct A;
2996
2997 #[derive(Component)]
2998 pub struct B;
2999
3000 #[test]
3002 fn world_query_struct_variants() {
3003 #[derive(QueryData)]
3004 pub struct NamedQuery {
3005 id: Entity,
3006 a: &'static A,
3007 }
3008
3009 #[derive(QueryData)]
3010 pub struct TupleQuery(&'static A, &'static B);
3011
3012 #[derive(QueryData)]
3013 pub struct UnitQuery;
3014
3015 fn my_system(_: Query<(NamedQuery, TupleQuery, UnitQuery)>) {}
3016
3017 assert_is_system(my_system);
3018 }
3019
3020 #[test]
3022 fn world_query_phantom_data() {
3023 #[derive(QueryData)]
3024 pub struct IgnoredQuery<Marker> {
3025 id: Entity,
3026 _marker: PhantomData<Marker>,
3027 }
3028
3029 fn ignored_system(_: Query<IgnoredQuery<()>>) {}
3030
3031 assert_is_system(ignored_system);
3032 }
3033
3034 #[test]
3035 fn derive_release_state() {
3036 struct NonReleaseQueryData;
3037
3038 unsafe impl WorldQuery for NonReleaseQueryData {
3042 type Fetch<'w> = ();
3043 type State = ();
3044
3045 fn shrink_fetch<'wlong: 'wshort, 'wshort>(
3046 _: Self::Fetch<'wlong>,
3047 ) -> Self::Fetch<'wshort> {
3048 }
3049
3050 unsafe fn init_fetch<'w, 's>(
3051 _world: UnsafeWorldCell<'w>,
3052 _state: &'s Self::State,
3053 _last_run: Tick,
3054 _this_run: Tick,
3055 ) -> Self::Fetch<'w> {
3056 }
3057
3058 const IS_DENSE: bool = true;
3059
3060 #[inline]
3061 unsafe fn set_archetype<'w, 's>(
3062 _fetch: &mut Self::Fetch<'w>,
3063 _state: &'s Self::State,
3064 _archetype: &'w Archetype,
3065 _table: &Table,
3066 ) {
3067 }
3068
3069 #[inline]
3070 unsafe fn set_table<'w, 's>(
3071 _fetch: &mut Self::Fetch<'w>,
3072 _state: &'s Self::State,
3073 _table: &'w Table,
3074 ) {
3075 }
3076
3077 fn update_component_access(_state: &Self::State, _access: &mut FilteredAccess) {}
3078
3079 fn init_state(_world: &mut World) {}
3080
3081 fn get_state(_components: &Components) -> Option<()> {
3082 Some(())
3083 }
3084
3085 fn matches_component_set(
3086 _state: &Self::State,
3087 _set_contains_id: &impl Fn(ComponentId) -> bool,
3088 ) -> bool {
3089 true
3090 }
3091 }
3092
3093 unsafe impl QueryData for NonReleaseQueryData {
3095 type ReadOnly = Self;
3096 const IS_READ_ONLY: bool = true;
3097
3098 type Item<'w, 's> = ();
3099
3100 fn shrink<'wlong: 'wshort, 'wshort, 's>(
3101 _item: Self::Item<'wlong, 's>,
3102 ) -> Self::Item<'wshort, 's> {
3103 }
3104
3105 #[inline(always)]
3106 unsafe fn fetch<'w, 's>(
3107 _state: &'s Self::State,
3108 _fetch: &mut Self::Fetch<'w>,
3109 _entity: Entity,
3110 _table_row: TableRow,
3111 ) -> Self::Item<'w, 's> {
3112 }
3113 }
3114
3115 unsafe impl ReadOnlyQueryData for NonReleaseQueryData {}
3117
3118 #[derive(QueryData)]
3119 pub struct DerivedNonReleaseRead {
3120 non_release: NonReleaseQueryData,
3121 a: &'static A,
3122 }
3123
3124 #[derive(QueryData)]
3125 #[query_data(mutable)]
3126 pub struct DerivedNonReleaseMutable {
3127 non_release: NonReleaseQueryData,
3128 a: &'static mut A,
3129 }
3130
3131 #[derive(QueryData)]
3132 pub struct DerivedReleaseRead {
3133 a: &'static A,
3134 }
3135
3136 #[derive(QueryData)]
3137 #[query_data(mutable)]
3138 pub struct DerivedReleaseMutable {
3139 a: &'static mut A,
3140 }
3141
3142 fn assert_is_release_state<Q: ReleaseStateQueryData>() {}
3143
3144 assert_is_release_state::<DerivedReleaseRead>();
3145 assert_is_release_state::<DerivedReleaseMutable>();
3146 }
3147
3148 #[test]
3151 fn read_only_field_visibility() {
3152 mod private {
3153 use super::*;
3154
3155 #[derive(QueryData)]
3156 #[query_data(mutable)]
3157 pub struct D {
3158 pub a: &'static mut A,
3159 }
3160 }
3161
3162 let _ = private::DReadOnly { a: &A };
3163
3164 fn my_system(query: Query<private::D>) {
3165 for q in &query {
3166 let _ = &q.a;
3167 }
3168 }
3169
3170 assert_is_system(my_system);
3171 }
3172
3173 #[test]
3177 fn world_query_metadata_collision() {
3178 #[derive(QueryData)]
3181 pub struct Client<S: ClientState> {
3182 pub state: &'static S,
3183 pub fetch: &'static ClientFetch,
3184 }
3185
3186 pub trait ClientState: Component {}
3187
3188 #[derive(Component)]
3189 pub struct ClientFetch;
3190
3191 #[derive(Component)]
3192 pub struct C;
3193
3194 impl ClientState for C {}
3195
3196 fn client_system(_: Query<Client<C>>) {}
3197
3198 assert_is_system(client_system);
3199 }
3200
3201 #[test]
3205 fn test_entity_ref_query_with_ticks() {
3206 #[derive(Component)]
3207 pub struct C;
3208
3209 fn system(query: Query<EntityRef>) {
3210 for entity_ref in &query {
3211 if let Some(c) = entity_ref.get_ref::<C>() {
3212 if !c.is_added() {
3213 panic!("Expected C to be added");
3214 }
3215 }
3216 }
3217 }
3218
3219 let mut world = World::new();
3220 let mut schedule = Schedule::default();
3221 schedule.add_systems(system);
3222 world.spawn(C);
3223
3224 world.clear_trackers();
3226
3227 schedule.run(&mut world);
3229 }
3230}