bevy_render/
extract_param.rs1use crate::MainWorld;
2use bevy_ecs::{
3 component::Tick,
4 prelude::*,
5 system::{ReadOnlySystemParam, SystemMeta, SystemParam, SystemParamItem, SystemState},
6 world::unsafe_world_cell::UnsafeWorldCell,
7};
8use core::ops::{Deref, DerefMut};
9
10pub struct Extract<'w, 's, P>
47where
48 P: ReadOnlySystemParam + 'static,
49{
50 item: SystemParamItem<'w, 's, P>,
51}
52
53#[doc(hidden)]
54pub struct ExtractState<P: SystemParam + 'static> {
55 state: SystemState<P>,
56 main_world_state: <Res<'static, MainWorld> as SystemParam>::State,
57}
58
59unsafe impl<P> ReadOnlySystemParam for Extract<'_, '_, P> where P: ReadOnlySystemParam {}
61
62unsafe impl<P> SystemParam for Extract<'_, '_, P>
65where
66 P: ReadOnlySystemParam,
67{
68 type State = ExtractState<P>;
69 type Item<'w, 's> = Extract<'w, 's, P>;
70
71 fn init_state(world: &mut World, system_meta: &mut SystemMeta) -> Self::State {
72 let mut main_world = world.resource_mut::<MainWorld>();
73 ExtractState {
74 state: SystemState::new(&mut main_world),
75 main_world_state: Res::<MainWorld>::init_state(world, system_meta),
76 }
77 }
78
79 #[inline]
80 unsafe fn validate_param(
81 state: &Self::State,
82 system_meta: &SystemMeta,
83 world: UnsafeWorldCell,
84 ) -> bool {
85 let result = unsafe { world.get_resource_by_id(state.main_world_state) };
87 let Some(main_world) = result else {
88 system_meta.try_warn_param::<&World>();
89 return false;
90 };
91 let main_world: &World = unsafe { main_world.deref() };
93 unsafe {
95 SystemState::<P>::validate_param(
96 &state.state,
97 main_world.as_unsafe_world_cell_readonly(),
98 )
99 }
100 }
101
102 #[inline]
103 unsafe fn get_param<'w, 's>(
104 state: &'s mut Self::State,
105 system_meta: &SystemMeta,
106 world: UnsafeWorldCell<'w>,
107 change_tick: Tick,
108 ) -> Self::Item<'w, 's> {
109 let main_world = unsafe {
113 Res::<MainWorld>::get_param(
114 &mut state.main_world_state,
115 system_meta,
116 world,
117 change_tick,
118 )
119 };
120 let item = state.state.get(main_world.into_inner());
121 Extract { item }
122 }
123}
124
125impl<'w, 's, P> Deref for Extract<'w, 's, P>
126where
127 P: ReadOnlySystemParam,
128{
129 type Target = SystemParamItem<'w, 's, P>;
130
131 #[inline]
132 fn deref(&self) -> &Self::Target {
133 &self.item
134 }
135}
136
137impl<'w, 's, P> DerefMut for Extract<'w, 's, P>
138where
139 P: ReadOnlySystemParam,
140{
141 #[inline]
142 fn deref_mut(&mut self) -> &mut Self::Target {
143 &mut self.item
144 }
145}
146
147impl<'a, 'w, 's, P> IntoIterator for &'a Extract<'w, 's, P>
148where
149 P: ReadOnlySystemParam,
150 &'a SystemParamItem<'w, 's, P>: IntoIterator,
151{
152 type Item = <&'a SystemParamItem<'w, 's, P> as IntoIterator>::Item;
153 type IntoIter = <&'a SystemParamItem<'w, 's, P> as IntoIterator>::IntoIter;
154
155 fn into_iter(self) -> Self::IntoIter {
156 (&self.item).into_iter()
157 }
158}