bevy_extract/
extract_param.rs1use crate::MainWorld;
2use bevy_ecs::{
3 change_detection::Tick,
4 prelude::*,
5 system::{
6 ReadOnlySystemParam, SystemAccess, SystemMeta, SystemParam, SystemParamItem,
7 SystemParamValidationError, SystemState,
8 },
9 world::unsafe_world_cell::UnsafeWorldCell,
10};
11use core::ops::{Deref, DerefMut};
12
13pub struct Extract<'w, 's, P>
52where
53 P: ReadOnlySystemParam + 'static,
54{
55 item: SystemParamItem<'w, 's, P>,
56}
57
58#[doc(hidden)]
59pub struct ExtractState<P: SystemParam + 'static> {
60 state: SystemState<P>,
61 main_world_state: <Res<'static, MainWorld> as SystemParam>::State,
62}
63
64unsafe impl<P> ReadOnlySystemParam for Extract<'_, '_, P> where P: ReadOnlySystemParam {}
66
67unsafe impl<P> SystemParam for Extract<'_, '_, P>
70where
71 P: ReadOnlySystemParam,
72{
73 type State = ExtractState<P>;
74 type Item<'w, 's> = Extract<'w, 's, P>;
75
76 fn init_state(world: &mut World) -> Self::State {
77 let mut main_world = world.resource_mut::<MainWorld>();
78 ExtractState {
79 state: SystemState::new(&mut main_world),
80 main_world_state: Res::<MainWorld>::init_state(world),
81 }
82 }
83
84 fn init_access(
85 state: &Self::State,
86 system_meta: &mut SystemMeta,
87 system_access: &mut SystemAccess,
88 world: &mut World,
89 ) {
90 Res::<MainWorld>::init_access(&state.main_world_state, system_meta, system_access, world);
91 }
92
93 #[inline]
94 unsafe fn get_param<'w, 's>(
95 state: &'s mut Self::State,
96 system_meta: &SystemMeta,
97 world: UnsafeWorldCell<'w>,
98 change_tick: Tick,
99 ) -> Result<Self::Item<'w, 's>, SystemParamValidationError> {
100 let main_world = unsafe {
104 Res::<MainWorld>::get_param(
105 &mut state.main_world_state,
106 system_meta,
107 world,
108 change_tick,
109 )?
110 };
111 let item = state.state.get(main_world.into_inner())?;
112 Ok(Extract { item })
113 }
114}
115
116impl<'w, 's, P> Deref for Extract<'w, 's, P>
117where
118 P: ReadOnlySystemParam,
119{
120 type Target = SystemParamItem<'w, 's, P>;
121
122 #[inline]
123 fn deref(&self) -> &Self::Target {
124 &self.item
125 }
126}
127
128impl<'w, 's, P> DerefMut for Extract<'w, 's, P>
129where
130 P: ReadOnlySystemParam,
131{
132 #[inline]
133 fn deref_mut(&mut self) -> &mut Self::Target {
134 &mut self.item
135 }
136}
137
138impl<'a, 'w, 's, P> IntoIterator for &'a Extract<'w, 's, P>
139where
140 P: ReadOnlySystemParam,
141 &'a SystemParamItem<'w, 's, P>: IntoIterator,
142{
143 type Item = <&'a SystemParamItem<'w, 's, P> as IntoIterator>::Item;
144 type IntoIter = <&'a SystemParamItem<'w, 's, P> as IntoIterator>::IntoIter;
145
146 fn into_iter(self) -> Self::IntoIter {
147 (&self.item).into_iter()
148 }
149}