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
6604 views
1
use bevy_utils::prelude::DebugName;
2
3
use 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
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
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
110
/// Constructed in [`IntoSystem::with_input_from`].
111
pub struct WithInputFromWrapper<S, T> {
112
system: S,
113
value: Option<T>,
114
}
115
116
impl<S, T> WithInputFromWrapper<S, T>
117
where
118
for<'i> S: System<In: SystemInput<Inner<'i> = &'i mut T>>,
119
T: Send + Sync + 'static,
120
{
121
/// Wraps the given system.
122
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
/// Returns a reference to the input value, if it has been initialized.
130
pub fn value(&self) -> Option<&T> {
131
self.value.as_ref()
132
}
133
134
/// Returns a mutable reference to the input value, if it has been initialized.
135
pub fn value_mut(&mut self) -> Option<&mut T> {
136
self.value.as_mut()
137
}
138
}
139
140
impl<S, T> System for WithInputFromWrapper<S, T>
141
where
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
210
/// Type alias for a `BoxedSystem` that a `Schedule` can store.
211
pub type ScheduleSystem = BoxedSystem<(), ()>;
212
213