bevy_ecs/system/
schedule_system.rs1use bevy_utils::prelude::DebugName;
2
3use crate::{
4 component::{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 self.system.run_unsafe(&mut self.value, world)
70 }
71
72 #[cfg(feature = "hotpatching")]
73 #[inline]
74 fn refresh_hotpatch(&mut self) {
75 self.system.refresh_hotpatch();
76 }
77
78 fn apply_deferred(&mut self, world: &mut World) {
79 self.system.apply_deferred(world);
80 }
81
82 fn queue_deferred(&mut self, world: DeferredWorld) {
83 self.system.queue_deferred(world);
84 }
85
86 unsafe fn validate_param_unsafe(
87 &mut self,
88 world: UnsafeWorldCell,
89 ) -> Result<(), SystemParamValidationError> {
90 self.system.validate_param_unsafe(world)
91 }
92
93 fn initialize(&mut self, world: &mut World) -> FilteredAccessSet {
94 self.system.initialize(world)
95 }
96
97 fn check_change_tick(&mut self, check: CheckChangeTicks) {
98 self.system.check_change_tick(check);
99 }
100
101 fn get_last_run(&self) -> Tick {
102 self.system.get_last_run()
103 }
104
105 fn set_last_run(&mut self, last_run: Tick) {
106 self.system.set_last_run(last_run);
107 }
108}
109
110pub struct WithInputFromWrapper<S, T> {
112 system: S,
113 value: Option<T>,
114}
115
116impl<S, T> WithInputFromWrapper<S, T>
117where
118 for<'i> S: System<In: SystemInput<Inner<'i> = &'i mut T>>,
119 T: Send + Sync + 'static,
120{
121 pub fn new<M>(system: impl IntoSystem<S::In, S::Out, M, System = S>) -> Self {
123 Self {
124 system: IntoSystem::into_system(system),
125 value: None,
126 }
127 }
128
129 pub fn value(&self) -> Option<&T> {
131 self.value.as_ref()
132 }
133
134 pub fn value_mut(&mut self) -> Option<&mut T> {
136 self.value.as_mut()
137 }
138}
139
140impl<S, T> System for WithInputFromWrapper<S, T>
141where
142 for<'i> S: System<In: SystemInput<Inner<'i> = &'i mut T>>,
143 T: FromWorld + Send + Sync + 'static,
144{
145 type In = ();
146 type Out = S::Out;
147
148 fn name(&self) -> DebugName {
149 self.system.name()
150 }
151
152 #[inline]
153 fn flags(&self) -> SystemStateFlags {
154 self.system.flags()
155 }
156
157 unsafe fn run_unsafe(
158 &mut self,
159 _input: SystemIn<'_, Self>,
160 world: UnsafeWorldCell,
161 ) -> Result<Self::Out, RunSystemError> {
162 let value = self
163 .value
164 .as_mut()
165 .expect("System input value was not found. Did you forget to initialize the system before running it?");
166 self.system.run_unsafe(value, world)
167 }
168
169 #[cfg(feature = "hotpatching")]
170 #[inline]
171 fn refresh_hotpatch(&mut self) {
172 self.system.refresh_hotpatch();
173 }
174
175 fn apply_deferred(&mut self, world: &mut World) {
176 self.system.apply_deferred(world);
177 }
178
179 fn queue_deferred(&mut self, world: DeferredWorld) {
180 self.system.queue_deferred(world);
181 }
182
183 unsafe fn validate_param_unsafe(
184 &mut self,
185 world: UnsafeWorldCell,
186 ) -> Result<(), SystemParamValidationError> {
187 self.system.validate_param_unsafe(world)
188 }
189
190 fn initialize(&mut self, world: &mut World) -> FilteredAccessSet {
191 if self.value.is_none() {
192 self.value = Some(T::from_world(world));
193 }
194 self.system.initialize(world)
195 }
196
197 fn check_change_tick(&mut self, check: CheckChangeTicks) {
198 self.system.check_change_tick(check);
199 }
200
201 fn get_last_run(&self) -> Tick {
202 self.system.get_last_run()
203 }
204
205 fn set_last_run(&mut self, last_run: Tick) {
206 self.system.set_last_run(last_run);
207 }
208}
209
210pub type ScheduleSystem = BoxedSystem<(), ()>;