1use crate::{
2 archetype::{Archetype, Archetypes},
3 change_detection::{Ticks, TicksMut},
4 component::{Component, ComponentId, Components, StorageType, Tick},
5 entity::{Entities, Entity, EntityLocation},
6 query::{Access, DebugCheckedUnwrap, FilteredAccess, WorldQuery},
7 storage::{ComponentSparseSet, Table, TableRow},
8 world::{
9 unsafe_world_cell::UnsafeWorldCell, EntityMut, EntityRef, FilteredEntityMut,
10 FilteredEntityRef, Mut, Ref, World,
11 },
12};
13use bevy_ptr::{ThinSlicePtr, UnsafeCellDeref};
14use bevy_utils::all_tuples;
15use std::{cell::UnsafeCell, marker::PhantomData};
16
17#[diagnostic::on_unimplemented(
272 message = "`{Self}` is not valid to request as data in a `Query`",
273 label = "invalid `Query` data"
274)]
275pub unsafe trait QueryData: WorldQuery {
276 type ReadOnly: ReadOnlyQueryData<State = <Self as WorldQuery>::State>;
278}
279
280pub unsafe trait ReadOnlyQueryData: QueryData<ReadOnly = Self> {}
286
287pub type QueryItem<'w, Q> = <Q as WorldQuery>::Item<'w>;
289pub type ROQueryItem<'w, D> = QueryItem<'w, <D as QueryData>::ReadOnly>;
291
292unsafe impl WorldQuery for Entity {
296 type Item<'w> = Entity;
297 type Fetch<'w> = ();
298 type State = ();
299
300 fn shrink<'wlong: 'wshort, 'wshort>(item: Self::Item<'wlong>) -> Self::Item<'wshort> {
301 item
302 }
303
304 unsafe fn init_fetch<'w>(
305 _world: UnsafeWorldCell<'w>,
306 _state: &Self::State,
307 _last_run: Tick,
308 _this_run: Tick,
309 ) -> Self::Fetch<'w> {
310 }
311
312 const IS_DENSE: bool = true;
313
314 #[inline]
315 unsafe fn set_archetype<'w>(
316 _fetch: &mut Self::Fetch<'w>,
317 _state: &Self::State,
318 _archetype: &'w Archetype,
319 _table: &Table,
320 ) {
321 }
322
323 #[inline]
324 unsafe fn set_table<'w>(_fetch: &mut Self::Fetch<'w>, _state: &Self::State, _table: &'w Table) {
325 }
326
327 #[inline(always)]
328 unsafe fn fetch<'w>(
329 _fetch: &mut Self::Fetch<'w>,
330 entity: Entity,
331 _table_row: TableRow,
332 ) -> Self::Item<'w> {
333 entity
334 }
335
336 fn update_component_access(_state: &Self::State, _access: &mut FilteredAccess<ComponentId>) {}
337
338 fn init_state(_world: &mut World) {}
339
340 fn get_state(_components: &Components) -> Option<()> {
341 Some(())
342 }
343
344 fn matches_component_set(
345 _state: &Self::State,
346 _set_contains_id: &impl Fn(ComponentId) -> bool,
347 ) -> bool {
348 true
349 }
350}
351
352unsafe impl QueryData for Entity {
354 type ReadOnly = Self;
355}
356
357unsafe impl ReadOnlyQueryData for Entity {}
359
360unsafe impl WorldQuery for EntityLocation {
364 type Item<'w> = EntityLocation;
365 type Fetch<'w> = &'w Entities;
366 type State = ();
367
368 fn shrink<'wlong: 'wshort, 'wshort>(item: Self::Item<'wlong>) -> Self::Item<'wshort> {
369 item
370 }
371
372 unsafe fn init_fetch<'w>(
373 world: UnsafeWorldCell<'w>,
374 _state: &Self::State,
375 _last_run: Tick,
376 _this_run: Tick,
377 ) -> Self::Fetch<'w> {
378 world.entities()
379 }
380
381 const IS_DENSE: bool = true;
384
385 #[inline]
386 unsafe fn set_archetype<'w>(
387 _fetch: &mut Self::Fetch<'w>,
388 _state: &Self::State,
389 _archetype: &'w Archetype,
390 _table: &Table,
391 ) {
392 }
393
394 #[inline]
395 unsafe fn set_table<'w>(_fetch: &mut Self::Fetch<'w>, _state: &Self::State, _table: &'w Table) {
396 }
397
398 #[inline(always)]
399 unsafe fn fetch<'w>(
400 fetch: &mut Self::Fetch<'w>,
401 entity: Entity,
402 _table_row: TableRow,
403 ) -> Self::Item<'w> {
404 unsafe { fetch.get(entity).debug_checked_unwrap() }
406 }
407
408 fn update_component_access(_state: &Self::State, _access: &mut FilteredAccess<ComponentId>) {}
409
410 fn init_state(_world: &mut World) {}
411
412 fn get_state(_components: &Components) -> Option<()> {
413 Some(())
414 }
415
416 fn matches_component_set(
417 _state: &Self::State,
418 _set_contains_id: &impl Fn(ComponentId) -> bool,
419 ) -> bool {
420 true
421 }
422}
423
424unsafe impl QueryData for EntityLocation {
426 type ReadOnly = Self;
427}
428
429unsafe impl ReadOnlyQueryData for EntityLocation {}
431
432unsafe impl<'a> WorldQuery for EntityRef<'a> {
437 type Item<'w> = EntityRef<'w>;
438 type Fetch<'w> = UnsafeWorldCell<'w>;
439 type State = ();
440
441 fn shrink<'wlong: 'wshort, 'wshort>(item: Self::Item<'wlong>) -> Self::Item<'wshort> {
442 item
443 }
444
445 unsafe fn init_fetch<'w>(
446 world: UnsafeWorldCell<'w>,
447 _state: &Self::State,
448 _last_run: Tick,
449 _this_run: Tick,
450 ) -> Self::Fetch<'w> {
451 world
452 }
453
454 const IS_DENSE: bool = true;
455
456 #[inline]
457 unsafe fn set_archetype<'w>(
458 _fetch: &mut Self::Fetch<'w>,
459 _state: &Self::State,
460 _archetype: &'w Archetype,
461 _table: &Table,
462 ) {
463 }
464
465 #[inline]
466 unsafe fn set_table<'w>(_fetch: &mut Self::Fetch<'w>, _state: &Self::State, _table: &'w Table) {
467 }
468
469 #[inline(always)]
470 unsafe fn fetch<'w>(
471 world: &mut Self::Fetch<'w>,
472 entity: Entity,
473 _table_row: TableRow,
474 ) -> Self::Item<'w> {
475 let cell = unsafe { world.get_entity(entity).debug_checked_unwrap() };
477 unsafe { EntityRef::new(cell) }
479 }
480
481 fn update_component_access(_state: &Self::State, access: &mut FilteredAccess<ComponentId>) {
482 assert!(
483 !access.access().has_any_write(),
484 "EntityRef conflicts with a previous access in this query. Shared access cannot coincide with exclusive access.",
485 );
486 access.read_all();
487 }
488
489 fn init_state(_world: &mut World) {}
490
491 fn get_state(_components: &Components) -> Option<()> {
492 Some(())
493 }
494
495 fn matches_component_set(
496 _state: &Self::State,
497 _set_contains_id: &impl Fn(ComponentId) -> bool,
498 ) -> bool {
499 true
500 }
501}
502
503unsafe impl<'a> QueryData for EntityRef<'a> {
505 type ReadOnly = Self;
506}
507
508unsafe impl ReadOnlyQueryData for EntityRef<'_> {}
510
511unsafe impl<'a> WorldQuery for EntityMut<'a> {
513 type Item<'w> = EntityMut<'w>;
514 type Fetch<'w> = UnsafeWorldCell<'w>;
515 type State = ();
516
517 fn shrink<'wlong: 'wshort, 'wshort>(item: Self::Item<'wlong>) -> Self::Item<'wshort> {
518 item
519 }
520
521 unsafe fn init_fetch<'w>(
522 world: UnsafeWorldCell<'w>,
523 _state: &Self::State,
524 _last_run: Tick,
525 _this_run: Tick,
526 ) -> Self::Fetch<'w> {
527 world
528 }
529
530 const IS_DENSE: bool = true;
531
532 #[inline]
533 unsafe fn set_archetype<'w>(
534 _fetch: &mut Self::Fetch<'w>,
535 _state: &Self::State,
536 _archetype: &'w Archetype,
537 _table: &Table,
538 ) {
539 }
540
541 #[inline]
542 unsafe fn set_table<'w>(_fetch: &mut Self::Fetch<'w>, _state: &Self::State, _table: &'w Table) {
543 }
544
545 #[inline(always)]
546 unsafe fn fetch<'w>(
547 world: &mut Self::Fetch<'w>,
548 entity: Entity,
549 _table_row: TableRow,
550 ) -> Self::Item<'w> {
551 let cell = unsafe { world.get_entity(entity).debug_checked_unwrap() };
553 unsafe { EntityMut::new(cell) }
555 }
556
557 fn update_component_access(_state: &Self::State, access: &mut FilteredAccess<ComponentId>) {
558 assert!(
559 !access.access().has_any_read(),
560 "EntityMut conflicts with a previous access in this query. Exclusive access cannot coincide with any other accesses.",
561 );
562 access.write_all();
563 }
564
565 fn init_state(_world: &mut World) {}
566
567 fn get_state(_components: &Components) -> Option<()> {
568 Some(())
569 }
570
571 fn matches_component_set(
572 _state: &Self::State,
573 _set_contains_id: &impl Fn(ComponentId) -> bool,
574 ) -> bool {
575 true
576 }
577}
578
579unsafe impl<'a> QueryData for EntityMut<'a> {
581 type ReadOnly = EntityRef<'a>;
582}
583
584unsafe impl<'a> WorldQuery for FilteredEntityRef<'a> {
586 type Fetch<'w> = (UnsafeWorldCell<'w>, Access<ComponentId>);
587 type Item<'w> = FilteredEntityRef<'w>;
588 type State = FilteredAccess<ComponentId>;
589
590 fn shrink<'wlong: 'wshort, 'wshort>(item: Self::Item<'wlong>) -> Self::Item<'wshort> {
591 item
592 }
593
594 const IS_DENSE: bool = false;
595
596 unsafe fn init_fetch<'w>(
597 world: UnsafeWorldCell<'w>,
598 _state: &Self::State,
599 _last_run: Tick,
600 _this_run: Tick,
601 ) -> Self::Fetch<'w> {
602 let mut access = Access::default();
603 access.read_all();
604 (world, access)
605 }
606
607 #[inline]
608 unsafe fn set_archetype<'w>(
609 fetch: &mut Self::Fetch<'w>,
610 state: &Self::State,
611 archetype: &'w Archetype,
612 _table: &Table,
613 ) {
614 let mut access = Access::default();
615 state.access.reads().for_each(|id| {
616 if archetype.contains(id) {
617 access.add_read(id);
618 }
619 });
620 fetch.1 = access;
621 }
622
623 #[inline]
624 unsafe fn set_table<'w>(fetch: &mut Self::Fetch<'w>, state: &Self::State, table: &'w Table) {
625 let mut access = Access::default();
626 state.access.reads().for_each(|id| {
627 if table.has_column(id) {
628 access.add_read(id);
629 }
630 });
631 fetch.1 = access;
632 }
633
634 #[inline]
635 fn set_access<'w>(state: &mut Self::State, access: &FilteredAccess<ComponentId>) {
636 *state = access.clone();
637 state.access_mut().clear_writes();
638 }
639
640 #[inline(always)]
641 unsafe fn fetch<'w>(
642 (world, access): &mut Self::Fetch<'w>,
643 entity: Entity,
644 _table_row: TableRow,
645 ) -> Self::Item<'w> {
646 let cell = unsafe { world.get_entity(entity).debug_checked_unwrap() };
648 unsafe { FilteredEntityRef::new(cell, access.clone()) }
650 }
651
652 fn update_component_access(
653 state: &Self::State,
654 filtered_access: &mut FilteredAccess<ComponentId>,
655 ) {
656 assert!(
657 filtered_access.access().is_compatible(&state.access),
658 "FilteredEntityRef conflicts with a previous access in this query. Exclusive access cannot coincide with any other accesses.",
659 );
660 filtered_access.access.extend(&state.access);
661 }
662
663 fn init_state(_world: &mut World) -> Self::State {
664 FilteredAccess::default()
665 }
666
667 fn get_state(_components: &Components) -> Option<Self::State> {
668 Some(FilteredAccess::default())
669 }
670
671 fn matches_component_set(
672 _state: &Self::State,
673 _set_contains_id: &impl Fn(ComponentId) -> bool,
674 ) -> bool {
675 true
676 }
677}
678
679unsafe impl<'a> QueryData for FilteredEntityRef<'a> {
681 type ReadOnly = Self;
682}
683
684unsafe impl ReadOnlyQueryData for FilteredEntityRef<'_> {}
686
687unsafe impl<'a> WorldQuery for FilteredEntityMut<'a> {
689 type Fetch<'w> = (UnsafeWorldCell<'w>, Access<ComponentId>);
690 type Item<'w> = FilteredEntityMut<'w>;
691 type State = FilteredAccess<ComponentId>;
692
693 fn shrink<'wlong: 'wshort, 'wshort>(item: Self::Item<'wlong>) -> Self::Item<'wshort> {
694 item
695 }
696
697 const IS_DENSE: bool = false;
698
699 unsafe fn init_fetch<'w>(
700 world: UnsafeWorldCell<'w>,
701 _state: &Self::State,
702 _last_run: Tick,
703 _this_run: Tick,
704 ) -> Self::Fetch<'w> {
705 let mut access = Access::default();
706 access.write_all();
707 (world, access)
708 }
709
710 #[inline]
711 unsafe fn set_archetype<'w>(
712 fetch: &mut Self::Fetch<'w>,
713 state: &Self::State,
714 archetype: &'w Archetype,
715 _table: &Table,
716 ) {
717 let mut access = Access::default();
718 state.access.reads().for_each(|id| {
719 if archetype.contains(id) {
720 access.add_read(id);
721 }
722 });
723 state.access.writes().for_each(|id| {
724 if archetype.contains(id) {
725 access.add_write(id);
726 }
727 });
728 fetch.1 = access;
729 }
730
731 #[inline]
732 unsafe fn set_table<'w>(fetch: &mut Self::Fetch<'w>, state: &Self::State, table: &'w Table) {
733 let mut access = Access::default();
734 state.access.reads().for_each(|id| {
735 if table.has_column(id) {
736 access.add_read(id);
737 }
738 });
739 state.access.writes().for_each(|id| {
740 if table.has_column(id) {
741 access.add_write(id);
742 }
743 });
744 fetch.1 = access;
745 }
746
747 #[inline]
748 fn set_access<'w>(state: &mut Self::State, access: &FilteredAccess<ComponentId>) {
749 *state = access.clone();
750 }
751
752 #[inline(always)]
753 unsafe fn fetch<'w>(
754 (world, access): &mut Self::Fetch<'w>,
755 entity: Entity,
756 _table_row: TableRow,
757 ) -> Self::Item<'w> {
758 let cell = unsafe { world.get_entity(entity).debug_checked_unwrap() };
760 unsafe { FilteredEntityMut::new(cell, access.clone()) }
762 }
763
764 fn update_component_access(
765 state: &Self::State,
766 filtered_access: &mut FilteredAccess<ComponentId>,
767 ) {
768 assert!(
769 filtered_access.access().is_compatible(&state.access),
770 "FilteredEntityMut conflicts with a previous access in this query. Exclusive access cannot coincide with any other accesses.",
771 );
772 filtered_access.access.extend(&state.access);
773 }
774
775 fn init_state(_world: &mut World) -> Self::State {
776 FilteredAccess::default()
777 }
778
779 fn get_state(_components: &Components) -> Option<Self::State> {
780 Some(FilteredAccess::default())
781 }
782
783 fn matches_component_set(
784 _state: &Self::State,
785 _set_contains_id: &impl Fn(ComponentId) -> bool,
786 ) -> bool {
787 true
788 }
789}
790
791unsafe impl<'a> QueryData for FilteredEntityMut<'a> {
793 type ReadOnly = FilteredEntityRef<'a>;
794}
795
796unsafe impl WorldQuery for &Archetype {
800 type Item<'w> = &'w Archetype;
801 type Fetch<'w> = (&'w Entities, &'w Archetypes);
802 type State = ();
803
804 fn shrink<'wlong: 'wshort, 'wshort>(item: Self::Item<'wlong>) -> Self::Item<'wshort> {
805 item
806 }
807
808 unsafe fn init_fetch<'w>(
809 world: UnsafeWorldCell<'w>,
810 _state: &Self::State,
811 _last_run: Tick,
812 _this_run: Tick,
813 ) -> Self::Fetch<'w> {
814 (world.entities(), world.archetypes())
815 }
816
817 const IS_DENSE: bool = true;
820
821 #[inline]
822 unsafe fn set_archetype<'w>(
823 _fetch: &mut Self::Fetch<'w>,
824 _state: &Self::State,
825 _archetype: &'w Archetype,
826 _table: &Table,
827 ) {
828 }
829
830 #[inline]
831 unsafe fn set_table<'w>(_fetch: &mut Self::Fetch<'w>, _state: &Self::State, _table: &'w Table) {
832 }
833
834 #[inline(always)]
835 unsafe fn fetch<'w>(
836 fetch: &mut Self::Fetch<'w>,
837 entity: Entity,
838 _table_row: TableRow,
839 ) -> Self::Item<'w> {
840 let (entities, archetypes) = *fetch;
841 let location = unsafe { entities.get(entity).debug_checked_unwrap() };
843 unsafe { archetypes.get(location.archetype_id).debug_checked_unwrap() }
845 }
846
847 fn update_component_access(_state: &Self::State, _access: &mut FilteredAccess<ComponentId>) {}
848
849 fn init_state(_world: &mut World) {}
850
851 fn get_state(_components: &Components) -> Option<()> {
852 Some(())
853 }
854
855 fn matches_component_set(
856 _state: &Self::State,
857 _set_contains_id: &impl Fn(ComponentId) -> bool,
858 ) -> bool {
859 true
860 }
861}
862
863unsafe impl QueryData for &Archetype {
865 type ReadOnly = Self;
866}
867
868unsafe impl ReadOnlyQueryData for &Archetype {}
870
871#[doc(hidden)]
872pub struct ReadFetch<'w, T> {
873 table_components: Option<ThinSlicePtr<'w, UnsafeCell<T>>>,
875 sparse_set: Option<&'w ComponentSparseSet>,
877}
878
879impl<T> Clone for ReadFetch<'_, T> {
880 fn clone(&self) -> Self {
881 *self
882 }
883}
884impl<T> Copy for ReadFetch<'_, T> {}
885
886unsafe impl<T: Component> WorldQuery for &T {
892 type Item<'w> = &'w T;
893 type Fetch<'w> = ReadFetch<'w, T>;
894 type State = ComponentId;
895
896 fn shrink<'wlong: 'wshort, 'wshort>(item: &'wlong T) -> &'wshort T {
897 item
898 }
899
900 #[inline]
901 unsafe fn init_fetch<'w>(
902 world: UnsafeWorldCell<'w>,
903 &component_id: &ComponentId,
904 _last_run: Tick,
905 _this_run: Tick,
906 ) -> ReadFetch<'w, T> {
907 ReadFetch {
908 table_components: None,
909 sparse_set: (T::STORAGE_TYPE == StorageType::SparseSet).then(|| {
910 unsafe {
915 world
916 .storages()
917 .sparse_sets
918 .get(component_id)
919 .debug_checked_unwrap()
920 }
921 }),
922 }
923 }
924
925 const IS_DENSE: bool = {
926 match T::STORAGE_TYPE {
927 StorageType::Table => true,
928 StorageType::SparseSet => false,
929 }
930 };
931
932 #[inline]
933 unsafe fn set_archetype<'w>(
934 fetch: &mut ReadFetch<'w, T>,
935 component_id: &ComponentId,
936 _archetype: &'w Archetype,
937 table: &'w Table,
938 ) {
939 if Self::IS_DENSE {
940 unsafe {
942 Self::set_table(fetch, component_id, table);
943 }
944 }
945 }
946
947 #[inline]
948 unsafe fn set_table<'w>(
949 fetch: &mut ReadFetch<'w, T>,
950 &component_id: &ComponentId,
951 table: &'w Table,
952 ) {
953 fetch.table_components = Some(
954 table
955 .get_column(component_id)
956 .debug_checked_unwrap()
957 .get_data_slice()
958 .into(),
959 );
960 }
961
962 #[inline(always)]
963 unsafe fn fetch<'w>(
964 fetch: &mut Self::Fetch<'w>,
965 entity: Entity,
966 table_row: TableRow,
967 ) -> Self::Item<'w> {
968 match T::STORAGE_TYPE {
969 StorageType::Table => {
970 let table = unsafe { fetch.table_components.debug_checked_unwrap() };
972 let item = unsafe { table.get(table_row.as_usize()) };
974 item.deref()
975 }
976 StorageType::SparseSet => {
977 let sparse_set = unsafe { fetch.sparse_set.debug_checked_unwrap() };
979 let item = unsafe { sparse_set.get(entity).debug_checked_unwrap() };
981 item.deref()
982 }
983 }
984 }
985
986 fn update_component_access(
987 &component_id: &ComponentId,
988 access: &mut FilteredAccess<ComponentId>,
989 ) {
990 assert!(
991 !access.access().has_write(component_id),
992 "&{} conflicts with a previous access in this query. Shared access cannot coincide with exclusive access.",
993 std::any::type_name::<T>(),
994 );
995 access.add_read(component_id);
996 }
997
998 fn init_state(world: &mut World) -> ComponentId {
999 world.init_component::<T>()
1000 }
1001
1002 fn get_state(components: &Components) -> Option<Self::State> {
1003 components.component_id::<T>()
1004 }
1005
1006 fn matches_component_set(
1007 &state: &ComponentId,
1008 set_contains_id: &impl Fn(ComponentId) -> bool,
1009 ) -> bool {
1010 set_contains_id(state)
1011 }
1012}
1013
1014unsafe impl<T: Component> QueryData for &T {
1016 type ReadOnly = Self;
1017}
1018
1019unsafe impl<T: Component> ReadOnlyQueryData for &T {}
1021
1022#[doc(hidden)]
1023pub struct RefFetch<'w, T> {
1024 table_data: Option<(
1026 ThinSlicePtr<'w, UnsafeCell<T>>,
1027 ThinSlicePtr<'w, UnsafeCell<Tick>>,
1028 ThinSlicePtr<'w, UnsafeCell<Tick>>,
1029 )>,
1030 sparse_set: Option<&'w ComponentSparseSet>,
1032
1033 last_run: Tick,
1034 this_run: Tick,
1035}
1036
1037impl<T> Clone for RefFetch<'_, T> {
1038 fn clone(&self) -> Self {
1039 *self
1040 }
1041}
1042impl<T> Copy for RefFetch<'_, T> {}
1043
1044unsafe impl<'__w, T: Component> WorldQuery for Ref<'__w, T> {
1050 type Item<'w> = Ref<'w, T>;
1051 type Fetch<'w> = RefFetch<'w, T>;
1052 type State = ComponentId;
1053
1054 fn shrink<'wlong: 'wshort, 'wshort>(item: Ref<'wlong, T>) -> Ref<'wshort, T> {
1055 item
1056 }
1057
1058 #[inline]
1059 unsafe fn init_fetch<'w>(
1060 world: UnsafeWorldCell<'w>,
1061 &component_id: &ComponentId,
1062 last_run: Tick,
1063 this_run: Tick,
1064 ) -> RefFetch<'w, T> {
1065 RefFetch {
1066 table_data: None,
1067 sparse_set: (T::STORAGE_TYPE == StorageType::SparseSet).then(|| {
1068 unsafe {
1073 world
1074 .storages()
1075 .sparse_sets
1076 .get(component_id)
1077 .debug_checked_unwrap()
1078 }
1079 }),
1080 last_run,
1081 this_run,
1082 }
1083 }
1084
1085 const IS_DENSE: bool = {
1086 match T::STORAGE_TYPE {
1087 StorageType::Table => true,
1088 StorageType::SparseSet => false,
1089 }
1090 };
1091
1092 #[inline]
1093 unsafe fn set_archetype<'w>(
1094 fetch: &mut RefFetch<'w, T>,
1095 component_id: &ComponentId,
1096 _archetype: &'w Archetype,
1097 table: &'w Table,
1098 ) {
1099 if Self::IS_DENSE {
1100 unsafe {
1102 Self::set_table(fetch, component_id, table);
1103 }
1104 }
1105 }
1106
1107 #[inline]
1108 unsafe fn set_table<'w>(
1109 fetch: &mut RefFetch<'w, T>,
1110 &component_id: &ComponentId,
1111 table: &'w Table,
1112 ) {
1113 let column = table.get_column(component_id).debug_checked_unwrap();
1114 fetch.table_data = Some((
1115 column.get_data_slice().into(),
1116 column.get_added_ticks_slice().into(),
1117 column.get_changed_ticks_slice().into(),
1118 ));
1119 }
1120
1121 #[inline(always)]
1122 unsafe fn fetch<'w>(
1123 fetch: &mut Self::Fetch<'w>,
1124 entity: Entity,
1125 table_row: TableRow,
1126 ) -> Self::Item<'w> {
1127 match T::STORAGE_TYPE {
1128 StorageType::Table => {
1129 let (table_components, added_ticks, changed_ticks) =
1131 unsafe { fetch.table_data.debug_checked_unwrap() };
1132
1133 let component = unsafe { table_components.get(table_row.as_usize()) };
1135 let added = unsafe { added_ticks.get(table_row.as_usize()) };
1137 let changed = unsafe { changed_ticks.get(table_row.as_usize()) };
1139
1140 Ref {
1141 value: component.deref(),
1142 ticks: Ticks {
1143 added: added.deref(),
1144 changed: changed.deref(),
1145 this_run: fetch.this_run,
1146 last_run: fetch.last_run,
1147 },
1148 }
1149 }
1150 StorageType::SparseSet => {
1151 let component_sparse_set = unsafe { fetch.sparse_set.debug_checked_unwrap() };
1153
1154 let (component, ticks) = unsafe {
1156 component_sparse_set
1157 .get_with_ticks(entity)
1158 .debug_checked_unwrap()
1159 };
1160
1161 Ref {
1162 value: component.deref(),
1163 ticks: Ticks::from_tick_cells(ticks, fetch.last_run, fetch.this_run),
1164 }
1165 }
1166 }
1167 }
1168
1169 fn update_component_access(
1170 &component_id: &ComponentId,
1171 access: &mut FilteredAccess<ComponentId>,
1172 ) {
1173 assert!(
1174 !access.access().has_write(component_id),
1175 "&{} conflicts with a previous access in this query. Shared access cannot coincide with exclusive access.",
1176 std::any::type_name::<T>(),
1177 );
1178 access.add_read(component_id);
1179 }
1180
1181 fn init_state(world: &mut World) -> ComponentId {
1182 world.init_component::<T>()
1183 }
1184
1185 fn get_state(components: &Components) -> Option<Self::State> {
1186 components.component_id::<T>()
1187 }
1188
1189 fn matches_component_set(
1190 &state: &ComponentId,
1191 set_contains_id: &impl Fn(ComponentId) -> bool,
1192 ) -> bool {
1193 set_contains_id(state)
1194 }
1195}
1196
1197unsafe impl<'__w, T: Component> QueryData for Ref<'__w, T> {
1199 type ReadOnly = Self;
1200}
1201
1202unsafe impl<'__w, T: Component> ReadOnlyQueryData for Ref<'__w, T> {}
1204
1205#[doc(hidden)]
1206pub struct WriteFetch<'w, T> {
1207 table_data: Option<(
1209 ThinSlicePtr<'w, UnsafeCell<T>>,
1210 ThinSlicePtr<'w, UnsafeCell<Tick>>,
1211 ThinSlicePtr<'w, UnsafeCell<Tick>>,
1212 )>,
1213 sparse_set: Option<&'w ComponentSparseSet>,
1215
1216 last_run: Tick,
1217 this_run: Tick,
1218}
1219
1220impl<T> Clone for WriteFetch<'_, T> {
1221 fn clone(&self) -> Self {
1222 *self
1223 }
1224}
1225impl<T> Copy for WriteFetch<'_, T> {}
1226
1227unsafe impl<'__w, T: Component> WorldQuery for &'__w mut T {
1233 type Item<'w> = Mut<'w, T>;
1234 type Fetch<'w> = WriteFetch<'w, T>;
1235 type State = ComponentId;
1236
1237 fn shrink<'wlong: 'wshort, 'wshort>(item: Mut<'wlong, T>) -> Mut<'wshort, T> {
1238 item
1239 }
1240
1241 #[inline]
1242 unsafe fn init_fetch<'w>(
1243 world: UnsafeWorldCell<'w>,
1244 &component_id: &ComponentId,
1245 last_run: Tick,
1246 this_run: Tick,
1247 ) -> WriteFetch<'w, T> {
1248 WriteFetch {
1249 table_data: None,
1250 sparse_set: (T::STORAGE_TYPE == StorageType::SparseSet).then(|| {
1251 unsafe {
1256 world
1257 .storages()
1258 .sparse_sets
1259 .get(component_id)
1260 .debug_checked_unwrap()
1261 }
1262 }),
1263 last_run,
1264 this_run,
1265 }
1266 }
1267
1268 const IS_DENSE: bool = {
1269 match T::STORAGE_TYPE {
1270 StorageType::Table => true,
1271 StorageType::SparseSet => false,
1272 }
1273 };
1274
1275 #[inline]
1276 unsafe fn set_archetype<'w>(
1277 fetch: &mut WriteFetch<'w, T>,
1278 component_id: &ComponentId,
1279 _archetype: &'w Archetype,
1280 table: &'w Table,
1281 ) {
1282 if Self::IS_DENSE {
1283 unsafe {
1285 Self::set_table(fetch, component_id, table);
1286 }
1287 }
1288 }
1289
1290 #[inline]
1291 unsafe fn set_table<'w>(
1292 fetch: &mut WriteFetch<'w, T>,
1293 &component_id: &ComponentId,
1294 table: &'w Table,
1295 ) {
1296 let column = table.get_column(component_id).debug_checked_unwrap();
1297 fetch.table_data = Some((
1298 column.get_data_slice().into(),
1299 column.get_added_ticks_slice().into(),
1300 column.get_changed_ticks_slice().into(),
1301 ));
1302 }
1303
1304 #[inline(always)]
1305 unsafe fn fetch<'w>(
1306 fetch: &mut Self::Fetch<'w>,
1307 entity: Entity,
1308 table_row: TableRow,
1309 ) -> Self::Item<'w> {
1310 match T::STORAGE_TYPE {
1311 StorageType::Table => {
1312 let (table_components, added_ticks, changed_ticks) =
1314 unsafe { fetch.table_data.debug_checked_unwrap() };
1315
1316 let component = unsafe { table_components.get(table_row.as_usize()) };
1318 let added = unsafe { added_ticks.get(table_row.as_usize()) };
1320 let changed = unsafe { changed_ticks.get(table_row.as_usize()) };
1322
1323 Mut {
1324 value: component.deref_mut(),
1325 ticks: TicksMut {
1326 added: added.deref_mut(),
1327 changed: changed.deref_mut(),
1328 this_run: fetch.this_run,
1329 last_run: fetch.last_run,
1330 },
1331 }
1332 }
1333 StorageType::SparseSet => {
1334 let component_sparse_set = unsafe { fetch.sparse_set.debug_checked_unwrap() };
1336
1337 let (component, ticks) = unsafe {
1339 component_sparse_set
1340 .get_with_ticks(entity)
1341 .debug_checked_unwrap()
1342 };
1343
1344 Mut {
1345 value: component.assert_unique().deref_mut(),
1346 ticks: TicksMut::from_tick_cells(ticks, fetch.last_run, fetch.this_run),
1347 }
1348 }
1349 }
1350 }
1351
1352 fn update_component_access(
1353 &component_id: &ComponentId,
1354 access: &mut FilteredAccess<ComponentId>,
1355 ) {
1356 assert!(
1357 !access.access().has_read(component_id),
1358 "&mut {} conflicts with a previous access in this query. Mutable component access must be unique.",
1359 std::any::type_name::<T>(),
1360 );
1361 access.add_write(component_id);
1362 }
1363
1364 fn init_state(world: &mut World) -> ComponentId {
1365 world.init_component::<T>()
1366 }
1367
1368 fn get_state(components: &Components) -> Option<Self::State> {
1369 components.component_id::<T>()
1370 }
1371
1372 fn matches_component_set(
1373 &state: &ComponentId,
1374 set_contains_id: &impl Fn(ComponentId) -> bool,
1375 ) -> bool {
1376 set_contains_id(state)
1377 }
1378}
1379
1380unsafe impl<'__w, T: Component> QueryData for &'__w mut T {
1382 type ReadOnly = &'__w T;
1383}
1384
1385unsafe impl<'__w, T: Component> WorldQuery for Mut<'__w, T> {
1395 type Item<'w> = Mut<'w, T>;
1396 type Fetch<'w> = WriteFetch<'w, T>;
1397 type State = ComponentId;
1398
1399 fn shrink<'wlong: 'wshort, 'wshort>(item: Mut<'wlong, T>) -> Mut<'wshort, T> {
1401 <&mut T as WorldQuery>::shrink(item)
1402 }
1403
1404 #[inline]
1405 unsafe fn init_fetch<'w>(
1407 world: UnsafeWorldCell<'w>,
1408 state: &ComponentId,
1409 last_run: Tick,
1410 this_run: Tick,
1411 ) -> WriteFetch<'w, T> {
1412 <&mut T as WorldQuery>::init_fetch(world, state, last_run, this_run)
1413 }
1414
1415 const IS_DENSE: bool = <&mut T as WorldQuery>::IS_DENSE;
1417
1418 #[inline]
1419 unsafe fn set_archetype<'w>(
1421 fetch: &mut WriteFetch<'w, T>,
1422 state: &ComponentId,
1423 archetype: &'w Archetype,
1424 table: &'w Table,
1425 ) {
1426 <&mut T as WorldQuery>::set_archetype(fetch, state, archetype, table);
1427 }
1428
1429 #[inline]
1430 unsafe fn set_table<'w>(fetch: &mut WriteFetch<'w, T>, state: &ComponentId, table: &'w Table) {
1432 <&mut T as WorldQuery>::set_table(fetch, state, table);
1433 }
1434
1435 #[inline(always)]
1436 unsafe fn fetch<'w>(
1438 fetch: &mut Self::Fetch<'w>,
1441 entity: Entity,
1442 table_row: TableRow,
1443 ) -> Mut<'w, T> {
1444 <&mut T as WorldQuery>::fetch(fetch, entity, table_row)
1445 }
1446
1447 fn update_component_access(
1449 &component_id: &ComponentId,
1450 access: &mut FilteredAccess<ComponentId>,
1451 ) {
1452 assert!(
1455 !access.access().has_read(component_id),
1456 "Mut<{}> conflicts with a previous access in this query. Mutable component access mut be unique.",
1457 std::any::type_name::<T>(),
1458 );
1459 access.add_write(component_id);
1460 }
1461
1462 fn init_state(world: &mut World) -> ComponentId {
1464 <&mut T as WorldQuery>::init_state(world)
1465 }
1466
1467 fn get_state(components: &Components) -> Option<ComponentId> {
1469 <&mut T as WorldQuery>::get_state(components)
1470 }
1471
1472 fn matches_component_set(
1474 state: &ComponentId,
1475 set_contains_id: &impl Fn(ComponentId) -> bool,
1476 ) -> bool {
1477 <&mut T as WorldQuery>::matches_component_set(state, set_contains_id)
1478 }
1479}
1480
1481unsafe impl<'__w, T: Component> QueryData for Mut<'__w, T> {
1483 type ReadOnly = Ref<'__w, T>;
1484}
1485
1486#[doc(hidden)]
1487pub struct OptionFetch<'w, T: WorldQuery> {
1488 fetch: T::Fetch<'w>,
1489 matches: bool,
1490}
1491
1492impl<T: WorldQuery> Clone for OptionFetch<'_, T> {
1493 fn clone(&self) -> Self {
1494 Self {
1495 fetch: self.fetch.clone(),
1496 matches: self.matches,
1497 }
1498 }
1499}
1500
1501unsafe impl<T: WorldQuery> WorldQuery for Option<T> {
1506 type Item<'w> = Option<T::Item<'w>>;
1507 type Fetch<'w> = OptionFetch<'w, T>;
1508 type State = T::State;
1509
1510 fn shrink<'wlong: 'wshort, 'wshort>(item: Self::Item<'wlong>) -> Self::Item<'wshort> {
1511 item.map(T::shrink)
1512 }
1513
1514 #[inline]
1515 unsafe fn init_fetch<'w>(
1516 world: UnsafeWorldCell<'w>,
1517 state: &T::State,
1518 last_run: Tick,
1519 this_run: Tick,
1520 ) -> OptionFetch<'w, T> {
1521 OptionFetch {
1522 fetch: unsafe { T::init_fetch(world, state, last_run, this_run) },
1524 matches: false,
1525 }
1526 }
1527
1528 const IS_DENSE: bool = T::IS_DENSE;
1529
1530 #[inline]
1531 unsafe fn set_archetype<'w>(
1532 fetch: &mut OptionFetch<'w, T>,
1533 state: &T::State,
1534 archetype: &'w Archetype,
1535 table: &'w Table,
1536 ) {
1537 fetch.matches = T::matches_component_set(state, &|id| archetype.contains(id));
1538 if fetch.matches {
1539 unsafe {
1541 T::set_archetype(&mut fetch.fetch, state, archetype, table);
1542 }
1543 }
1544 }
1545
1546 #[inline]
1547 unsafe fn set_table<'w>(fetch: &mut OptionFetch<'w, T>, state: &T::State, table: &'w Table) {
1548 fetch.matches = T::matches_component_set(state, &|id| table.has_column(id));
1549 if fetch.matches {
1550 unsafe {
1552 T::set_table(&mut fetch.fetch, state, table);
1553 }
1554 }
1555 }
1556
1557 #[inline(always)]
1558 unsafe fn fetch<'w>(
1559 fetch: &mut Self::Fetch<'w>,
1560 entity: Entity,
1561 table_row: TableRow,
1562 ) -> Self::Item<'w> {
1563 fetch
1564 .matches
1565 .then(|| unsafe { T::fetch(&mut fetch.fetch, entity, table_row) })
1567 }
1568
1569 fn update_component_access(state: &T::State, access: &mut FilteredAccess<ComponentId>) {
1570 let mut intermediate = access.clone();
1580 T::update_component_access(state, &mut intermediate);
1581 access.extend_access(&intermediate);
1582 }
1583
1584 fn init_state(world: &mut World) -> T::State {
1585 T::init_state(world)
1586 }
1587
1588 fn get_state(components: &Components) -> Option<Self::State> {
1589 T::get_state(components)
1590 }
1591
1592 fn matches_component_set(
1593 _state: &T::State,
1594 _set_contains_id: &impl Fn(ComponentId) -> bool,
1595 ) -> bool {
1596 true
1597 }
1598}
1599
1600unsafe impl<T: QueryData> QueryData for Option<T> {
1602 type ReadOnly = Option<T::ReadOnly>;
1603}
1604
1605unsafe impl<T: ReadOnlyQueryData> ReadOnlyQueryData for Option<T> {}
1607
1608pub struct Has<T>(PhantomData<T>);
1672
1673impl<T> std::fmt::Debug for Has<T> {
1674 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
1675 write!(f, "Has<{}>", std::any::type_name::<T>())
1676 }
1677}
1678
1679unsafe impl<T: Component> WorldQuery for Has<T> {
1683 type Item<'w> = bool;
1684 type Fetch<'w> = bool;
1685 type State = ComponentId;
1686
1687 fn shrink<'wlong: 'wshort, 'wshort>(item: Self::Item<'wlong>) -> Self::Item<'wshort> {
1688 item
1689 }
1690
1691 #[inline]
1692 unsafe fn init_fetch<'w>(
1693 _world: UnsafeWorldCell<'w>,
1694 _state: &Self::State,
1695 _last_run: Tick,
1696 _this_run: Tick,
1697 ) -> Self::Fetch<'w> {
1698 false
1699 }
1700
1701 const IS_DENSE: bool = {
1702 match T::STORAGE_TYPE {
1703 StorageType::Table => true,
1704 StorageType::SparseSet => false,
1705 }
1706 };
1707
1708 #[inline]
1709 unsafe fn set_archetype<'w>(
1710 fetch: &mut Self::Fetch<'w>,
1711 state: &Self::State,
1712 archetype: &'w Archetype,
1713 _table: &Table,
1714 ) {
1715 *fetch = archetype.contains(*state);
1716 }
1717
1718 #[inline]
1719 unsafe fn set_table<'w>(fetch: &mut Self::Fetch<'w>, state: &Self::State, table: &'w Table) {
1720 *fetch = table.has_column(*state);
1721 }
1722
1723 #[inline(always)]
1724 unsafe fn fetch<'w>(
1725 fetch: &mut Self::Fetch<'w>,
1726 _entity: Entity,
1727 _table_row: TableRow,
1728 ) -> Self::Item<'w> {
1729 *fetch
1730 }
1731
1732 fn update_component_access(
1733 &component_id: &Self::State,
1734 access: &mut FilteredAccess<ComponentId>,
1735 ) {
1736 access.access_mut().add_archetypal(component_id);
1737 }
1738
1739 fn init_state(world: &mut World) -> ComponentId {
1740 world.init_component::<T>()
1741 }
1742
1743 fn get_state(components: &Components) -> Option<Self::State> {
1744 components.component_id::<T>()
1745 }
1746
1747 fn matches_component_set(
1748 _state: &Self::State,
1749 _set_contains_id: &impl Fn(ComponentId) -> bool,
1750 ) -> bool {
1751 true
1753 }
1754}
1755
1756unsafe impl<T: Component> QueryData for Has<T> {
1758 type ReadOnly = Self;
1759}
1760
1761unsafe impl<T: Component> ReadOnlyQueryData for Has<T> {}
1763
1764pub struct AnyOf<T>(PhantomData<T>);
1770
1771macro_rules! impl_tuple_query_data {
1772 ($(($name: ident, $state: ident)),*) => {
1773
1774 #[allow(non_snake_case)]
1775 #[allow(clippy::unused_unit)]
1776 unsafe impl<$($name: QueryData),*> QueryData for ($($name,)*) {
1778 type ReadOnly = ($($name::ReadOnly,)*);
1779 }
1780
1781 unsafe impl<$($name: ReadOnlyQueryData),*> ReadOnlyQueryData for ($($name,)*) {}
1783
1784 };
1785}
1786
1787macro_rules! impl_anytuple_fetch {
1788 ($(($name: ident, $state: ident)),*) => {
1789
1790 #[allow(non_snake_case)]
1791 #[allow(clippy::unused_unit)]
1792 unsafe impl<$($name: WorldQuery),*> WorldQuery for AnyOf<($($name,)*)> {
1798 type Fetch<'w> = ($(($name::Fetch<'w>, bool),)*);
1799 type Item<'w> = ($(Option<$name::Item<'w>>,)*);
1800 type State = ($($name::State,)*);
1801
1802 fn shrink<'wlong: 'wshort, 'wshort>(item: Self::Item<'wlong>) -> Self::Item<'wshort> {
1803 let ($($name,)*) = item;
1804 ($(
1805 $name.map($name::shrink),
1806 )*)
1807 }
1808
1809 #[inline]
1810 #[allow(clippy::unused_unit)]
1811 unsafe fn init_fetch<'w>(_world: UnsafeWorldCell<'w>, state: &Self::State, _last_run: Tick, _this_run: Tick) -> Self::Fetch<'w> {
1812 let ($($name,)*) = state;
1813 ($(( unsafe { $name::init_fetch(_world, $name, _last_run, _this_run) }, false),)*)
1815 }
1816
1817 const IS_DENSE: bool = true $(&& $name::IS_DENSE)*;
1818
1819 #[inline]
1820 unsafe fn set_archetype<'w>(
1821 _fetch: &mut Self::Fetch<'w>,
1822 _state: &Self::State,
1823 _archetype: &'w Archetype,
1824 _table: &'w Table
1825 ) {
1826 let ($($name,)*) = _fetch;
1827 let ($($state,)*) = _state;
1828 $(
1829 $name.1 = $name::matches_component_set($state, &|id| _archetype.contains(id));
1830 if $name.1 {
1831 unsafe { $name::set_archetype(&mut $name.0, $state, _archetype, _table); }
1833 }
1834 )*
1835 }
1836
1837 #[inline]
1838 unsafe fn set_table<'w>(_fetch: &mut Self::Fetch<'w>, _state: &Self::State, _table: &'w Table) {
1839 let ($($name,)*) = _fetch;
1840 let ($($state,)*) = _state;
1841 $(
1842 $name.1 = $name::matches_component_set($state, &|id| _table.has_column(id));
1843 if $name.1 {
1844 unsafe { $name::set_table(&mut $name.0, $state, _table); }
1846 }
1847 )*
1848 }
1849
1850 #[inline(always)]
1851 #[allow(clippy::unused_unit)]
1852 unsafe fn fetch<'w>(
1853 _fetch: &mut Self::Fetch<'w>,
1854 _entity: Entity,
1855 _table_row: TableRow
1856 ) -> Self::Item<'w> {
1857 let ($($name,)*) = _fetch;
1858 ($(
1859 $name.1.then(|| unsafe { $name::fetch(&mut $name.0, _entity, _table_row) }),
1861 )*)
1862 }
1863
1864 fn update_component_access(state: &Self::State, _access: &mut FilteredAccess<ComponentId>) {
1865 let mut _new_access = _access.clone();
1866
1867 let ($($name,)*) = state;
1869 let mut _not_first = false;
1870 $(
1871 if _not_first {
1872 let mut intermediate = _access.clone();
1874 $name::update_component_access($name, &mut intermediate);
1875 _new_access.append_or(&intermediate);
1876 } else {
1877 $name::update_component_access($name, &mut _new_access);
1878 _new_access.required = _access.required.clone();
1879 _not_first = true;
1880 }
1881 )*
1882
1883 _access.filter_sets = _new_access.filter_sets;
1884
1885 <($(Option<$name>,)*)>::update_component_access(state, _access);
1888
1889 }
1890 #[allow(unused_variables)]
1891 fn init_state(world: &mut World) -> Self::State {
1892 ($($name::init_state(world),)*)
1893 }
1894 #[allow(unused_variables)]
1895 fn get_state(components: &Components) -> Option<Self::State> {
1896 Some(($($name::get_state(components)?,)*))
1897 }
1898
1899 fn matches_component_set(_state: &Self::State, _set_contains_id: &impl Fn(ComponentId) -> bool) -> bool {
1900 let ($($name,)*) = _state;
1901 false $(|| $name::matches_component_set($name, _set_contains_id))*
1902 }
1903 }
1904
1905 #[allow(non_snake_case)]
1906 #[allow(clippy::unused_unit)]
1907 unsafe impl<$($name: QueryData),*> QueryData for AnyOf<($($name,)*)> {
1909 type ReadOnly = AnyOf<($($name::ReadOnly,)*)>;
1910 }
1911
1912 unsafe impl<$($name: ReadOnlyQueryData),*> ReadOnlyQueryData for AnyOf<($($name,)*)> {}
1914 };
1915}
1916
1917all_tuples!(impl_tuple_query_data, 0, 15, F, S);
1918all_tuples!(impl_anytuple_fetch, 0, 15, F, S);
1919
1920pub(crate) struct NopWorldQuery<D: QueryData>(PhantomData<D>);
1924
1925unsafe impl<D: QueryData> WorldQuery for NopWorldQuery<D> {
1929 type Item<'w> = ();
1930 type Fetch<'w> = ();
1931 type State = D::State;
1932
1933 fn shrink<'wlong: 'wshort, 'wshort>(_: ()) {}
1934
1935 #[inline(always)]
1936 unsafe fn init_fetch(
1937 _world: UnsafeWorldCell,
1938 _state: &D::State,
1939 _last_run: Tick,
1940 _this_run: Tick,
1941 ) {
1942 }
1943
1944 const IS_DENSE: bool = D::IS_DENSE;
1945
1946 #[inline(always)]
1947 unsafe fn set_archetype(
1948 _fetch: &mut (),
1949 _state: &D::State,
1950 _archetype: &Archetype,
1951 _tables: &Table,
1952 ) {
1953 }
1954
1955 #[inline(always)]
1956 unsafe fn set_table<'w>(_fetch: &mut (), _state: &D::State, _table: &Table) {}
1957
1958 #[inline(always)]
1959 unsafe fn fetch<'w>(
1960 _fetch: &mut Self::Fetch<'w>,
1961 _entity: Entity,
1962 _table_row: TableRow,
1963 ) -> Self::Item<'w> {
1964 }
1965
1966 fn update_component_access(_state: &D::State, _access: &mut FilteredAccess<ComponentId>) {}
1967
1968 fn init_state(world: &mut World) -> Self::State {
1969 D::init_state(world)
1970 }
1971
1972 fn get_state(components: &Components) -> Option<Self::State> {
1973 D::get_state(components)
1974 }
1975
1976 fn matches_component_set(
1977 state: &Self::State,
1978 set_contains_id: &impl Fn(ComponentId) -> bool,
1979 ) -> bool {
1980 D::matches_component_set(state, set_contains_id)
1981 }
1982}
1983
1984unsafe impl<D: QueryData> QueryData for NopWorldQuery<D> {
1986 type ReadOnly = Self;
1987}
1988
1989unsafe impl<D: QueryData> ReadOnlyQueryData for NopWorldQuery<D> {}
1991
1992unsafe impl<T: ?Sized> WorldQuery for PhantomData<T> {
1996 type Item<'a> = ();
1997 type Fetch<'a> = ();
1998
1999 type State = ();
2000
2001 fn shrink<'wlong: 'wshort, 'wshort>(_item: Self::Item<'wlong>) -> Self::Item<'wshort> {}
2002
2003 unsafe fn init_fetch<'w>(
2004 _world: UnsafeWorldCell<'w>,
2005 _state: &Self::State,
2006 _last_run: Tick,
2007 _this_run: Tick,
2008 ) -> Self::Fetch<'w> {
2009 }
2010
2011 const IS_DENSE: bool = true;
2014
2015 unsafe fn set_archetype<'w>(
2016 _fetch: &mut Self::Fetch<'w>,
2017 _state: &Self::State,
2018 _archetype: &'w Archetype,
2019 _table: &'w Table,
2020 ) {
2021 }
2022
2023 unsafe fn set_table<'w>(_fetch: &mut Self::Fetch<'w>, _state: &Self::State, _table: &'w Table) {
2024 }
2025
2026 unsafe fn fetch<'w>(
2027 _fetch: &mut Self::Fetch<'w>,
2028 _entity: Entity,
2029 _table_row: TableRow,
2030 ) -> Self::Item<'w> {
2031 }
2032
2033 fn update_component_access(_state: &Self::State, _access: &mut FilteredAccess<ComponentId>) {}
2034
2035 fn init_state(_world: &mut World) -> Self::State {}
2036
2037 fn get_state(_components: &Components) -> Option<Self::State> {
2038 Some(())
2039 }
2040
2041 fn matches_component_set(
2042 _state: &Self::State,
2043 _set_contains_id: &impl Fn(ComponentId) -> bool,
2044 ) -> bool {
2045 true
2046 }
2047}
2048
2049unsafe impl<T: ?Sized> QueryData for PhantomData<T> {
2051 type ReadOnly = Self;
2052}
2053
2054unsafe impl<T: ?Sized> ReadOnlyQueryData for PhantomData<T> {}
2056
2057#[cfg(test)]
2058mod tests {
2059 use bevy_ecs_macros::QueryData;
2060
2061 use super::*;
2062 use crate::{
2063 self as bevy_ecs,
2064 system::{assert_is_system, Query},
2065 };
2066
2067 #[derive(Component)]
2068 pub struct A;
2069
2070 #[derive(Component)]
2071 pub struct B;
2072
2073 #[test]
2075 fn world_query_struct_variants() {
2076 #[derive(QueryData)]
2077 pub struct NamedQuery {
2078 id: Entity,
2079 a: &'static A,
2080 }
2081
2082 #[derive(QueryData)]
2083 pub struct TupleQuery(&'static A, &'static B);
2084
2085 #[derive(QueryData)]
2086 pub struct UnitQuery;
2087
2088 fn my_system(_: Query<(NamedQuery, TupleQuery, UnitQuery)>) {}
2089
2090 assert_is_system(my_system);
2091 }
2092
2093 #[test]
2095 fn world_query_phantom_data() {
2096 #[derive(QueryData)]
2097 pub struct IgnoredQuery<Marker> {
2098 id: Entity,
2099 _marker: PhantomData<Marker>,
2100 }
2101
2102 fn ignored_system(_: Query<IgnoredQuery<()>>) {}
2103
2104 assert_is_system(ignored_system);
2105 }
2106
2107 #[test]
2110 fn read_only_field_visibility() {
2111 mod private {
2112 use super::*;
2113
2114 #[derive(QueryData)]
2115 #[query_data(mutable)]
2116 pub struct D {
2117 pub a: &'static mut A,
2118 }
2119 }
2120
2121 let _ = private::DReadOnly { a: &A };
2122
2123 fn my_system(query: Query<private::D>) {
2124 for q in &query {
2125 let _ = &q.a;
2126 }
2127 }
2128
2129 assert_is_system(my_system);
2130 }
2131
2132 #[test]
2136 fn world_query_metadata_collision() {
2137 #[derive(QueryData)]
2140 pub struct Client<S: ClientState> {
2141 pub state: &'static S,
2142 pub fetch: &'static ClientFetch,
2143 }
2144
2145 pub trait ClientState: Component {}
2146
2147 #[derive(Component)]
2148 pub struct ClientFetch;
2149
2150 #[derive(Component)]
2151 pub struct C;
2152
2153 impl ClientState for C {}
2154
2155 fn client_system(_: Query<Client<C>>) {}
2156
2157 assert_is_system(client_system);
2158 }
2159}