Move schedule name into Schedule (#9600)

# Objective

- Move schedule name into `Schedule` to allow the schedule name to be
used for errors and tracing in Schedule methods
- Fixes #9510

## Solution

- Move label onto `Schedule` and adjust api's on `World` and `Schedule`
to not pass explicit label where it makes sense to.
- add name to errors and tracing.
- `Schedule::new` now takes a label so either add the label or use
`Schedule::default` which uses a default label. `default` is mostly used
in doc examples and tests.

---

## Changelog

- move label onto `Schedule` to improve error message and logging for
schedules.

## Migration Guide

`Schedule::new` and `App::add_schedule`
```rust
// old
let schedule = Schedule::new();
app.add_schedule(MyLabel, schedule);

// new
let schedule = Schedule::new(MyLabel);
app.add_schedule(schedule);
```

if you aren't using a label and are using the schedule struct directly
you can use the default constructor.
```rust
// old
let schedule = Schedule::new();
schedule.run(world);

// new
let schedule = Schedule::default();
schedule.run(world);
```

`Schedules:insert`
```rust
// old
let schedule = Schedule::new();
schedules.insert(MyLabel, schedule);

// new
let schedule = Schedule::new(MyLabel);
schedules.insert(schedule);
```

`World::add_schedule`
```rust
// old
let schedule = Schedule::new();
world.add_schedule(MyLabel, schedule);

// new
let schedule = Schedule::new(MyLabel);
world.add_schedule(schedule);
```
This commit is contained in:
Mike 2023-08-28 13:44:48 -07:00 committed by GitHub
parent c440de06f1
commit 33fdc5f5db
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 131 additions and 116 deletions

View File

@ -7,7 +7,7 @@ struct A<const N: u16>(f32);
fn setup(system_count: usize) -> (World, Schedule) {
let mut world = World::new();
fn empty() {}
let mut schedule = Schedule::new();
let mut schedule = Schedule::default();
for _ in 0..system_count {
schedule.add_systems(empty);
}

View File

@ -77,7 +77,7 @@ fn par_for_each(
fn setup(parallel: bool, setup: impl FnOnce(&mut Schedule)) -> (World, Schedule) {
let mut world = World::new();
let mut schedule = Schedule::new();
let mut schedule = Schedule::default();
if parallel {
world.insert_resource(ComputeTaskPool(TaskPool::default()));
}

View File

@ -18,7 +18,7 @@ pub fn run_condition_yes(criterion: &mut Criterion) {
group.measurement_time(std::time::Duration::from_secs(3));
fn empty() {}
for amount in 0..21 {
let mut schedule = Schedule::new();
let mut schedule = Schedule::default();
schedule.add_systems(empty.run_if(yes));
for _ in 0..amount {
schedule.add_systems((empty, empty, empty, empty, empty).distributive_run_if(yes));
@ -41,7 +41,7 @@ pub fn run_condition_no(criterion: &mut Criterion) {
group.measurement_time(std::time::Duration::from_secs(3));
fn empty() {}
for amount in 0..21 {
let mut schedule = Schedule::new();
let mut schedule = Schedule::default();
schedule.add_systems(empty.run_if(no));
for _ in 0..amount {
schedule.add_systems((empty, empty, empty, empty, empty).distributive_run_if(no));
@ -71,7 +71,7 @@ pub fn run_condition_yes_with_query(criterion: &mut Criterion) {
query.single().0
}
for amount in 0..21 {
let mut schedule = Schedule::new();
let mut schedule = Schedule::default();
schedule.add_systems(empty.run_if(yes_with_query));
for _ in 0..amount {
schedule.add_systems(
@ -100,7 +100,7 @@ pub fn run_condition_yes_with_resource(criterion: &mut Criterion) {
res.0
}
for amount in 0..21 {
let mut schedule = Schedule::new();
let mut schedule = Schedule::default();
schedule.add_systems(empty.run_if(yes_with_resource));
for _ in 0..amount {
schedule.add_systems(

View File

@ -21,7 +21,7 @@ pub fn empty_systems(criterion: &mut Criterion) {
group.measurement_time(std::time::Duration::from_secs(3));
fn empty() {}
for amount in 0..5 {
let mut schedule = Schedule::new();
let mut schedule = Schedule::default();
for _ in 0..amount {
schedule.add_systems(empty);
}
@ -33,7 +33,7 @@ pub fn empty_systems(criterion: &mut Criterion) {
});
}
for amount in 1..21 {
let mut schedule = Schedule::new();
let mut schedule = Schedule::default();
for _ in 0..amount {
schedule.add_systems((empty, empty, empty, empty, empty));
}
@ -73,7 +73,7 @@ pub fn busy_systems(criterion: &mut Criterion) {
world.spawn_batch((0..ENTITY_BUNCH).map(|_| (A(0.0), B(0.0), C(0.0), D(0.0))));
world.spawn_batch((0..ENTITY_BUNCH).map(|_| (A(0.0), B(0.0), C(0.0), E(0.0))));
for system_amount in 0..5 {
let mut schedule = Schedule::new();
let mut schedule = Schedule::default();
schedule.add_systems((ab, cd, ce));
for _ in 0..system_amount {
schedule.add_systems((ab, cd, ce));
@ -124,7 +124,7 @@ pub fn contrived(criterion: &mut Criterion) {
world.spawn_batch((0..ENTITY_BUNCH).map(|_| (A(0.0), B(0.0))));
world.spawn_batch((0..ENTITY_BUNCH).map(|_| (C(0.0), D(0.0))));
for system_amount in 0..5 {
let mut schedule = Schedule::new();
let mut schedule = Schedule::default();
schedule.add_systems((s_0, s_1, s_2));
for _ in 0..system_amount {
schedule.add_systems((s_0, s_1, s_2));

View File

@ -46,7 +46,7 @@ pub fn schedule(c: &mut Criterion) {
world.spawn_batch((0..10000).map(|_| (A(0.0), B(0.0), C(0.0), E(0.0))));
let mut schedule = Schedule::new();
let mut schedule = Schedule::default();
schedule.add_systems((ab, cd, ce));
schedule.run(&mut world);

View File

@ -384,9 +384,9 @@ impl App {
if let Some(schedule) = schedules.get_mut(&schedule) {
schedule.add_systems(systems);
} else {
let mut new_schedule = Schedule::new();
let mut new_schedule = Schedule::new(schedule);
new_schedule.add_systems(systems);
schedules.insert(schedule, new_schedule);
schedules.insert(new_schedule);
}
self
@ -403,9 +403,9 @@ impl App {
if let Some(schedule) = schedules.get_mut(&schedule) {
schedule.configure_set(set);
} else {
let mut new_schedule = Schedule::new();
let mut new_schedule = Schedule::new(schedule);
new_schedule.configure_set(set);
schedules.insert(schedule, new_schedule);
schedules.insert(new_schedule);
}
self
}
@ -421,9 +421,9 @@ impl App {
if let Some(schedule) = schedules.get_mut(&schedule) {
schedule.configure_sets(sets);
} else {
let mut new_schedule = Schedule::new();
let mut new_schedule = Schedule::new(schedule);
new_schedule.configure_sets(sets);
schedules.insert(schedule, new_schedule);
schedules.insert(new_schedule);
}
self
}
@ -798,9 +798,9 @@ impl App {
/// # Warning
/// This method will overwrite any existing schedule at that label.
/// To avoid this behavior, use the `init_schedule` method instead.
pub fn add_schedule(&mut self, label: impl ScheduleLabel, schedule: Schedule) -> &mut Self {
pub fn add_schedule(&mut self, schedule: Schedule) -> &mut Self {
let mut schedules = self.world.resource_mut::<Schedules>();
schedules.insert(label, schedule);
schedules.insert(schedule);
self
}
@ -811,7 +811,7 @@ impl App {
pub fn init_schedule(&mut self, label: impl ScheduleLabel) -> &mut Self {
let mut schedules = self.world.resource_mut::<Schedules>();
if !schedules.contains(&label) {
schedules.insert(label, Schedule::new());
schedules.insert(Schedule::new(label));
}
self
}
@ -841,7 +841,7 @@ impl App {
let mut schedules = self.world.resource_mut::<Schedules>();
if schedules.get(&label).is_none() {
schedules.insert(label.dyn_clone(), Schedule::new());
schedules.insert(Schedule::new(label.dyn_clone()));
}
let schedule = schedules.get_mut(&label).unwrap();

View File

@ -161,13 +161,13 @@ pub struct MainSchedulePlugin;
impl Plugin for MainSchedulePlugin {
fn build(&self, app: &mut App) {
// simple "facilitator" schedules benefit from simpler single threaded scheduling
let mut main_schedule = Schedule::new();
let mut main_schedule = Schedule::new(Main);
main_schedule.set_executor_kind(ExecutorKind::SingleThreaded);
let mut fixed_update_loop_schedule = Schedule::new();
let mut fixed_update_loop_schedule = Schedule::new(RunFixedUpdateLoop);
fixed_update_loop_schedule.set_executor_kind(ExecutorKind::SingleThreaded);
app.add_schedule(Main, main_schedule)
.add_schedule(RunFixedUpdateLoop, fixed_update_loop_schedule)
app.add_schedule(main_schedule)
.add_schedule(fixed_update_loop_schedule)
.init_resource::<MainScheduleOrder>()
.add_systems(Main, Main::run_main);
}

View File

@ -149,7 +149,7 @@ pub trait DetectChangesMut: DetectChanges {
/// # score_changed.initialize(&mut world);
/// # score_changed.run((), &mut world);
/// #
/// # let mut schedule = Schedule::new();
/// # let mut schedule = Schedule::default();
/// # schedule.add_systems(reset_score);
/// #
/// # // first time `reset_score` runs, the score is changed.
@ -214,7 +214,7 @@ pub trait DetectChangesMut: DetectChanges {
/// # score_changed_event.initialize(&mut world);
/// # score_changed_event.run((), &mut world);
/// #
/// # let mut schedule = Schedule::new();
/// # let mut schedule = Schedule::default();
/// # schedule.add_systems(reset_score);
/// #
/// # // first time `reset_score` runs, the score is changed.

View File

@ -1034,7 +1034,7 @@ mod tests {
world.send_event(TestEvent { i: 3 });
world.send_event(TestEvent { i: 4 });
let mut schedule = Schedule::new();
let mut schedule = Schedule::default();
schedule.add_systems(|mut events: EventReader<TestEvent>| {
let mut iter = events.iter();

View File

@ -789,7 +789,7 @@ mod tests {
}
}
let mut schedule = Schedule::new();
let mut schedule = Schedule::default();
schedule.add_systems((propagate_system, modify_system).chain());
schedule.run(&mut world);
world.clear_trackers();

View File

@ -26,7 +26,7 @@ pub type BoxedCondition<In = ()> = Box<dyn ReadOnlySystem<In = In, Out = bool>>;
///
/// # #[derive(Resource)] struct DidRun(bool);
/// # fn my_system(mut did_run: ResMut<DidRun>) { did_run.0 = true; }
/// # let mut schedule = Schedule::new();
/// # let mut schedule = Schedule::default();
/// schedule.add_systems(my_system.run_if(every_other_time()));
/// # let mut world = World::new();
/// # world.insert_resource(DidRun(false));
@ -46,13 +46,13 @@ pub type BoxedCondition<In = ()> = Box<dyn ReadOnlySystem<In = In, Out = bool>>;
/// }
///
/// # fn always_true() -> bool { true }
/// # let mut schedule = Schedule::new();
/// # let mut app = Schedule::default();
/// # #[derive(Resource)] struct DidRun(bool);
/// # fn my_system(mut did_run: ResMut<DidRun>) { did_run.0 = true; }
/// schedule.add_systems(my_system.run_if(always_true.pipe(identity())));
/// app.add_systems(my_system.run_if(always_true.pipe(identity())));
/// # let mut world = World::new();
/// # world.insert_resource(DidRun(false));
/// # schedule.run(&mut world);
/// # app.run(&mut world);
/// # assert!(world.resource::<DidRun>().0);
pub trait Condition<Marker, In = ()>: sealed::Condition<Marker, In> {
/// Returns a new run condition that only returns `true`
@ -69,7 +69,7 @@ pub trait Condition<Marker, In = ()>: sealed::Condition<Marker, In> {
/// #[derive(Resource, PartialEq)]
/// struct R(u32);
///
/// # let mut app = Schedule::new();
/// # let mut app = Schedule::default();
/// # let mut world = World::new();
/// # fn my_system() {}
/// app.add_systems(
@ -86,7 +86,7 @@ pub trait Condition<Marker, In = ()>: sealed::Condition<Marker, In> {
/// # use bevy_ecs::prelude::*;
/// # #[derive(Resource, PartialEq)]
/// # struct R(u32);
/// # let mut app = Schedule::new();
/// # let mut app = Schedule::default();
/// # let mut world = World::new();
/// # fn my_system() {}
/// app.add_systems(
@ -123,7 +123,7 @@ pub trait Condition<Marker, In = ()>: sealed::Condition<Marker, In> {
/// #[derive(Resource, PartialEq)]
/// struct B(u32);
///
/// # let mut app = Schedule::new();
/// # let mut app = Schedule::default();
/// # let mut world = World::new();
/// # #[derive(Resource)] struct C(bool);
/// # fn my_system(mut c: ResMut<C>) { c.0 = true; }
@ -197,7 +197,7 @@ pub mod common_conditions {
/// # use bevy_ecs::prelude::*;
/// # #[derive(Resource, Default)]
/// # struct Counter(u8);
/// # let mut app = Schedule::new();
/// # let mut app = Schedule::default();
/// # let mut world = World::new();
/// # world.init_resource::<Counter>();
/// app.add_systems(
@ -238,7 +238,7 @@ pub mod common_conditions {
/// # use bevy_ecs::prelude::*;
/// # #[derive(Resource, Default)]
/// # struct Counter(u8);
/// # let mut app = Schedule::new();
/// # let mut app = Schedule::default();
/// # let mut world = World::new();
/// app.add_systems(
/// // `resource_exists` will only return true if the given resource exists in the world
@ -277,7 +277,7 @@ pub mod common_conditions {
/// # use bevy_ecs::prelude::*;
/// # #[derive(Resource, Default, PartialEq)]
/// # struct Counter(u8);
/// # let mut app = Schedule::new();
/// # let mut app = Schedule::default();
/// # let mut world = World::new();
/// # world.init_resource::<Counter>();
/// app.add_systems(
@ -315,7 +315,7 @@ pub mod common_conditions {
/// # use bevy_ecs::prelude::*;
/// # #[derive(Resource, Default, PartialEq)]
/// # struct Counter(u8);
/// # let mut app = Schedule::new();
/// # let mut app = Schedule::default();
/// # let mut world = World::new();
/// app.add_systems(
/// // `resource_exists_and_equals` will only return true
@ -358,7 +358,7 @@ pub mod common_conditions {
/// # use bevy_ecs::prelude::*;
/// # #[derive(Resource, Default)]
/// # struct Counter(u8);
/// # let mut app = Schedule::new();
/// # let mut app = Schedule::default();
/// # let mut world = World::new();
/// app.add_systems(
/// // `resource_added` will only return true if the
@ -408,7 +408,7 @@ pub mod common_conditions {
/// # use bevy_ecs::prelude::*;
/// # #[derive(Resource, Default)]
/// # struct Counter(u8);
/// # let mut app = Schedule::new();
/// # let mut app = Schedule::default();
/// # let mut world = World::new();
/// # world.init_resource::<Counter>();
/// app.add_systems(
@ -462,7 +462,7 @@ pub mod common_conditions {
/// # use bevy_ecs::prelude::*;
/// # #[derive(Resource, Default)]
/// # struct Counter(u8);
/// # let mut app = Schedule::new();
/// # let mut app = Schedule::default();
/// # let mut world = World::new();
/// app.add_systems(
/// // `resource_exists_and_changed` will only return true if the
@ -523,7 +523,7 @@ pub mod common_conditions {
/// # use bevy_ecs::prelude::*;
/// # #[derive(Resource, Default)]
/// # struct Counter(u8);
/// # let mut app = Schedule::new();
/// # let mut app = Schedule::default();
/// # let mut world = World::new();
/// # world.init_resource::<Counter>();
/// app.add_systems(
@ -593,7 +593,7 @@ pub mod common_conditions {
/// # use bevy_ecs::prelude::*;
/// # #[derive(Resource, Default)]
/// # struct Counter(u8);
/// # let mut app = Schedule::new();
/// # let mut app = Schedule::default();
/// # let mut world = World::new();
/// # world.init_resource::<Counter>();
/// app.add_systems(
@ -648,7 +648,7 @@ pub mod common_conditions {
/// # use bevy_ecs::prelude::*;
/// # #[derive(Resource, Default)]
/// # struct Counter(u8);
/// # let mut app = Schedule::new();
/// # let mut app = Schedule::default();
/// # let mut world = World::new();
/// # world.init_resource::<Counter>();
/// #[derive(States, Clone, Copy, Default, Eq, PartialEq, Hash, Debug)]
@ -695,7 +695,7 @@ pub mod common_conditions {
/// # use bevy_ecs::prelude::*;
/// # #[derive(Resource, Default)]
/// # struct Counter(u8);
/// # let mut app = Schedule::new();
/// # let mut app = Schedule::default();
/// # let mut world = World::new();
/// # world.init_resource::<Counter>();
/// #[derive(States, Clone, Copy, Default, Eq, PartialEq, Hash, Debug)]
@ -747,7 +747,7 @@ pub mod common_conditions {
/// # use bevy_ecs::prelude::*;
/// # #[derive(Resource, Default)]
/// # struct Counter(u8);
/// # let mut app = Schedule::new();
/// # let mut app = Schedule::default();
/// # let mut world = World::new();
/// # world.init_resource::<Counter>();
/// #[derive(States, Clone, Copy, Default, Eq, PartialEq, Hash, Debug)]
@ -813,7 +813,7 @@ pub mod common_conditions {
/// # use bevy_ecs::prelude::*;
/// # #[derive(Resource, Default)]
/// # struct Counter(u8);
/// # let mut app = Schedule::new();
/// # let mut app = Schedule::default();
/// # let mut world = World::new();
/// # world.init_resource::<Counter>();
/// #[derive(States, Clone, Copy, Default, Eq, PartialEq, Hash, Debug)]
@ -863,7 +863,7 @@ pub mod common_conditions {
/// # use bevy_ecs::prelude::*;
/// # #[derive(Resource, Default)]
/// # struct Counter(u8);
/// # let mut app = Schedule::new();
/// # let mut app = Schedule::default();
/// # let mut world = World::new();
/// # world.init_resource::<Counter>();
/// # world.init_resource::<Events<MyEvent>>();
@ -907,7 +907,7 @@ pub mod common_conditions {
/// # use bevy_ecs::prelude::*;
/// # #[derive(Resource, Default)]
/// # struct Counter(u8);
/// # let mut app = Schedule::new();
/// # let mut app = Schedule::default();
/// # let mut world = World::new();
/// # world.init_resource::<Counter>();
/// app.add_systems(
@ -954,7 +954,7 @@ pub mod common_conditions {
/// # use bevy_ecs::prelude::*;
/// # #[derive(Resource, Default)]
/// # struct Counter(u8);
/// # let mut app = Schedule::new();
/// # let mut app = Schedule::default();
/// # let mut world = World::new();
/// # world.init_resource::<Counter>();
/// app.add_systems(
@ -1084,7 +1084,7 @@ mod tests {
fn run_condition() {
let mut world = World::new();
world.init_resource::<Counter>();
let mut schedule = Schedule::new();
let mut schedule = Schedule::default();
// Run every other cycle
schedule.add_systems(increment_counter.run_if(every_other_time));
@ -1111,7 +1111,7 @@ mod tests {
fn run_condition_combinators() {
let mut world = World::new();
world.init_resource::<Counter>();
let mut schedule = Schedule::new();
let mut schedule = Schedule::default();
// Always run
schedule.add_systems(increment_counter.run_if(every_other_time.or_else(|| true)));
@ -1128,7 +1128,7 @@ mod tests {
fn multiple_run_conditions() {
let mut world = World::new();
world.init_resource::<Counter>();
let mut schedule = Schedule::new();
let mut schedule = Schedule::default();
// Run every other cycle
schedule.add_systems(increment_counter.run_if(every_other_time).run_if(|| true));
@ -1146,7 +1146,7 @@ mod tests {
let mut world = World::new();
world.init_resource::<Counter>();
let mut schedule = Schedule::new();
let mut schedule = Schedule::default();
// This should never run, if multiple run conditions worked
// like an OR condition then it would always run

View File

@ -225,7 +225,7 @@ where
///
/// ```
/// # use bevy_ecs::prelude::*;
/// # let mut schedule = Schedule::new();
/// # let mut schedule = Schedule::default();
/// # fn a() {}
/// # fn b() {}
/// # fn condition() -> bool { true }
@ -258,7 +258,7 @@ where
///
/// ```
/// # use bevy_ecs::prelude::*;
/// # let mut schedule = Schedule::new();
/// # let mut schedule = Schedule::default();
/// # fn a() {}
/// # fn b() {}
/// # fn condition() -> bool { true }

View File

@ -180,7 +180,7 @@ mod tests {
#[test]
fn add_systems_correct_order() {
let mut world = World::new();
let mut schedule = Schedule::new();
let mut schedule = Schedule::default();
world.init_resource::<SystemOrder>();
@ -201,7 +201,7 @@ mod tests {
#[test]
fn add_systems_correct_order_nested() {
let mut world = World::new();
let mut schedule = Schedule::new();
let mut schedule = Schedule::default();
world.init_resource::<SystemOrder>();
@ -528,14 +528,14 @@ mod tests {
#[test]
#[should_panic]
fn dependency_loop() {
let mut schedule = Schedule::new();
let mut schedule = Schedule::default();
schedule.configure_set(TestSet::X.after(TestSet::X));
}
#[test]
fn dependency_cycle() {
let mut world = World::new();
let mut schedule = Schedule::new();
let mut schedule = Schedule::default();
schedule.configure_set(TestSet::A.after(TestSet::B));
schedule.configure_set(TestSet::B.after(TestSet::A));
@ -550,7 +550,7 @@ mod tests {
fn bar() {}
let mut world = World::new();
let mut schedule = Schedule::new();
let mut schedule = Schedule::default();
schedule.add_systems((foo.after(bar), bar.after(foo)));
let result = schedule.initialize(&mut world);
@ -563,14 +563,14 @@ mod tests {
#[test]
#[should_panic]
fn hierarchy_loop() {
let mut schedule = Schedule::new();
let mut schedule = Schedule::default();
schedule.configure_set(TestSet::X.in_set(TestSet::X));
}
#[test]
fn hierarchy_cycle() {
let mut world = World::new();
let mut schedule = Schedule::new();
let mut schedule = Schedule::default();
schedule.configure_set(TestSet::A.in_set(TestSet::B));
schedule.configure_set(TestSet::B.in_set(TestSet::A));
@ -586,7 +586,7 @@ mod tests {
fn bar() {}
let mut world = World::new();
let mut schedule = Schedule::new();
let mut schedule = Schedule::default();
// Schedule `bar` to run after `foo`.
schedule.add_systems((foo, bar.after(foo)));
@ -607,7 +607,7 @@ mod tests {
));
// same goes for `ambiguous_with`
let mut schedule = Schedule::new();
let mut schedule = Schedule::default();
schedule.add_systems(foo);
schedule.add_systems(bar.ambiguous_with(foo));
let result = schedule.initialize(&mut world);
@ -624,14 +624,14 @@ mod tests {
#[should_panic]
fn configure_system_type_set() {
fn foo() {}
let mut schedule = Schedule::new();
let mut schedule = Schedule::default();
schedule.configure_set(foo.into_system_set());
}
#[test]
fn hierarchy_redundancy() {
let mut world = World::new();
let mut schedule = Schedule::new();
let mut schedule = Schedule::default();
schedule.set_build_settings(ScheduleBuildSettings {
hierarchy_detection: LogLevel::Error,
@ -658,7 +658,7 @@ mod tests {
#[test]
fn cross_dependency() {
let mut world = World::new();
let mut schedule = Schedule::new();
let mut schedule = Schedule::default();
// Add `B` and give it both kinds of relationships with `A`.
schedule.configure_set(TestSet::B.in_set(TestSet::A));
@ -673,7 +673,7 @@ mod tests {
#[test]
fn sets_have_order_but_intersect() {
let mut world = World::new();
let mut schedule = Schedule::new();
let mut schedule = Schedule::default();
fn foo() {}
@ -704,7 +704,7 @@ mod tests {
fn res_mut(_x: ResMut<X>) {}
let mut world = World::new();
let mut schedule = Schedule::new();
let mut schedule = Schedule::default();
schedule.set_build_settings(ScheduleBuildSettings {
ambiguity_detection: LogLevel::Error,

View File

@ -41,8 +41,8 @@ impl Schedules {
///
/// If the map already had an entry for `label`, `schedule` is inserted,
/// and the old schedule is returned. Otherwise, `None` is returned.
pub fn insert(&mut self, label: impl ScheduleLabel, schedule: Schedule) -> Option<Schedule> {
let label = label.dyn_clone();
pub fn insert(&mut self, schedule: Schedule) -> Option<Schedule> {
let label = schedule.name.dyn_clone();
self.inner.insert(label, schedule)
}
@ -158,22 +158,31 @@ fn make_executor(kind: ExecutorKind) -> Box<dyn SystemExecutor> {
/// }
/// ```
pub struct Schedule {
name: BoxedScheduleLabel,
graph: ScheduleGraph,
executable: SystemSchedule,
executor: Box<dyn SystemExecutor>,
executor_initialized: bool,
}
#[derive(ScheduleLabel, Hash, PartialEq, Eq, Debug, Clone)]
struct DefaultSchedule;
/// Creates a schedule with a default label. Only use in situations where
/// where you don't care about the [`ScheduleLabel`]. Inserting a default schedule
/// into the world risks overwriting another schedule. For most situations you should use
/// [`Schedule::new`].
impl Default for Schedule {
fn default() -> Self {
Self::new()
Self::new(DefaultSchedule)
}
}
impl Schedule {
/// Constructs an empty `Schedule`.
pub fn new() -> Self {
pub fn new(label: impl ScheduleLabel) -> Self {
Self {
name: label.dyn_clone(),
graph: ScheduleGraph::new(),
executable: SystemSchedule::new(),
executor: make_executor(ExecutorKind::default()),
@ -237,8 +246,12 @@ impl Schedule {
/// Runs all systems in this schedule on the `world`, using its current execution strategy.
pub fn run(&mut self, world: &mut World) {
#[cfg(feature = "trace")]
let _span = bevy_utils::tracing::info_span!("schedule", name = ?self.name).entered();
world.check_change_ticks();
self.initialize(world).unwrap_or_else(|e| panic!("{e}"));
self.initialize(world)
.unwrap_or_else(|e| panic!("Error when intializing schedule {:?}: {e}", self.name));
self.executor.run(&mut self.executable, world);
}
@ -250,7 +263,7 @@ impl Schedule {
if self.graph.changed {
self.graph.initialize(world);
self.graph
.update_schedule(&mut self.executable, world.components())?;
.update_schedule(&mut self.executable, world.components(), &self.name)?;
self.graph.changed = false;
self.executor_initialized = false;
}
@ -882,13 +895,14 @@ impl ScheduleGraph {
pub fn build_schedule(
&mut self,
components: &Components,
schedule_label: &BoxedScheduleLabel,
) -> Result<SystemSchedule, ScheduleBuildError> {
// check hierarchy for cycles
self.hierarchy.topsort =
self.topsort_graph(&self.hierarchy.graph, ReportCycles::Hierarchy)?;
let hier_results = check_graph(&self.hierarchy.graph, &self.hierarchy.topsort);
self.optionally_check_hierarchy_conflicts(&hier_results.transitive_edges)?;
self.optionally_check_hierarchy_conflicts(&hier_results.transitive_edges, schedule_label)?;
// remove redundant edges
self.hierarchy.graph = hier_results.transitive_reduction;
@ -932,7 +946,7 @@ impl ScheduleGraph {
// check for conflicts
let conflicting_systems =
self.get_conflicting_systems(&flat_results.disconnected, &ambiguous_with_flattened);
self.optionally_check_conflicts(&conflicting_systems, components)?;
self.optionally_check_conflicts(&conflicting_systems, components, schedule_label)?;
self.conflicting_systems = conflicting_systems;
// build the schedule
@ -1182,6 +1196,7 @@ impl ScheduleGraph {
&mut self,
schedule: &mut SystemSchedule,
components: &Components,
schedule_label: &BoxedScheduleLabel,
) -> Result<(), ScheduleBuildError> {
if !self.uninit.is_empty() {
return Err(ScheduleBuildError::Uninitialized);
@ -1206,7 +1221,7 @@ impl ScheduleGraph {
self.system_set_conditions[id.index()] = conditions;
}
*schedule = self.build_schedule(components)?;
*schedule = self.build_schedule(components, schedule_label)?;
// move systems into new schedule
for &id in &schedule.system_ids {
@ -1297,6 +1312,7 @@ impl ScheduleGraph {
fn optionally_check_hierarchy_conflicts(
&self,
transitive_edges: &[(NodeId, NodeId)],
schedule_label: &BoxedScheduleLabel,
) -> Result<(), ScheduleBuildError> {
if self.settings.hierarchy_detection == LogLevel::Ignore || transitive_edges.is_empty() {
return Ok(());
@ -1306,7 +1322,10 @@ impl ScheduleGraph {
match self.settings.hierarchy_detection {
LogLevel::Ignore => unreachable!(),
LogLevel::Warn => {
error!("{}", message);
error!(
"Schedule {schedule_label:?} has redundant edges:\n {}",
message
);
Ok(())
}
LogLevel::Error => Err(ScheduleBuildError::HierarchyRedundancy(message)),
@ -1505,6 +1524,7 @@ impl ScheduleGraph {
&self,
conflicts: &[(NodeId, NodeId, Vec<ComponentId>)],
components: &Components,
schedule_label: &BoxedScheduleLabel,
) -> Result<(), ScheduleBuildError> {
if self.settings.ambiguity_detection == LogLevel::Ignore || conflicts.is_empty() {
return Ok(());
@ -1514,7 +1534,7 @@ impl ScheduleGraph {
match self.settings.ambiguity_detection {
LogLevel::Ignore => Ok(()),
LogLevel::Warn => {
warn!("{}", message);
warn!("Schedule {schedule_label:?} has ambiguities.\n{}", message);
Ok(())
}
LogLevel::Error => Err(ScheduleBuildError::Ambiguity(message)),
@ -1689,7 +1709,7 @@ mod tests {
struct Set;
let mut world = World::new();
let mut schedule = Schedule::new();
let mut schedule = Schedule::default();
schedule.configure_set(Set.run_if(|| false));
schedule.add_systems(

View File

@ -198,9 +198,9 @@ mod tests {
let mut world = World::new();
let mut schedule = Schedule::new();
let mut schedule = Schedule::new(A);
schedule.add_systems(|mut flag: ResMut<Flag>| flag.0 = true);
world.add_schedule(schedule, A);
world.add_schedule(schedule);
let boxed: Box<dyn ScheduleLabel> = Box::new(A);

View File

@ -50,7 +50,7 @@ use super::{ReadOnlySystem, System};
/// # let mut world = World::new();
/// # world.init_resource::<RanFlag>();
/// #
/// # let mut app = Schedule::new();
/// # let mut app = Schedule::default();
/// app.add_systems(my_system.run_if(Xor::new(
/// IntoSystem::into_system(resource_equals(A(1))),
/// IntoSystem::into_system(resource_equals(B(1))),

View File

@ -596,9 +596,9 @@ impl<'w, 's> Commands<'w, 's> {
/// # let mut world = World::new();
/// # world.init_resource::<Counter>();
/// #
/// # let mut setup_schedule = Schedule::new();
/// # let mut setup_schedule = Schedule::default();
/// # setup_schedule.add_systems(setup);
/// # let mut assert_schedule = Schedule::new();
/// # let mut assert_schedule = Schedule::default();
/// # assert_schedule.add_systems(assert_names);
/// #
/// # setup_schedule.run(&mut world);

View File

@ -55,7 +55,7 @@
//!
//! ```
//! # use bevy_ecs::prelude::*;
//! # let mut schedule = Schedule::new();
//! # let mut schedule = Schedule::default();
//! # let mut world = World::new();
//! // Configure these systems to run in order using `chain()`.
//! schedule.add_systems((print_first, print_last).chain());
@ -170,7 +170,7 @@ pub trait IntoSystem<In, Out, Marker>: Sized {
///
/// ```
/// # use bevy_ecs::prelude::*;
/// # let mut schedule = Schedule::new();
/// # let mut schedule = Schedule::default();
/// // Ignores the output of a system that may fail.
/// schedule.add_systems(my_system.map(std::mem::drop));
/// # let mut world = World::new();
@ -1916,7 +1916,7 @@ mod tests {
world.insert_resource(A);
world.insert_resource(C(0));
let mut sched = Schedule::new();
let mut sched = Schedule::default();
sched.add_systems(
(
(|mut res: ResMut<C>| {

View File

@ -353,7 +353,7 @@ impl_param_set!();
///
/// ```
/// # let mut world = World::default();
/// # let mut schedule = Schedule::new();
/// # let mut schedule = Schedule::default();
/// # use bevy_ecs::prelude::*;
/// #[derive(Resource)]
/// struct MyResource { value: u32 }
@ -854,7 +854,7 @@ pub trait SystemBuffer: FromWorld + Send + 'static {
/// // ...
/// });
///
/// let mut schedule = Schedule::new();
/// let mut schedule = Schedule::default();
/// // These two systems have no conflicts and will run in parallel.
/// schedule.add_systems((alert_criminal, alert_monster));
///
@ -1735,7 +1735,7 @@ mod tests {
}
let mut world = World::new();
let mut schedule = crate::schedule::Schedule::new();
let mut schedule = crate::schedule::Schedule::default();
schedule.add_systems(non_sync_system);
schedule.run(&mut world);
}

View File

@ -1748,9 +1748,9 @@ impl World {
/// accessing the [`Schedules`] resource.
///
/// The `Schedules` resource will be initialized if it does not already exist.
pub fn add_schedule(&mut self, schedule: Schedule, label: impl ScheduleLabel) {
pub fn add_schedule(&mut self, schedule: Schedule) {
let mut schedules = self.get_resource_or_insert_with(Schedules::default);
schedules.insert(label, schedule);
schedules.insert(schedule);
}
/// Temporarily removes the schedule associated with `label` from the world,
@ -1770,21 +1770,16 @@ impl World {
f: impl FnOnce(&mut World, &mut Schedule) -> R,
) -> Result<R, TryRunScheduleError> {
let label = label.as_ref();
let Some((extracted_label, mut schedule)) = self
let Some(mut schedule) = self
.get_resource_mut::<Schedules>()
.and_then(|mut s| s.remove_entry(label))
.and_then(|mut s| s.remove(label))
else {
return Err(TryRunScheduleError(label.dyn_clone()));
};
// TODO: move this span to Schedule::run
#[cfg(feature = "trace")]
let _span = bevy_utils::tracing::info_span!("schedule", name = ?extracted_label).entered();
let value = f(self, &mut schedule);
let old = self
.resource_mut::<Schedules>()
.insert(extracted_label, schedule);
let old = self.resource_mut::<Schedules>().insert(schedule);
if old.is_some() {
warn!("Schedule `{label:?}` was inserted during a call to `World::schedule_scope`: its value has been overwritten");
}
@ -1809,10 +1804,10 @@ impl World {
/// #
/// # let mut world = World::new();
/// # world.insert_resource(Counter(0));
/// # let mut schedule = Schedule::new();
/// # let mut schedule = Schedule::new(MySchedule);
/// # schedule.add_systems(tick_counter);
/// # world.init_resource::<Schedules>();
/// # world.add_schedule(schedule, MySchedule);
/// # world.add_schedule(schedule);
/// # fn tick_counter(mut counter: ResMut<Counter>) { counter.0 += 1; }
/// // Run the schedule five times.
/// world.schedule_scope(MySchedule, |world, schedule| {

View File

@ -132,7 +132,7 @@ impl Render {
pub fn base_schedule() -> Schedule {
use RenderSet::*;
let mut schedule = Schedule::new();
let mut schedule = Schedule::new(Self);
// Create "stage-like" structure using buffer flushes + ordering
schedule.add_systems((
@ -295,12 +295,12 @@ impl Plugin for RenderPlugin {
let mut render_app = App::empty();
render_app.main_schedule_label = Box::new(Render);
let mut extract_schedule = Schedule::new();
let mut extract_schedule = Schedule::new(ExtractSchedule);
extract_schedule.set_apply_final_deferred(false);
render_app
.add_schedule(ExtractSchedule, extract_schedule)
.add_schedule(Render, Render::base_schedule())
.add_schedule(extract_schedule)
.add_schedule(Render::base_schedule())
.init_resource::<render_graph::RenderGraph>()
.insert_resource(app.world.resource::<AssetServer>().clone())
.add_systems(ExtractSchedule, PipelineCache::extract_shaders)

View File

@ -124,7 +124,7 @@ impl Time {
/// world.insert_resource(time);
/// world.insert_resource(Health { health_value: 0.2 });
///
/// let mut schedule = Schedule::new();
/// let mut schedule = Schedule::default();
/// schedule.add_systems(health_system);
///
/// // Simulate that 30 ms have passed

View File

@ -200,7 +200,7 @@ mod test {
let offset_transform =
|offset| TransformBundle::from_transform(Transform::from_xyz(offset, offset, offset));
let mut schedule = Schedule::new();
let mut schedule = Schedule::default();
schedule.add_systems((sync_simple_transforms, propagate_transforms));
let mut command_queue = CommandQueue::default();
@ -251,7 +251,7 @@ mod test {
ComputeTaskPool::init(TaskPool::default);
let mut world = World::default();
let mut schedule = Schedule::new();
let mut schedule = Schedule::default();
schedule.add_systems((sync_simple_transforms, propagate_transforms));
// Root entity
@ -289,7 +289,7 @@ mod test {
fn did_propagate_command_buffer() {
let mut world = World::default();
let mut schedule = Schedule::new();
let mut schedule = Schedule::default();
schedule.add_systems((sync_simple_transforms, propagate_transforms));
// Root entity
@ -329,7 +329,7 @@ mod test {
ComputeTaskPool::init(TaskPool::default);
let mut world = World::default();
let mut schedule = Schedule::new();
let mut schedule = Schedule::default();
schedule.add_systems((sync_simple_transforms, propagate_transforms));
// Add parent entities