bevy_render/
extract_param.rs1use crate::MainWorld;
2use bevy_ecs::{
3 component::Tick,
4 prelude::*,
5 query::FilteredAccessSet,
6 system::{
7 ReadOnlySystemParam, SystemMeta, SystemParam, SystemParamItem, SystemParamValidationError,
8 SystemState,
9 },
10 world::unsafe_world_cell::UnsafeWorldCell,
11};
12use core::ops::{Deref, DerefMut};
13
14pub struct Extract<'w, 's, P>
51where
52 P: ReadOnlySystemParam + 'static,
53{
54 item: SystemParamItem<'w, 's, P>,
55}
56
57#[doc(hidden)]
58pub struct ExtractState<P: SystemParam + 'static> {
59 state: SystemState<P>,
60 main_world_state: <Res<'static, MainWorld> as SystemParam>::State,
61}
62
63unsafe impl<P> ReadOnlySystemParam for Extract<'_, '_, P> where P: ReadOnlySystemParam {}
65
66unsafe impl<P> SystemParam for Extract<'_, '_, P>
69where
70 P: ReadOnlySystemParam,
71{
72 type State = ExtractState<P>;
73 type Item<'w, 's> = Extract<'w, 's, P>;
74
75 fn init_state(world: &mut World) -> Self::State {
76 let mut main_world = world.resource_mut::<MainWorld>();
77 ExtractState {
78 state: SystemState::new(&mut main_world),
79 main_world_state: Res::<MainWorld>::init_state(world),
80 }
81 }
82
83 fn init_access(
84 state: &Self::State,
85 system_meta: &mut SystemMeta,
86 component_access_set: &mut FilteredAccessSet,
87 world: &mut World,
88 ) {
89 Res::<MainWorld>::init_access(
90 &state.main_world_state,
91 system_meta,
92 component_access_set,
93 world,
94 );
95 }
96
97 #[inline]
98 unsafe fn validate_param(
99 state: &mut Self::State,
100 _system_meta: &SystemMeta,
101 world: UnsafeWorldCell,
102 ) -> Result<(), SystemParamValidationError> {
103 let result = unsafe { world.get_resource_by_id(state.main_world_state) };
105 let Some(main_world) = result else {
106 return Err(SystemParamValidationError::invalid::<Self>(
107 "`MainWorld` resource does not exist",
108 ));
109 };
110 let main_world: &World = unsafe { main_world.deref() };
112 unsafe {
114 SystemState::<P>::validate_param(
115 &mut state.state,
116 main_world.as_unsafe_world_cell_readonly(),
117 )
118 }
119 }
120
121 #[inline]
122 unsafe fn get_param<'w, 's>(
123 state: &'s mut Self::State,
124 system_meta: &SystemMeta,
125 world: UnsafeWorldCell<'w>,
126 change_tick: Tick,
127 ) -> Self::Item<'w, 's> {
128 let main_world = unsafe {
132 Res::<MainWorld>::get_param(
133 &mut state.main_world_state,
134 system_meta,
135 world,
136 change_tick,
137 )
138 };
139 let item = state.state.get(main_world.into_inner());
140 Extract { item }
141 }
142}
143
144impl<'w, 's, P> Deref for Extract<'w, 's, P>
145where
146 P: ReadOnlySystemParam,
147{
148 type Target = SystemParamItem<'w, 's, P>;
149
150 #[inline]
151 fn deref(&self) -> &Self::Target {
152 &self.item
153 }
154}
155
156impl<'w, 's, P> DerefMut for Extract<'w, 's, P>
157where
158 P: ReadOnlySystemParam,
159{
160 #[inline]
161 fn deref_mut(&mut self) -> &mut Self::Target {
162 &mut self.item
163 }
164}
165
166impl<'a, 'w, 's, P> IntoIterator for &'a Extract<'w, 's, P>
167where
168 P: ReadOnlySystemParam,
169 &'a SystemParamItem<'w, 's, P>: IntoIterator,
170{
171 type Item = <&'a SystemParamItem<'w, 's, P> as IntoIterator>::Item;
172 type IntoIter = <&'a SystemParamItem<'w, 's, P> as IntoIterator>::IntoIter;
173
174 fn into_iter(self) -> Self::IntoIter {
175 (&self.item).into_iter()
176 }
177}