@@ -477,87 +477,12 @@ unsafe impl<'a, D: QueryData + 'static, F: QueryFilter + 'static> SystemParam fo
477477 }
478478}
479479
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-
549480// SAFETY: QueryState is constrained to read-only fetches, so it only reads World.
550481unsafe impl < ' a , D : ReadOnlyQueryData + ' static , F : QueryFilter + ' static > ReadOnlySystemParam
551482 for Single < ' a , D , F >
552483{
553484}
554485
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-
561486// SAFETY: Relevant query ComponentId and ArchetypeComponentId access is applied to SystemMeta. If
562487// this Query conflicts with any prior access, a panic will occur.
563488unsafe impl < D : QueryData + ' static , F : QueryFilter + ' static > SystemParam
@@ -931,40 +856,6 @@ unsafe impl<'a, T: Resource> SystemParam for Res<'a, T> {
931856 }
932857}
933858
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-
968859// SAFETY: Res ComponentId and ArchetypeComponentId access is applied to SystemMeta. If this Res
969860// conflicts with any prior access, a panic will occur.
970861unsafe impl < ' a , T : Resource > SystemParam for ResMut < ' a , T > {
@@ -1045,37 +936,6 @@ unsafe impl<'a, T: Resource> SystemParam for ResMut<'a, T> {
1045936 }
1046937}
1047938
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-
1079939/// SAFETY: only reads world
1080940unsafe impl < ' w > ReadOnlySystemParam for & ' w World { }
1081941
@@ -1644,37 +1504,6 @@ unsafe impl<'a, T: 'static> SystemParam for NonSend<'a, T> {
16441504 }
16451505}
16461506
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-
16781507// SAFETY: NonSendMut ComponentId and ArchetypeComponentId access is applied to SystemMeta. If this
16791508// NonSendMut conflicts with any prior access, a panic will occur.
16801509unsafe impl < ' a , T : ' static > SystemParam for NonSendMut < ' a , T > {
@@ -1753,32 +1582,6 @@ unsafe impl<'a, T: 'static> SystemParam for NonSendMut<'a, T> {
17531582 }
17541583}
17551584
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-
17821585// SAFETY: Only reads World archetypes
17831586unsafe impl < ' a > ReadOnlySystemParam for & ' a Archetypes { }
17841587
@@ -1916,6 +1719,91 @@ unsafe impl SystemParam for SystemChangeTick {
19161719 }
19171720}
19181721
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+
19191807/// A [`SystemParam`] that wraps another parameter and causes its system to skip instead of failing when the parameter is invalid.
19201808///
19211809/// # Example
0 commit comments