1
1
use crate :: {
2
2
archetype:: { Archetype , ArchetypeComponentId } ,
3
- change_detection:: Ticks ,
3
+ change_detection:: { Ticks , TicksMut } ,
4
4
component:: { Component , ComponentId , ComponentStorage , ComponentTicks , StorageType , Tick } ,
5
5
entity:: Entity ,
6
6
query:: { Access , DebugCheckedUnwrap , FilteredAccess } ,
7
7
storage:: { ComponentSparseSet , Table , TableRow } ,
8
- world:: { Mut , World } ,
8
+ world:: { Mut , Ref , World } ,
9
9
} ;
10
10
use bevy_ecs_macros:: all_tuples;
11
11
pub use bevy_ecs_macros:: WorldQuery ;
@@ -653,6 +653,167 @@ unsafe impl<T: Component> WorldQuery for &T {
653
653
/// SAFETY: access is read only
654
654
unsafe impl < T : Component > ReadOnlyWorldQuery for & T { }
655
655
656
+ #[ doc( hidden) ]
657
+ pub struct RefFetch < ' w , T > {
658
+ // T::Storage = TableStorage
659
+ table_data : Option < (
660
+ ThinSlicePtr < ' w , UnsafeCell < T > > ,
661
+ ThinSlicePtr < ' w , UnsafeCell < Tick > > ,
662
+ ThinSlicePtr < ' w , UnsafeCell < Tick > > ,
663
+ ) > ,
664
+ // T::Storage = SparseStorage
665
+ sparse_set : Option < & ' w ComponentSparseSet > ,
666
+
667
+ last_change_tick : u32 ,
668
+ change_tick : u32 ,
669
+ }
670
+
671
+ /// SAFETY: `Self` is the same as `Self::ReadOnly`
672
+ unsafe impl < ' __w , T : Component > WorldQuery for Ref < ' __w , T > {
673
+ type Fetch < ' w > = RefFetch < ' w , T > ;
674
+ type Item < ' w > = Ref < ' w , T > ;
675
+ type ReadOnly = Self ;
676
+ type State = ComponentId ;
677
+
678
+ fn shrink < ' wlong : ' wshort , ' wshort > ( item : Ref < ' wlong , T > ) -> Ref < ' wshort , T > {
679
+ item
680
+ }
681
+
682
+ const IS_DENSE : bool = {
683
+ match T :: Storage :: STORAGE_TYPE {
684
+ StorageType :: Table => true ,
685
+ StorageType :: SparseSet => false ,
686
+ }
687
+ } ;
688
+
689
+ const IS_ARCHETYPAL : bool = true ;
690
+
691
+ unsafe fn init_fetch < ' w > (
692
+ world : & ' w World ,
693
+ & component_id: & ComponentId ,
694
+ last_change_tick : u32 ,
695
+ change_tick : u32 ,
696
+ ) -> RefFetch < ' w , T > {
697
+ RefFetch {
698
+ table_data : None ,
699
+ sparse_set : ( T :: Storage :: STORAGE_TYPE == StorageType :: SparseSet ) . then ( || {
700
+ world
701
+ . storages ( )
702
+ . sparse_sets
703
+ . get ( component_id)
704
+ . debug_checked_unwrap ( )
705
+ } ) ,
706
+ last_change_tick,
707
+ change_tick,
708
+ }
709
+ }
710
+
711
+ unsafe fn clone_fetch < ' w > ( fetch : & Self :: Fetch < ' w > ) -> Self :: Fetch < ' w > {
712
+ RefFetch {
713
+ table_data : fetch. table_data ,
714
+ sparse_set : fetch. sparse_set ,
715
+ last_change_tick : fetch. last_change_tick ,
716
+ change_tick : fetch. change_tick ,
717
+ }
718
+ }
719
+
720
+ #[ inline]
721
+ unsafe fn set_archetype < ' w > (
722
+ fetch : & mut RefFetch < ' w , T > ,
723
+ component_id : & ComponentId ,
724
+ _archetype : & ' w Archetype ,
725
+ table : & ' w Table ,
726
+ ) {
727
+ if Self :: IS_DENSE {
728
+ Self :: set_table ( fetch, component_id, table) ;
729
+ }
730
+ }
731
+
732
+ #[ inline]
733
+ unsafe fn set_table < ' w > (
734
+ fetch : & mut RefFetch < ' w , T > ,
735
+ & component_id: & ComponentId ,
736
+ table : & ' w Table ,
737
+ ) {
738
+ let column = table. get_column ( component_id) . debug_checked_unwrap ( ) ;
739
+ fetch. table_data = Some ( (
740
+ column. get_data_slice ( ) . into ( ) ,
741
+ column. get_added_ticks_slice ( ) . into ( ) ,
742
+ column. get_changed_ticks_slice ( ) . into ( ) ,
743
+ ) ) ;
744
+ }
745
+
746
+ #[ inline( always) ]
747
+ unsafe fn fetch < ' w > (
748
+ fetch : & mut Self :: Fetch < ' w > ,
749
+ entity : Entity ,
750
+ table_row : TableRow ,
751
+ ) -> Self :: Item < ' w > {
752
+ match T :: Storage :: STORAGE_TYPE {
753
+ StorageType :: Table => {
754
+ let ( table_components, added_ticks, changed_ticks) =
755
+ fetch. table_data . debug_checked_unwrap ( ) ;
756
+ Ref {
757
+ value : table_components. get ( table_row. index ( ) ) . deref ( ) ,
758
+ ticks : Ticks {
759
+ added : added_ticks. get ( table_row. index ( ) ) . deref ( ) ,
760
+ changed : changed_ticks. get ( table_row. index ( ) ) . deref ( ) ,
761
+ change_tick : fetch. change_tick ,
762
+ last_change_tick : fetch. last_change_tick ,
763
+ } ,
764
+ }
765
+ }
766
+ StorageType :: SparseSet => {
767
+ let ( component, ticks) = fetch
768
+ . sparse_set
769
+ . debug_checked_unwrap ( )
770
+ . get_with_ticks ( entity)
771
+ . debug_checked_unwrap ( ) ;
772
+ Ref {
773
+ value : component. deref ( ) ,
774
+ ticks : Ticks :: from_tick_cells ( ticks, fetch. last_change_tick , fetch. change_tick ) ,
775
+ }
776
+ }
777
+ }
778
+ }
779
+
780
+ fn update_component_access (
781
+ & component_id: & ComponentId ,
782
+ access : & mut FilteredAccess < ComponentId > ,
783
+ ) {
784
+ assert ! (
785
+ !access. access( ) . has_write( component_id) ,
786
+ "&{} conflicts with a previous access in this query. Shared access cannot coincide with exclusive access." ,
787
+ std:: any:: type_name:: <T >( ) ,
788
+ ) ;
789
+ access. add_read ( component_id) ;
790
+ }
791
+
792
+ fn update_archetype_component_access (
793
+ & component_id: & ComponentId ,
794
+ archetype : & Archetype ,
795
+ access : & mut Access < ArchetypeComponentId > ,
796
+ ) {
797
+ if let Some ( archetype_component_id) = archetype. get_archetype_component_id ( component_id) {
798
+ access. add_read ( archetype_component_id) ;
799
+ }
800
+ }
801
+
802
+ fn init_state ( world : & mut World ) -> ComponentId {
803
+ world. init_component :: < T > ( )
804
+ }
805
+
806
+ fn matches_component_set (
807
+ & state: & ComponentId ,
808
+ set_contains_id : & impl Fn ( ComponentId ) -> bool ,
809
+ ) -> bool {
810
+ set_contains_id ( state)
811
+ }
812
+ }
813
+
814
+ /// SAFETY: access is read only
815
+ unsafe impl < ' __w , T : Component > ReadOnlyWorldQuery for Ref < ' __w , T > { }
816
+
656
817
#[ doc( hidden) ]
657
818
pub struct WriteFetch < ' w , T > {
658
819
// T::Storage = TableStorage
@@ -755,7 +916,7 @@ unsafe impl<'__w, T: Component> WorldQuery for &'__w mut T {
755
916
fetch. table_data . debug_checked_unwrap ( ) ;
756
917
Mut {
757
918
value : table_components. get ( table_row. index ( ) ) . deref_mut ( ) ,
758
- ticks : Ticks {
919
+ ticks : TicksMut {
759
920
added : added_ticks. get ( table_row. index ( ) ) . deref_mut ( ) ,
760
921
changed : changed_ticks. get ( table_row. index ( ) ) . deref_mut ( ) ,
761
922
change_tick : fetch. change_tick ,
@@ -771,7 +932,11 @@ unsafe impl<'__w, T: Component> WorldQuery for &'__w mut T {
771
932
. debug_checked_unwrap ( ) ;
772
933
Mut {
773
934
value : component. assert_unique ( ) . deref_mut ( ) ,
774
- ticks : Ticks :: from_tick_cells ( ticks, fetch. last_change_tick , fetch. change_tick ) ,
935
+ ticks : TicksMut :: from_tick_cells (
936
+ ticks,
937
+ fetch. last_change_tick ,
938
+ fetch. change_tick ,
939
+ ) ,
775
940
}
776
941
}
777
942
}
0 commit comments