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