bevy_render/
extract_param.rs1use crate::MainWorld;
2use bevy_ecs::{
3 change_detection::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 get_param<'w, 's>(
99 state: &'s mut Self::State,
100 system_meta: &SystemMeta,
101 world: UnsafeWorldCell<'w>,
102 change_tick: Tick,
103 ) -> Result<Self::Item<'w, 's>, SystemParamValidationError> {
104 let main_world = unsafe {
108 Res::<MainWorld>::get_param(
109 &mut state.main_world_state,
110 system_meta,
111 world,
112 change_tick,
113 )?
114 };
115 let item = state.state.get(main_world.into_inner())?;
116 Ok(Extract { item })
117 }
118}
119
120impl<'w, 's, P> Deref for Extract<'w, 's, P>
121where
122 P: ReadOnlySystemParam,
123{
124 type Target = SystemParamItem<'w, 's, P>;
125
126 #[inline]
127 fn deref(&self) -> &Self::Target {
128 &self.item
129 }
130}
131
132impl<'w, 's, P> DerefMut for Extract<'w, 's, P>
133where
134 P: ReadOnlySystemParam,
135{
136 #[inline]
137 fn deref_mut(&mut self) -> &mut Self::Target {
138 &mut self.item
139 }
140}
141
142impl<'a, 'w, 's, P> IntoIterator for &'a Extract<'w, 's, P>
143where
144 P: ReadOnlySystemParam,
145 &'a SystemParamItem<'w, 's, P>: IntoIterator,
146{
147 type Item = <&'a SystemParamItem<'w, 's, P> as IntoIterator>::Item;
148 type IntoIter = <&'a SystemParamItem<'w, 's, P> as IntoIterator>::IntoIter;
149
150 fn into_iter(self) -> Self::IntoIter {
151 (&self.item).into_iter()
152 }
153}