15
15
bevy_ptr:: ThinSlicePtr ,
16
16
core:: { cell:: UnsafeCell , panic:: Location } ,
17
17
} ;
18
+ use crate :: storage:: { ParallelChanges , EntityChange } ;
18
19
19
20
/// The (arbitrarily chosen) minimum number of world tick increments between `check_tick` scans.
20
21
///
@@ -387,6 +388,7 @@ macro_rules! impl_methods {
387
388
/// <T>`, but you need a `Mut<T>`.
388
389
pub fn reborrow( & mut self ) -> Mut <' _, $target> {
389
390
Mut {
391
+ on_change: self . on_change,
390
392
value: self . value,
391
393
ticks: TicksMut {
392
394
added: self . ticks. added,
@@ -423,6 +425,7 @@ macro_rules! impl_methods {
423
425
/// ```
424
426
pub fn map_unchanged<U : ?Sized >( self , f: impl FnOnce ( & mut $target) -> & mut U ) -> Mut <' w, U > {
425
427
Mut {
428
+ on_change: self . on_change,
426
429
value: f( self . value) ,
427
430
ticks: self . ticks,
428
431
#[ cfg( feature = "track_change_detection" ) ]
@@ -437,6 +440,7 @@ macro_rules! impl_methods {
437
440
pub fn filter_map_unchanged<U : ?Sized >( self , f: impl FnOnce ( & mut $target) -> Option <& mut U >) -> Option <Mut <' w, U >> {
438
441
let value = f( self . value) ;
439
442
value. map( |value| Mut {
443
+ on_change: self . on_change,
440
444
value,
441
445
ticks: self . ticks,
442
446
#[ cfg( feature = "track_change_detection" ) ]
@@ -659,22 +663,31 @@ where
659
663
660
664
change_detection_impl ! ( ResMut <' w, T >, T , Resource ) ;
661
665
change_detection_mut_impl ! ( ResMut <' w, T >, T , Resource ) ;
662
- impl_methods ! ( ResMut <' w, T >, T , Resource ) ;
666
+ // impl_methods!(ResMut<'w, T>, T, Resource);
663
667
impl_debug ! ( ResMut <' w, T >, Resource ) ;
664
668
665
- impl < ' w , T : Resource > From < ResMut < ' w , T > > for Mut < ' w , T > {
666
- /// Convert this `ResMut` into a `Mut`. This allows keeping the change-detection feature of `Mut`
667
- /// while losing the specificity of `ResMut` for resources.
668
- fn from ( other : ResMut < ' w , T > ) -> Mut < ' w , T > {
669
- Mut {
670
- value : other. value ,
671
- ticks : other. ticks ,
672
- #[ cfg( feature = "track_change_detection" ) ]
673
- changed_by : other. changed_by ,
674
- }
669
+ impl < ' w , T : ?Sized + Resource > ResMut < ' w , T > {
670
+
671
+ /// TODO
672
+ pub fn into_inner ( mut self ) -> & ' w mut T {
673
+ self . set_changed ( ) ;
674
+ self . value
675
675
}
676
676
}
677
677
678
+ // impl<'w, T: Resource> From<ResMut<'w, T>> for Mut<'w, T> {
679
+ // /// Convert this `ResMut` into a `Mut`. This allows keeping the change-detection feature of `Mut`
680
+ // /// while losing the specificity of `ResMut` for resources.
681
+ // fn from(other: ResMut<'w, T>) -> Mut<'w, T> {
682
+ // Mut {
683
+ // value: other.value,
684
+ // ticks: other.ticks,
685
+ // #[cfg(feature = "track_change_detection")]
686
+ // changed_by: other.changed_by,
687
+ // }
688
+ // }
689
+ // }
690
+
678
691
/// Unique borrow of a non-[`Send`] resource.
679
692
///
680
693
/// Only [`Send`] resources may be accessed with the [`ResMut`] [`SystemParam`](crate::system::SystemParam). In case that the
@@ -695,21 +708,21 @@ pub struct NonSendMut<'w, T: ?Sized + 'static> {
695
708
696
709
change_detection_impl ! ( NonSendMut <' w, T >, T , ) ;
697
710
change_detection_mut_impl ! ( NonSendMut <' w, T >, T , ) ;
698
- impl_methods ! ( NonSendMut <' w, T >, T , ) ;
711
+ // impl_methods!(NonSendMut<'w, T>, T,);
699
712
impl_debug ! ( NonSendMut <' w, T >, ) ;
700
713
701
- impl < ' w , T : ' static > From < NonSendMut < ' w , T > > for Mut < ' w , T > {
702
- /// Convert this `NonSendMut` into a `Mut`. This allows keeping the change-detection feature of `Mut`
703
- /// while losing the specificity of `NonSendMut`.
704
- fn from ( other : NonSendMut < ' w , T > ) -> Mut < ' w , T > {
705
- Mut {
706
- value : other. value ,
707
- ticks : other. ticks ,
708
- #[ cfg( feature = "track_change_detection" ) ]
709
- changed_by : other. changed_by ,
710
- }
711
- }
712
- }
714
+ // impl<'w, T: 'static> From<NonSendMut<'w, T>> for Mut<'w, T> {
715
+ // /// Convert this `NonSendMut` into a `Mut`. This allows keeping the change-detection feature of `Mut`
716
+ // /// while losing the specificity of `NonSendMut`.
717
+ // fn from(other: NonSendMut<'w, T>) -> Mut<'w, T> {
718
+ // Mut {
719
+ // value: other.value,
720
+ // ticks: other.ticks,
721
+ // #[cfg(feature = "track_change_detection")]
722
+ // changed_by: other.changed_by,
723
+ // }
724
+ // }
725
+ // }
713
726
714
727
/// Shared borrow of an entity's component with access to change detection.
715
728
/// Similar to [`Mut`] but is immutable and so doesn't require unique access.
@@ -869,6 +882,7 @@ impl_debug!(Ref<'w, T>,);
869
882
/// # fn update_player_position(player: &Player, new_position: Position) {}
870
883
/// ```
871
884
pub struct Mut < ' w , T : ?Sized > {
885
+ pub ( crate ) on_change : Option < ( EntityChange , & ' w ParallelChanges ) > ,
872
886
pub ( crate ) value : & ' w mut T ,
873
887
pub ( crate ) ticks : TicksMut < ' w > ,
874
888
#[ cfg( feature = "track_change_detection" ) ]
@@ -900,6 +914,7 @@ impl<'w, T: ?Sized> Mut<'w, T> {
900
914
#[ cfg( feature = "track_change_detection" ) ] caller : & ' w mut & ' static Location < ' static > ,
901
915
) -> Self {
902
916
Self {
917
+ on_change : None ,
903
918
value,
904
919
ticks : TicksMut {
905
920
added,
@@ -949,8 +964,58 @@ where
949
964
}
950
965
}
951
966
967
+ impl < ' w , T : ?Sized > DetectChangesMut for Mut < ' w , T > {
968
+ type Inner = T ;
969
+ #[ inline]
970
+ #[ track_caller]
971
+ fn set_changed ( & mut self ) {
972
+ * self . ticks . changed = self . ticks . this_run ;
973
+ if let Some ( ( change, changes) ) = self . on_change {
974
+ changes. push ( change) ;
975
+ }
976
+ #[ cfg( feature = "track_change_detection" ) ]
977
+ {
978
+ * self . changed_by = Location :: caller ( ) ;
979
+ }
980
+ }
981
+ #[ inline]
982
+ #[ track_caller]
983
+ fn set_last_changed ( & mut self , last_changed : Tick ) {
984
+ * self . ticks . changed = last_changed;
985
+ #[ cfg( feature = "track_change_detection" ) ]
986
+ {
987
+ * self . changed_by = Location :: caller ( ) ;
988
+ }
989
+ }
990
+
991
+ #[ inline]
992
+ fn bypass_change_detection ( & mut self ) -> & mut Self :: Inner {
993
+ self . value
994
+ }
995
+ }
996
+
997
+ impl < ' w , T : ?Sized > DerefMut for Mut < ' w , T > {
998
+ #[ inline]
999
+ #[ track_caller]
1000
+ fn deref_mut ( & mut self ) -> & mut Self :: Target {
1001
+ self . set_changed ( ) ;
1002
+ #[ cfg( feature = "track_change_detection" ) ]
1003
+ {
1004
+ * self . changed_by = Location :: caller ( ) ;
1005
+ }
1006
+ self . value
1007
+ }
1008
+ }
1009
+
1010
+ impl < ' w , T : ?Sized > AsMut < T > for Mut < ' w , T > {
1011
+ #[ inline]
1012
+ fn as_mut ( & mut self ) -> & mut T {
1013
+ self . deref_mut ( )
1014
+ }
1015
+ }
1016
+
952
1017
change_detection_impl ! ( Mut <' w, T >, T , ) ;
953
- change_detection_mut_impl ! ( Mut <' w, T >, T , ) ;
1018
+ // change_detection_mut_impl!(Mut<'w, T>, T,);
954
1019
impl_methods ! ( Mut <' w, T >, T , ) ;
955
1020
impl_debug ! ( Mut <' w, T >, ) ;
956
1021
@@ -1041,6 +1106,7 @@ impl<'w> MutUntyped<'w> {
1041
1106
/// ```
1042
1107
pub fn map_unchanged < T : ?Sized > ( self , f : impl FnOnce ( PtrMut < ' w > ) -> & ' w mut T ) -> Mut < ' w , T > {
1043
1108
Mut {
1109
+ on_change : None , // TODO
1044
1110
value : f ( self . value ) ,
1045
1111
ticks : self . ticks ,
1046
1112
#[ cfg( feature = "track_change_detection" ) ]
@@ -1054,6 +1120,7 @@ impl<'w> MutUntyped<'w> {
1054
1120
/// - `T` must be the erased pointee type for this [`MutUntyped`].
1055
1121
pub unsafe fn with_type < T > ( self ) -> Mut < ' w , T > {
1056
1122
Mut {
1123
+ on_change : None ,
1057
1124
// SAFETY: `value` is `Aligned` and caller ensures the pointee type is `T`.
1058
1125
value : unsafe { self . value . deref_mut ( ) } ,
1059
1126
ticks : self . ticks ,
@@ -1423,6 +1490,7 @@ mod tests {
1423
1490
let mut caller = Location :: caller ( ) ;
1424
1491
1425
1492
let ptr = Mut {
1493
+ on_change : None ,
1426
1494
value : & mut outer,
1427
1495
ticks,
1428
1496
#[ cfg( feature = "track_change_detection" ) ]
@@ -1551,6 +1619,7 @@ mod tests {
1551
1619
let mut caller = Location :: caller ( ) ;
1552
1620
1553
1621
let mut_typed = Mut {
1622
+ on_change : None ,
1554
1623
value : & mut c,
1555
1624
ticks,
1556
1625
#[ cfg( feature = "track_change_detection" ) ]
0 commit comments