Skip to content

Commit 509b138

Browse files
authored
Schedule v2 (#1021)
Schedule V2
1 parent 61b181a commit 509b138

38 files changed

+1896
-1002
lines changed

Cargo.toml

+8
Original file line numberDiff line numberDiff line change
@@ -193,10 +193,18 @@ path = "examples/diagnostics/print_diagnostics.rs"
193193
name = "event"
194194
path = "examples/ecs/event.rs"
195195

196+
[[example]]
197+
name = "fixed_timestep"
198+
path = "examples/ecs/fixed_timestep.rs"
199+
196200
[[example]]
197201
name = "startup_system"
198202
path = "examples/ecs/startup_system.rs"
199203

204+
[[example]]
205+
name = "state"
206+
path = "examples/ecs/state.rs"
207+
200208
[[example]]
201209
name = "system_chaining"
202210
path = "examples/ecs/system_chaining.rs"

crates/bevy_app/src/app.rs

+3-29
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::app_builder::AppBuilder;
2-
use bevy_ecs::{ParallelExecutor, Resources, Schedule, World};
2+
use bevy_ecs::{Resources, Schedule, World};
33
#[cfg(feature = "trace")]
44
use bevy_utils::tracing::info_span;
55

@@ -30,9 +30,6 @@ pub struct App {
3030
pub resources: Resources,
3131
pub runner: Box<dyn Fn(App)>,
3232
pub schedule: Schedule,
33-
pub executor: ParallelExecutor,
34-
pub startup_schedule: Schedule,
35-
pub startup_executor: ParallelExecutor,
3633
}
3734

3835
impl Default for App {
@@ -41,16 +38,12 @@ impl Default for App {
4138
world: Default::default(),
4239
resources: Default::default(),
4340
schedule: Default::default(),
44-
executor: Default::default(),
45-
startup_schedule: Default::default(),
46-
startup_executor: ParallelExecutor::without_tracker_clears(),
4741
runner: Box::new(run_once),
4842
}
4943
}
5044
}
5145

5246
fn run_once(mut app: App) {
53-
app.initialize();
5447
app.update();
5548
}
5649

@@ -61,34 +54,15 @@ impl App {
6154

6255
pub fn update(&mut self) {
6356
self.schedule
64-
.initialize(&mut self.world, &mut self.resources);
65-
self.executor
66-
.run(&mut self.schedule, &mut self.world, &mut self.resources);
67-
}
68-
69-
pub fn initialize(&mut self) {
70-
#[cfg(feature = "trace")]
71-
let startup_schedule_span = info_span!("startup_schedule");
72-
#[cfg(feature = "trace")]
73-
let _startup_schedule_guard = startup_schedule_span.enter();
74-
self.startup_schedule
75-
.initialize(&mut self.world, &mut self.resources);
76-
self.startup_executor.initialize(&mut self.resources);
77-
self.startup_executor.run(
78-
&mut self.startup_schedule,
79-
&mut self.world,
80-
&mut self.resources,
81-
);
57+
.initialize_and_run(&mut self.world, &mut self.resources);
8258
}
8359

8460
pub fn run(mut self) {
8561
#[cfg(feature = "trace")]
86-
let bevy_app_run_span = info_span!("bevy_app_run");
62+
let bevy_app_run_span = info_span!("bevy_app");
8763
#[cfg(feature = "trace")]
8864
let _bevy_app_run_guard = bevy_app_run_span.enter();
8965

90-
self.executor.initialize(&mut self.resources);
91-
9266
let runner = std::mem::replace(&mut self.runner, Box::new(run_once));
9367
(runner)(self);
9468
}

crates/bevy_app/src/app_builder.rs

+131-55
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
1+
use std::any::Any;
2+
13
use crate::{
24
app::{App, AppExit},
35
event::Events,
46
plugin::Plugin,
57
stage, startup_stage, PluginGroup, PluginGroupBuilder,
68
};
7-
use bevy_ecs::{FromResources, IntoSystem, Resources, System, World};
9+
use bevy_ecs::{
10+
clear_trackers_system, FromResources, IntoStage, IntoSystem, Resource, Resources, RunOnce,
11+
Schedule, Stage, State, StateStage, System, SystemStage, World,
12+
};
813
use bevy_utils::tracing::debug;
914

1015
/// Configure [App]s using the builder pattern
@@ -18,8 +23,10 @@ impl Default for AppBuilder {
1823
app: App::default(),
1924
};
2025

21-
app_builder.add_default_stages();
22-
app_builder.add_event::<AppExit>();
26+
app_builder
27+
.add_default_stages()
28+
.add_event::<AppExit>()
29+
.add_system_to_stage(stage::LAST, clear_trackers_system);
2330
app_builder
2431
}
2532
}
@@ -49,55 +56,88 @@ impl AppBuilder {
4956
self
5057
}
5158

