bevy_ecs/system/
schedule_system.rs1use bevy_utils::prelude::DebugName;
2
3use crate::{
4 change_detection::{CheckChangeTicks, Tick},
5 error::Result,
6 query::FilteredAccessSet,
7 system::{input::SystemIn, BoxedSystem, RunSystemError, System, SystemInput},
8 world::{unsafe_world_cell::UnsafeWorldCell, DeferredWorld, FromWorld, World},
9};
10
11use super::{IntoSystem, SystemParamValidationError, SystemStateFlags};
12
13pub struct WithInputWrapper<S, T>
15where
16 for<'i> S: System<In: SystemInput<Inner<'i> = &'i mut T>>,
17 T: Send + Sync + 'static,
18{
19 system: S,
20 value: T,
21}
22
23impl<S, T> WithInputWrapper<S, T>
24where
25 for<'i> S: System<In: SystemInput<Inner<'i> = &'i mut T>>,
26 T: Send + Sync + 'static,
27{
28 pub fn new<M>(system: impl IntoSystem<S::In, S::Out, M, System = S>, value: T) -> Self {
30 Self {
31 system: IntoSystem::into_system(system),
32 value,
33 }
34 }
35
36 pub fn value(&self) -> &T {
38 &self.value
39 }
40
41 pub fn value_mut(&mut self) -> &mut T {
43 &mut self.value
44 }
45}
46
47impl<S, T> System for WithInputWrapper<S, T>
48where
49 for<'i> S: System<In: SystemInput<Inner<'i> = &'i mut T>>,
50 T: Send + Sync + 'static,
51{
52 type In = ();
53 type Out = S::Out;
54
55 fn name(&self) -> DebugName {
56 self.system.name()
57 }
58
59 #[inline]
60 fn flags(&self) -> SystemStateFlags {
61 self.system.flags()
62 }
63
64 unsafe fn run_unsafe(
65 &mut self,
66 _input: SystemIn<'_, Self>,
67 world: UnsafeWorldCell,
68 ) -> Result<Self::Out, RunSystemError> {
69 unsafe { self.system.run_unsafe(&mut self.value, world) }
71 }
72
73 #[cfg(feature = "hotpatching")]
74 #[inline]
75 fn refresh_hotpatch(&mut self) {
76 self.system.refresh_hotpatch();
77 }
78
79 fn apply_deferred(&mut self, world: &mut World) {
80 self.system.apply_deferred(world);
81 }
82
83 fn queue_deferred(&mut self, world: DeferredWorld) {
84 self.system.queue_deferred(world);
85 }
86
87 unsafe fn validate_param_unsafe(
88 &mut self,
89 world: UnsafeWorldCell,
90 ) -> Result<(), SystemParamValidationError> {
91 unsafe { self.system.validate_param_unsafe(world) }
93 }
94
95 fn initialize(&mut self, world: &mut World) -> FilteredAccessSet {
96 self.system.initialize(world)
97 }
98
99 fn check_change_tick(&mut self, check: CheckChangeTicks) {
100 self.system.check_change_tick(check);
101 }
102
103 fn get_last_run(&self) -> Tick {
104 self.system.get_last_run()
105 }
106
107 fn set_last_run(&mut self, last_run: Tick) {
108 self.system.set_last_run(last_run);
109 }
110}
111
112pub struct WithInputFromWrapper<S, T> {
114 system: S,
115 value: Option<T>,
116}
117
118impl<S, T> WithInputFromWrapper<S, T>
119where
120 for<'i> S: System<In: SystemInput<Inner<'i> = &'i mut T>>,
121 T: Send + Sync + 'static,
122{
123 pub fn new<M>(system: impl IntoSystem<S::In, S::Out, M, System = S>) -> Self {
125 Self {
126 system: IntoSystem::into_system(system),
127 value: None,
128 }
129 }
130
131 pub fn value(&self) -> Option<&T> {
133 self.value.as_ref()
134 }
135
136 pub fn value_mut(&mut self) -> Option<&mut T> {
138 self.value.as_mut()
139 }
140}
141
142impl<S, T> System for WithInputFromWrapper<S, T>
143where
144 for<'i> S: System<In: SystemInput<Inner<'i> = &'i mut T>>,
145 T: FromWorld + Send + Sync + 'static,
146{
147 type In = ();
148 type Out = S::Out;
149
150 fn name(&self) -> DebugName {
151 self.system.name()
152 }
153
154 #[inline]
155 fn flags(&self) -> SystemStateFlags {
156 self.system.flags()
157 }
158
159 unsafe fn run_unsafe(
160 &mut self,
161 _input: SystemIn<'_, Self>,
162 world: UnsafeWorldCell,
163 ) -> Result<Self::Out, RunSystemError> {
164 let value = self
165 .value
166 .as_mut()
167 .expect("System input value was not found. Did you forget to initialize the system before running it?");
168 unsafe { self.system.run_unsafe(value, world) }
170 }
171
172 #[cfg(feature = "hotpatching")]
173 #[inline]
174 fn refresh_hotpatch(&mut self) {
175 self.system.refresh_hotpatch();
176 }
177
178 fn apply_deferred(&mut self, world: &mut World) {
179 self.system.apply_deferred(world);
180 }
181
182 fn queue_deferred(&mut self, world: DeferredWorld) {
183 self.system.queue_deferred(world);
184 }
185
186 unsafe fn validate_param_unsafe(
187 &mut self,
188 world: UnsafeWorldCell,
189 ) -> Result<(), SystemParamValidationError> {
190 unsafe { self.system.validate_param_unsafe(world) }
192 }
193
194 fn initialize(&mut self, world: &mut World) -> FilteredAccessSet {
195 if self.value.is_none() {
196 self.value = Some(T::from_world(world));
197 }
198 self.system.initialize(world)
199 }
200
201 fn check_change_tick(&mut self, check: CheckChangeTicks) {
202 self.system.check_change_tick(check);
203 }
204
205 fn get_last_run(&self) -> Tick {
206 self.system.get_last_run()
207 }
208
209 fn set_last_run(&mut self, last_run: Tick) {
210 self.system.set_last_run(last_run);
211 }
212}
213
214pub type ScheduleSystem = BoxedSystem<(), ()>;