@@ -477,87 +477,12 @@ unsafe impl<'a, D: QueryData + 'static, F: QueryFilter + 'static> SystemParam fo
477
477
}
478
478
}
479
479
480
- // SAFETY: Relevant query ComponentId and ArchetypeComponentId access is applied to SystemMeta. If
481
- // this Query conflicts with any prior access, a panic will occur.
482
- unsafe impl < ' a , D : QueryData + ' static , F : QueryFilter + ' static > SystemParam
483
- for Option < Single < ' a , D , F > >
484
- {
485
- type State = QueryState < D , F > ;
486
- type Item < ' w , ' s > = Option < Single < ' w , D , F > > ;
487
-
488
- fn init_state ( world : & mut World , system_meta : & mut SystemMeta ) -> Self :: State {
489
- Single :: init_state ( world, system_meta)
490
- }
491
-
492
- unsafe fn new_archetype (
493
- state : & mut Self :: State ,
494
- archetype : & Archetype ,
495
- system_meta : & mut SystemMeta ,
496
- ) {
497
- // SAFETY: Delegate to existing `SystemParam` implementations.
498
- unsafe { Single :: new_archetype ( state, archetype, system_meta) } ;
499
- }
500
-
501
- #[ inline]
502
- unsafe fn get_param < ' w , ' s > (
503
- state : & ' s mut Self :: State ,
504
- system_meta : & SystemMeta ,
505
- world : UnsafeWorldCell < ' w > ,
506
- change_tick : Tick ,
507
- ) -> Self :: Item < ' w , ' s > {
508
- state. validate_world ( world. id ( ) ) ;
509
- // SAFETY: State ensures that the components it accesses are not accessible elsewhere.
510
- // The caller ensures the world matches the one used in init_state.
511
- let query = unsafe {
512
- state. query_unchecked_manual_with_ticks ( world, system_meta. last_run , change_tick)
513
- } ;
514
- match query. single_inner ( ) {
515
- Ok ( single) => Some ( Single {
516
- item : single,
517
- _filter : PhantomData ,
518
- } ) ,
519
- Err ( QuerySingleError :: NoEntities ( _) ) => None ,
520
- Err ( QuerySingleError :: MultipleEntities ( e) ) => panic ! ( "{}" , e) ,
521
- }
522
- }
523
-
524
- #[ inline]
525
- unsafe fn validate_param (
526
- state : & Self :: State ,
527
- system_meta : & SystemMeta ,
528
- world : UnsafeWorldCell ,
529
- ) -> Result < ( ) , SystemParamValidationError > {
530
- // SAFETY: State ensures that the components it accesses are not mutably accessible elsewhere
531
- // and the query is read only.
532
- // The caller ensures the world matches the one used in init_state.
533
- let query = unsafe {
534
- state. query_unchecked_manual_with_ticks (
535
- world,
536
- system_meta. last_run ,
537
- world. change_tick ( ) ,
538
- )
539
- } ;
540
- match query. single_inner ( ) {
541
- Ok ( _) | Err ( QuerySingleError :: NoEntities ( _) ) => Ok ( ( ) ) ,
542
- Err ( QuerySingleError :: MultipleEntities ( _) ) => Err (
543
- SystemParamValidationError :: skipped :: < Self > ( "Multiple matching entities" ) ,
544
- ) ,
545
- }
546
- }
547
- }
548
-
549
480
// SAFETY: QueryState is constrained to read-only fetches, so it only reads World.
550
481
unsafe impl < ' a , D : ReadOnlyQueryData + ' static , F : QueryFilter + ' static > ReadOnlySystemParam
551
482
for Single < ' a , D , F >
552
483
{
553
484
}
554
485
555
- // SAFETY: QueryState is constrained to read-only fetches, so it only reads World.
556
- unsafe impl < ' a , D : ReadOnlyQueryData + ' static , F : QueryFilter + ' static > ReadOnlySystemParam
557
- for Option < Single < ' a , D , F > >
558
- {
559
- }
560
-
561
486
// SAFETY: Relevant query ComponentId and ArchetypeComponentId access is applied to SystemMeta. If
562
487
// this Query conflicts with any prior access, a panic will occur.
563
488
unsafe impl < D : QueryData + ' static , F : QueryFilter + ' static > SystemParam
@@ -931,40 +856,6 @@ unsafe impl<'a, T: Resource> SystemParam for Res<'a, T> {
931
856
}
932
857
}
933
858
934
- // SAFETY: Only reads a single World resource
935
- unsafe impl < ' a , T : Resource > ReadOnlySystemParam for Option < Res < ' a , T > > { }
936
-
937
- // SAFETY: this impl defers to `Res`, which initializes and validates the correct world access.
938
- unsafe impl < ' a , T : Resource > SystemParam for Option < Res < ' a , T > > {
939
- type State = ComponentId ;
940
- type Item < ' w , ' s > = Option < Res < ' w , T > > ;
941
-
942
- fn init_state ( world : & mut World , system_meta : & mut SystemMeta ) -> Self :: State {
943
- Res :: < T > :: init_state ( world, system_meta)
944
- }
945
-
946
- #[ inline]
947
- unsafe fn get_param < ' w , ' s > (
948
- & mut component_id: & ' s mut Self :: State ,
949
- system_meta : & SystemMeta ,
950
- world : UnsafeWorldCell < ' w > ,
951
- change_tick : Tick ,
952
- ) -> Self :: Item < ' w , ' s > {
953
- world
954
- . get_resource_with_ticks ( component_id)
955
- . map ( |( ptr, ticks, caller) | Res {
956
- value : ptr. deref ( ) ,
957
- ticks : Ticks {
958
- added : ticks. added . deref ( ) ,
959
- changed : ticks. changed . deref ( ) ,
960
- last_run : system_meta. last_run ,
961
- this_run : change_tick,
962
- } ,
963
- changed_by : caller. map ( |caller| caller. deref ( ) ) ,
964
- } )
965
- }
966
- }
967
-
968
859
// SAFETY: Res ComponentId and ArchetypeComponentId access is applied to SystemMeta. If this Res
969
860
// conflicts with any prior access, a panic will occur.
970
861
unsafe impl < ' a , T : Resource > SystemParam for ResMut < ' a , T > {
@@ -1045,37 +936,6 @@ unsafe impl<'a, T: Resource> SystemParam for ResMut<'a, T> {
1045
936
}
1046
937
}
1047
938
1048
- // SAFETY: this impl defers to `ResMut`, which initializes and validates the correct world access.
1049
- unsafe impl < ' a , T : Resource > SystemParam for Option < ResMut < ' a , T > > {
1050
- type State = ComponentId ;
1051
- type Item < ' w , ' s > = Option < ResMut < ' w , T > > ;
1052
-
1053
- fn init_state ( world : & mut World , system_meta : & mut SystemMeta ) -> Self :: State {
1054
- ResMut :: < T > :: init_state ( world, system_meta)
1055
- }
1056
-
1057
- #[ inline]
1058
- unsafe fn get_param < ' w , ' s > (
1059
- & mut component_id: & ' s mut Self :: State ,
1060
- system_meta : & SystemMeta ,
1061
- world : UnsafeWorldCell < ' w > ,
1062
- change_tick : Tick ,
1063
- ) -> Self :: Item < ' w , ' s > {
1064
- world
1065
- . get_resource_mut_by_id ( component_id)
1066
- . map ( |value| ResMut {
1067
- value : value. value . deref_mut :: < T > ( ) ,
1068
- ticks : TicksMut {
1069
- added : value. ticks . added ,
1070
- changed : value. ticks . changed ,
1071
- last_run : system_meta. last_run ,
1072
- this_run : change_tick,
1073
- } ,
1074
- changed_by : value. changed_by ,
1075
- } )
1076
- }
1077
- }
1078
-
1079
939
/// SAFETY: only reads world
1080
940
unsafe impl < ' w > ReadOnlySystemParam for & ' w World { }
1081
941
@@ -1644,37 +1504,6 @@ unsafe impl<'a, T: 'static> SystemParam for NonSend<'a, T> {
1644
1504
}
1645
1505
}
1646
1506
1647
- // SAFETY: Only reads a single World non-send resource
1648
- unsafe impl < T : ' static > ReadOnlySystemParam for Option < NonSend < ' _ , T > > { }
1649
-
1650
- // SAFETY: this impl defers to `NonSend`, which initializes and validates the correct world access.
1651
- unsafe impl < T : ' static > SystemParam for Option < NonSend < ' _ , T > > {
1652
- type State = ComponentId ;
1653
- type Item < ' w , ' s > = Option < NonSend < ' w , T > > ;
1654
-
1655
- fn init_state ( world : & mut World , system_meta : & mut SystemMeta ) -> Self :: State {
1656
- NonSend :: < T > :: init_state ( world, system_meta)
1657
- }
1658
-
1659
- #[ inline]
1660
- unsafe fn get_param < ' w , ' s > (
1661
- & mut component_id: & ' s mut Self :: State ,
1662
- system_meta : & SystemMeta ,
1663
- world : UnsafeWorldCell < ' w > ,
1664
- change_tick : Tick ,
1665
- ) -> Self :: Item < ' w , ' s > {
1666
- world
1667
- . get_non_send_with_ticks ( component_id)
1668
- . map ( |( ptr, ticks, caller) | NonSend {
1669
- value : ptr. deref ( ) ,
1670
- ticks : ticks. read ( ) ,
1671
- last_run : system_meta. last_run ,
1672
- this_run : change_tick,
1673
- changed_by : caller. map ( |caller| caller. deref ( ) ) ,
1674
- } )
1675
- }
1676
- }
1677
-
1678
1507
// SAFETY: NonSendMut ComponentId and ArchetypeComponentId access is applied to SystemMeta. If this
1679
1508
// NonSendMut conflicts with any prior access, a panic will occur.
1680
1509
unsafe impl < ' a , T : ' static > SystemParam for NonSendMut < ' a , T > {
@@ -1753,32 +1582,6 @@ unsafe impl<'a, T: 'static> SystemParam for NonSendMut<'a, T> {
1753
1582
}
1754
1583
}
1755
1584
1756
- // SAFETY: this impl defers to `NonSendMut`, which initializes and validates the correct world access.
1757
- unsafe impl < ' a , T : ' static > SystemParam for Option < NonSendMut < ' a , T > > {
1758
- type State = ComponentId ;
1759
- type Item < ' w , ' s > = Option < NonSendMut < ' w , T > > ;
1760
-
1761
- fn init_state ( world : & mut World , system_meta : & mut SystemMeta ) -> Self :: State {
1762
- NonSendMut :: < T > :: init_state ( world, system_meta)
1763
- }
1764
-
1765
- #[ inline]
1766
- unsafe fn get_param < ' w , ' s > (
1767
- & mut component_id: & ' s mut Self :: State ,
1768
- system_meta : & SystemMeta ,
1769
- world : UnsafeWorldCell < ' w > ,
1770
- change_tick : Tick ,
1771
- ) -> Self :: Item < ' w , ' s > {
1772
- world
1773
- . get_non_send_with_ticks ( component_id)
1774
- . map ( |( ptr, ticks, caller) | NonSendMut {
1775
- value : ptr. assert_unique ( ) . deref_mut ( ) ,
1776
- ticks : TicksMut :: from_tick_cells ( ticks, system_meta. last_run , change_tick) ,
1777
- changed_by : caller. map ( |caller| caller. deref_mut ( ) ) ,
1778
- } )
1779
- }
1780
- }
1781
-
1782
1585
// SAFETY: Only reads World archetypes
1783
1586
unsafe impl < ' a > ReadOnlySystemParam for & ' a Archetypes { }
1784
1587
@@ -1916,6 +1719,91 @@ unsafe impl SystemParam for SystemChangeTick {
1916
1719
}
1917
1720
}
1918
1721
1722
+ // SAFETY: Delegates to `T`, which ensures the safety requirements are met
1723
+ unsafe impl < T : SystemParam > SystemParam for Option < T > {
1724
+ type State = T :: State ;
1725
+
1726
+ type Item < ' world , ' state > = Option < T :: Item < ' world , ' state > > ;
1727
+
1728
+ fn init_state ( world : & mut World , system_meta : & mut SystemMeta ) -> Self :: State {
1729
+ T :: init_state ( world, system_meta)
1730
+ }
1731
+
1732
+ #[ inline]
1733
+ unsafe fn get_param < ' world , ' state > (
1734
+ state : & ' state mut Self :: State ,
1735
+ system_meta : & SystemMeta ,
1736
+ world : UnsafeWorldCell < ' world > ,
1737
+ change_tick : Tick ,
1738
+ ) -> Self :: Item < ' world , ' state > {
1739
+ T :: validate_param ( state, system_meta, world)
1740
+ . ok ( )
1741
+ . map ( |( ) | T :: get_param ( state, system_meta, world, change_tick) )
1742
+ }
1743
+
1744
+ unsafe fn new_archetype (
1745
+ state : & mut Self :: State ,
1746
+ archetype : & Archetype ,
1747
+ system_meta : & mut SystemMeta ,
1748
+ ) {
1749
+ // SAFETY: The caller ensures that `archetype` is from the World the state was initialized from in `init_state`.
1750
+ unsafe { T :: new_archetype ( state, archetype, system_meta) } ;
1751
+ }
1752
+
1753
+ fn apply ( state : & mut Self :: State , system_meta : & SystemMeta , world : & mut World ) {
1754
+ T :: apply ( state, system_meta, world) ;
1755
+ }
1756
+
1757
+ fn queue ( state : & mut Self :: State , system_meta : & SystemMeta , world : DeferredWorld ) {
1758
+ T :: queue ( state, system_meta, world) ;
1759
+ }
1760
+ }
1761
+
1762
+ // SAFETY: Delegates to `T`, which ensures the safety requirements are met
1763
+ unsafe impl < T : ReadOnlySystemParam > ReadOnlySystemParam for Option < T > { }
1764
+
1765
+ // SAFETY: Delegates to `T`, which ensures the safety requirements are met
1766
+ unsafe impl < T : SystemParam > SystemParam for Result < T , SystemParamValidationError > {
1767
+ type State = T :: State ;
1768
+
1769
+ type Item < ' world , ' state > = Result < T :: Item < ' world , ' state > , SystemParamValidationError > ;
1770
+
1771
+ fn init_state ( world : & mut World , system_meta : & mut SystemMeta ) -> Self :: State {
1772
+ T :: init_state ( world, system_meta)
1773
+ }
1774
+
1775
+ #[ inline]
1776
+ unsafe fn get_param < ' world , ' state > (
1777
+ state : & ' state mut Self :: State ,
1778
+ system_meta : & SystemMeta ,
1779
+ world : UnsafeWorldCell < ' world > ,
1780
+ change_tick : Tick ,
1781
+ ) -> Self :: Item < ' world , ' state > {
1782
+ T :: validate_param ( state, system_meta, world)
1783
+ . map ( |( ) | T :: get_param ( state, system_meta, world, change_tick) )
1784
+ }
1785
+
1786
+ unsafe fn new_archetype (
1787
+ state : & mut Self :: State ,
1788
+ archetype : & Archetype ,
1789
+ system_meta : & mut SystemMeta ,
1790
+ ) {
1791
+ // SAFETY: The caller ensures that `archetype` is from the World the state was initialized from in `init_state`.
1792
+ unsafe { T :: new_archetype ( state, archetype, system_meta) } ;
1793
+ }
1794
+
1795
+ fn apply ( state : & mut Self :: State , system_meta : & SystemMeta , world : & mut World ) {
1796
+ T :: apply ( state, system_meta, world) ;
1797
+ }
1798
+
1799
+ fn queue ( state : & mut Self :: State , system_meta : & SystemMeta , world : DeferredWorld ) {
1800
+ T :: queue ( state, system_meta, world) ;
1801
+ }
1802
+ }
1803
+
1804
+ // SAFETY: Delegates to `T`, which ensures the safety requirements are met
1805
+ unsafe impl < T : ReadOnlySystemParam > ReadOnlySystemParam for Result < T , SystemParamValidationError > { }
1806
+
1919
1807
/// A [`SystemParam`] that wraps another parameter and causes its system to skip instead of failing when the parameter is invalid.
1920
1808
///
1921
1809
/// # Example
0 commit comments