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 std::ops::{Deref, DerefMut};
9
10pub struct Extract<'w, 's, P>
45where
46 P: ReadOnlySystemParam + 'static,
47{
48 item: SystemParamItem<'w, 's, P>,
49}
50
51#[doc(hidden)]
52pub struct ExtractState<P: SystemParam + 'static> {
53 state: SystemState<P>,
54 main_world_state: <Res<'static, MainWorld> as SystemParam>::State,
55}
56
57unsafe impl<P> ReadOnlySystemParam for Extract<'_, '_, P> where P: ReadOnlySystemParam {}
59
60unsafe impl<P> SystemParam for Extract<'_, '_, P>
63where
64 P: ReadOnlySystemParam,
65{
66 type State = ExtractState<P>;
67 type Item<'w, 's> = Extract<'w, 's, P>;
68
69 fn init_state(world: &mut World, system_meta: &mut SystemMeta) -> Self::State {
70 let mut main_world = world.resource_mut::<MainWorld>();
71 ExtractState {
72 state: SystemState::new(&mut main_world),
73 main_world_state: Res::<MainWorld>::init_state(world, system_meta),
74 }
75 }
76
77 unsafe fn get_param<'w, 's>(
78 state: &'s mut Self::State,
79 system_meta: &SystemMeta,
80 world: UnsafeWorldCell<'w>,
81 change_tick: Tick,
82 ) -> Self::Item<'w, 's> {
83 let main_world = unsafe {
87 Res::<MainWorld>::get_param(
88 &mut state.main_world_state,
89 system_meta,
90 world,
91 change_tick,
92 )
93 };
94 let item = state.state.get(main_world.into_inner());
95 Extract { item }
96 }
97}
98
99impl<'w, 's, P> Deref for Extract<'w, 's, P>
100where
101 P: ReadOnlySystemParam,
102{
103 type Target = SystemParamItem<'w, 's, P>;
104
105 #[inline]
106 fn deref(&self) -> &Self::Target {
107 &self.item
108 }
109}
110
111impl<'w, 's, P> DerefMut for Extract<'w, 's, P>
112where
113 P: ReadOnlySystemParam,
114{
115 #[inline]
116 fn deref_mut(&mut self) -> &mut Self::Target {
117 &mut self.item
118 }
119}
120
121impl<'a, 'w, 's, P> IntoIterator for &'a Extract<'w, 's, P>
122where
123 P: ReadOnlySystemParam,
124 &'a SystemParamItem<'w, 's, P>: IntoIterator,
125{
126 type Item = <&'a SystemParamItem<'w, 's, P> as IntoIterator>::Item;
127 type IntoIter = <&'a SystemParamItem<'w, 's, P> as IntoIterator>::IntoIter;
128
129 fn into_iter(self) -> Self::IntoIter {
130 (&self.item).into_iter()
131 }
132}