52-
pub fn add_stage(&mut self, stage_name: &'static str) -> &mut Self {
53-
self.app.schedule.add_stage(stage_name);
59+
pub fn add_stage<Params, S: IntoStage<Params>>(
60+
&mut self,
61+
name: &'static str,
62+
stage: S,
63+
) -> &mut Self {
64+
self.app.schedule.add_stage(name, stage);
5465
self
5566
}
5667

57-
pub fn add_stage_after(&mut self, target: &'static str, stage_name: &'static str) -> &mut Self {
58-
self.app.schedule.add_stage_after(target, stage_name);
68+
pub fn add_stage_after<Params, S: IntoStage<Params>>(
69+
&mut self,
70+
target: &'static str,
71+
name: &'static str,
72+
stage: S,
73+
) -> &mut Self {
74+
self.app.schedule.add_stage_after(target, name, stage);
5975
self
6076
}
6177

62-
pub fn add_stage_before(
78+
pub fn add_stage_before<Params, S: IntoStage<Params>>(
6379
&mut self,
6480
target: &'static str,
65-
stage_name: &'static str,
81+
name: &'static str,
82+
stage: S,
6683
) -> &mut Self {
67-
self.app.schedule.add_stage_before(target, stage_name);
84+
self.app.schedule.add_stage_before(target, name, stage);
6885
self
6986
}
7087

71-
pub fn add_startup_stage(&mut self, stage_name: &'static str) -> &mut Self {
72-
self.app.startup_schedule.add_stage(stage_name);
88+
pub fn add_startup_stage<Params, S: IntoStage<Params>>(
89+
&mut self,
90+
name: &'static str,
91+
stage: S,
92+
) -> &mut Self {
93+
self.app
94+
.schedule
95+
.stage(stage::STARTUP, |schedule: &mut Schedule| {
96+
schedule.add_stage(name, stage)
97+
});
7398
self
7499
}
75100

76-
pub fn add_startup_stage_after(
101+
pub fn add_startup_stage_after<Params, S: IntoStage<Params>>(
77102
&mut self,
78103
target: &'static str,
79-
stage_name: &'static str,
104+
name: &'static str,
105+
stage: S,
80106
) -> &mut Self {
81107
self.app
82-
.startup_schedule
83-
.add_stage_after(target, stage_name);
108+
.schedule
109+
.stage(stage::STARTUP, |schedule: &mut Schedule| {
110+
schedule.add_stage_after(target, name, stage)
111+
});
84112
self
85113
}
86114

87-
pub fn add_startup_stage_before(
115+
pub fn add_startup_stage_before<Params, S: IntoStage<Params>>(
88116
&mut self,
89117
target: &'static str,
90-
stage_name: &'static str,
118+
name: &'static str,
119+
stage: S,
91120
) -> &mut Self {
92121
self.app
93-
.startup_schedule
94-
.add_stage_before(target, stage_name);
122+
.schedule
123+
.stage(stage::STARTUP, |schedule: &mut Schedule| {
124+
schedule.add_stage_before(target, name, stage)
125+
});
126+
self
127+
}
128+
129+
pub fn stage<T: Stage, F: FnOnce(&mut T) -> &mut T>(
130+
&mut self,
131+
name: &str,
132+
func: F,
133+
) -> &mut Self {
134+
self.app.schedule.stage(name, func);
95135
self
96136
}
97137

98138
pub fn add_system<S, Params, IntoS>(&mut self, system: IntoS) -> &mut Self
99139
where
100-
S: System<Input = (), Output = ()>,
140+
S: System<In = (), Out = ()>,
101141
IntoS: IntoSystem<Params, S>,
102142
{
103143
self.add_system_to_stage(stage::UPDATE, system)
@@ -109,37 +149,41 @@ impl AppBuilder {
109149
system: IntoS,
110150
) -> &mut Self
111151
where
112-
S: System<Input = (), Output = ()>,
152+
S: System<In = (), Out = ()>,
113153
IntoS: IntoSystem<Params, S>,
114154
{
115155
self.app
116-
.startup_schedule
117-
.add_system_to_stage(stage_name, system);
156+
.schedule
157+
.stage(stage::STARTUP, |schedule: &mut Schedule| {
158+
schedule.add_system_to_stage(stage_name, system)
159+
});
118160
self
119161
}
120162

121163
pub fn add_startup_system<S, Params, IntoS>(&mut self, system: IntoS) -> &mut Self
122164
where
123-
S: System<Input = (), Output = ()>,
165+
S: System<In = (), Out = ()>,
124166
IntoS: IntoSystem<Params, S>,
125167
{
126-
self.app
127-
.startup_schedule
128-
.add_system_to_stage(startup_stage::STARTUP, system);
129-
self
168+
self.add_startup_system_to_stage(startup_stage::STARTUP, system)
130169
}
131170

132171
pub fn add_default_stages(&mut self) -> &mut Self {
133-
self.add_startup_stage(startup_stage::PRE_STARTUP)
134-
.add_startup_stage(startup_stage::STARTUP)
135-
.add_startup_stage(startup_stage::POST_STARTUP)
136-
.add_stage(stage::FIRST)
137-
.add_stage(stage::PRE_EVENT)
138-
.add_stage(stage::EVENT)
139-
.add_stage(stage::PRE_UPDATE)
140-
.add_stage(stage::UPDATE)
141-
.add_stage(stage::POST_UPDATE)
142-
.add_stage(stage::LAST)
172+
self.add_stage(
173+
stage::STARTUP,
174+
Schedule::default()
175+
.with_run_criteria(RunOnce::default())
176+
.with_stage(startup_stage::PRE_STARTUP, SystemStage::parallel())
177+
.with_stage(startup_stage::STARTUP, SystemStage::parallel())
178+
.with_stage(startup_stage::POST_STARTUP, SystemStage::parallel()),
179+
)
180+
.add_stage(stage::FIRST, SystemStage::parallel())
181+
.add_stage(stage::PRE_EVENT, SystemStage::parallel())
182+
.add_stage(stage::EVENT, SystemStage::parallel())
183+
.add_stage(stage::PRE_UPDATE, SystemStage::parallel())
184+
.add_stage(stage::UPDATE, SystemStage::parallel())
185+
.add_stage(stage::POST_UPDATE, SystemStage::parallel())
186+
.add_stage(stage::LAST, SystemStage::parallel())
143187
}
144188

145189
pub fn add_system_to_stage<S, Params, IntoS>(
@@ -148,28 +192,13 @@ impl AppBuilder {
148192
system: IntoS,
149193
) -> &mut Self
150194
where
151-
S: System<Input = (), Output = ()>,
195+
S: System<In = (), Out = ()>,
152196
IntoS: IntoSystem<Params, S>,
153197
{
154198
self.app.schedule.add_system_to_stage(stage_name, system);
155199
self
156200
}
157201

158-
pub fn add_system_to_stage_front<S, Params, IntoS>(
159-
&mut self,
160-
stage_name: &'static str,
161-
system: IntoS,
162-
) -> &mut Self
163-
where
164-
S: System<Input = (), Output = ()>,
165-
IntoS: IntoSystem<Params, S>,
166-
{
167-
self.app
168-
.schedule
169-
.add_system_to_stage_front(stage_name, system.system());
170-
self
171-
}
172-
173202
pub fn add_event<T>(&mut self) -> &mut Self
174203
where
175204
T: Send + Sync + 'static,
@@ -178,6 +207,53 @@ impl AppBuilder {
178207
.add_system_to_stage(stage::EVENT, Events::<T>::update_system)
179208
}
180209

210+
pub fn state_stage_name<T: Any>() -> String {
211+
format!("state({})", std::any::type_name::<T>())
212+
}
213+
214+
pub fn add_state<T: Clone + Resource>(&mut self, initial: T) -> &mut Self {
215+
self.add_resource(State::new(initial));
216+
self.app.schedule.add_stage_after(
217+
stage::UPDATE,
218+
&Self::state_stage_name::<T>(),
219+
StateStage::<T>::default(),
220+
);
221+
self
222+
}
223+
224+
pub fn on_state_enter<T: Clone + Resource, Params, S: IntoStage<Params>>(
225+
&mut self,
226+
value: T,
227+
stage: S,
228+
) -> &mut Self {
229+
self.stage(
230+
&Self::state_stage_name::<T>(),
231+
|state_stage: &mut StateStage<T>| state_stage.on_state_enter(value, stage),
232+
)
233+
}
234+
235+
pub fn on_state_update<T: Clone + Resource, Params, S: IntoStage<Params>>(
236+
&mut self,
237+
value: T,
238+
stage: S,
239+
) -> &mut Self {
240+
self.stage(
241+
&Self::state_stage_name::<T>(),
242+
|state_stage: &mut StateStage<T>| state_stage.on_state_update(value, stage),
243+
)
244+
}
245+
246+
pub fn on_state_exit<T: Clone + Resource, Params, S: IntoStage<Params>>(
247+
&mut self,
248+
value: T,
249+
stage: S,
250+
) -> &mut Self {
251+
self.stage(
252+
&Self::state_stage_name::<T>(),
253+
|state_stage: &mut StateStage<T>| state_stage.on_state_exit(value, stage),
254+
)
255+
}
256+
181257
/// Adds a resource to the current [App] and overwrites any resource previously added of the same type.
182258
pub fn add_resource<T>(&mut self, resource: T) -> &mut Self
183259
where

crates/bevy_app/src/schedule_runner.rs

-2
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,6 @@ impl Plugin for ScheduleRunnerPlugin {
5656
.get_or_insert_with(ScheduleRunnerSettings::default)
5757
.to_owned();
5858
app.set_runner(move |mut app: App| {
59-
app.initialize();
60-
6159
let mut app_exit_event_reader = EventReader::<AppExit>::default();
6260
match settings.run_mode {
6361
RunMode::Once => {

crates/bevy_app/src/stage.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
1+
/// Name of the app stage that runs once at the beginning of the app
2+
pub const STARTUP: &str = "startup";
3+
14
/// Name of app stage that runs before all other app stages
25
pub const FIRST: &str = "first";
36

47
/// Name of app stage that runs before EVENT
5-
pub const PRE_EVENT: &str = "pre_events";
8+
pub const PRE_EVENT: &str = "pre_event";
69

710
/// Name of app stage that updates events. Runs before UPDATE
8-
pub const EVENT: &str = "events";
11+
pub const EVENT: &str = "event";
912

1013
/// Name of app stage responsible for performing setup before an update. Runs before UPDATE.
1114
pub const PRE_UPDATE: &str = "pre_update";

0 commit comments

Comments
 (0)