Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bevyengine
GitHub Repository: bevyengine/bevy
Path: blob/main/crates/bevy_ecs/src/system/schedule_system.rs
9394 views
1
use bevy_utils::prelude::DebugName;
2
3
use 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
11
use super::{IntoSystem, SystemParamValidationError, SystemStateFlags};
12
13
/// See [`IntoSystem::with_input`] for details.
14
pub struct WithInputWrapper<S, T>
15
where
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
23
impl<S, T> WithInputWrapper<S, T>
24
where
25
for<'i> S: System<In: SystemInput<Inner<'i> = &'i mut T>>,
26
T: Send + Sync + 'static,
27
{
28
/// Wraps the given system with the given input value.
29
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
/// Returns a reference to the input value.
37
pub fn value(&self) -> &T {
38
&self.value
39
}
40
41
/// Returns a mutable reference to the input value.
42
pub fn value_mut(&mut self) -> &mut T {
43
&mut self.value
44
}
45
}
46
47
impl<S, T> System for WithInputWrapper<S, T>
48
where
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
// SAFETY: Upheld by caller
70
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
// SAFETY: Upheld by caller
92
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
112
/// Constructed in [`IntoSystem::with_input_from`].
113
pub struct WithInputFromWrapper<S, T> {
114
system: S,
115
value: Option<T>,
116
}
117
118
impl<S, T> WithInputFromWrapper<S, T>
119
where
120
for<'i> S: System<In: SystemInput<Inner<'i> = &'i mut T>>,
121
T: Send + Sync + 'static,
122
{
123
/// Wraps the given system.
124
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
/// Returns a reference to the input value, if it has been initialized.
132
pub fn value(&self) -> Option<&T> {
133
self.value.as_ref()
134
}
135
136
/// Returns a mutable reference to the input value, if it has been initialized.
137
pub fn value_mut(&mut self) -> Option<&mut T> {
138
self.value.as_mut()
139
}
140
}
141
142
impl<S, T> System for WithInputFromWrapper<S, T>
143
where
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
// SAFETY: Upheld by caller
169
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
// SAFETY: Upheld by caller
191
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
214
/// Type alias for a `BoxedSystem` that a `Schedule` can store.
215
pub type ScheduleSystem = BoxedSystem<(), ()>;
216
217