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