diff --git a/crates/bevy_app/src/app.rs b/crates/bevy_app/src/app.rs index 8a67a2fc30cad..0806aa59450cc 100644 --- a/crates/bevy_app/src/app.rs +++ b/crates/bevy_app/src/app.rs @@ -987,7 +987,7 @@ impl App { let mut schedules = self.world.resource_mut::(); if schedules.get(&label).is_none() { - schedules.insert(label.dyn_clone(), Schedule::new()); + schedules.insert_boxed(label.dyn_clone(), Schedule::new()); } let schedule = schedules.get_mut(&label).unwrap(); diff --git a/crates/bevy_ecs/src/schedule/schedule.rs b/crates/bevy_ecs/src/schedule/schedule.rs index 3c64995a106f2..87088f2781e2c 100644 --- a/crates/bevy_ecs/src/schedule/schedule.rs +++ b/crates/bevy_ecs/src/schedule/schedule.rs @@ -43,6 +43,21 @@ impl Schedules { /// and the old schedule is returned. Otherwise, `None` is returned. pub fn insert(&mut self, label: impl ScheduleLabel, schedule: Schedule) -> Option { let label = label.dyn_clone(); + self.insert_boxed(label, schedule) + } + + /// Inserts a labeled schedule into the map. + /// + /// Unlike `insert`, this method takes a [`BoxedScheduleLabel`]. This is useful when you + /// do not have a concrete schedule label and only a boxed version of it. + /// + /// 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_boxed( + &mut self, + label: BoxedScheduleLabel, + schedule: Schedule, + ) -> Option { if self.inner.contains_key(&label) { warn!("schedule with label {:?} already exists", label); } diff --git a/crates/bevy_ecs/src/world/mod.rs b/crates/bevy_ecs/src/world/mod.rs index face0b33ef0b4..d7ebea84fcca4 100644 --- a/crates/bevy_ecs/src/world/mod.rs +++ b/crates/bevy_ecs/src/world/mod.rs @@ -1726,7 +1726,8 @@ impl World { /// Runs the [`Schedule`] associated with the `label` a single time. /// - /// Unlike the `run_schedule` method, this method takes the label by reference, which can save a clone. + /// Unlike the `run_schedule` method, this method takes the label by reference. This is useful + /// when you have the schedule label behind a pointer, such as a `Box`. /// /// The [`Schedule`] is fetched from the [`Schedules`] resource of the world by its label, /// and system state is cached. @@ -1747,7 +1748,7 @@ impl World { let _span = bevy_utils::tracing::info_span!("schedule", name = ?extracted_label).entered(); schedule.run(self); self.resource_mut::() - .insert(extracted_label, schedule); + .insert_boxed(extracted_label, schedule); } } diff --git a/crates/bevy_utils/src/label.rs b/crates/bevy_utils/src/label.rs index 631ef7a426245..d3e816552bb1e 100644 --- a/crates/bevy_utils/src/label.rs +++ b/crates/bevy_utils/src/label.rs @@ -98,14 +98,6 @@ macro_rules! define_boxed_label { self.dyn_clone() } } - - impl $label_trait_name for Box { - fn dyn_clone(&self) -> Box { - // Be explicit that we want to use the inner value - // to avoid infinite recursion. - (**self).dyn_clone() - } - } }; }