Skip to content

Commit

Permalink
Deprecate configure_set & make configure_sets work for single par…
Browse files Browse the repository at this point in the history
…ams.
  • Loading branch information
geieredgar committed Jul 23, 2023
1 parent eb485b1 commit 2ad6fc9
Show file tree
Hide file tree
Showing 13 changed files with 331 additions and 201 deletions.
13 changes: 3 additions & 10 deletions crates/bevy_app/src/app.rs
Expand Up @@ -393,20 +393,13 @@ impl App {
}

/// Configures a system set in the default schedule, adding the set if it does not exist.
#[deprecated(since = "0.12.0", note = "Please use `configure_sets` instead.")]
pub fn configure_set(
&mut self,
schedule: impl ScheduleLabel,
set: impl IntoSystemSetConfig,
set: impl IntoSystemSetConfigs,
) -> &mut Self {
let mut schedules = self.world.resource_mut::<Schedules>();
if let Some(schedule) = schedules.get_mut(&schedule) {
schedule.configure_set(set);
} else {
let mut new_schedule = Schedule::new();
new_schedule.configure_set(set);
schedules.insert(schedule, new_schedule);
}
self
self.configure_sets(schedule, set)
}

/// Configures a collection of system sets in the default schedule, adding any sets that do not exist.
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_audio/src/lib.rs
Expand Up @@ -69,7 +69,7 @@ pub struct AudioPlugin {
impl Plugin for AudioPlugin {
fn build(&self, app: &mut App) {
app.insert_resource(self.global_volume)
.configure_set(PostUpdate, AudioPlaySet.run_if(audio_output_available))
.configure_sets(PostUpdate, AudioPlaySet.run_if(audio_output_available))
.init_resource::<AudioOutput>();

#[cfg(any(feature = "mp3", feature = "flac", feature = "wav", feature = "vorbis"))]
Expand Down
4 changes: 2 additions & 2 deletions crates/bevy_ecs/src/lib.rs
Expand Up @@ -41,8 +41,8 @@ pub mod prelude {
removal_detection::RemovedComponents,
schedule::{
apply_deferred, apply_state_transition, common_conditions::*, Condition,
IntoSystemConfigs, IntoSystemSet, IntoSystemSetConfig, IntoSystemSetConfigs, NextState,
OnEnter, OnExit, OnTransition, Schedule, Schedules, State, States, SystemSet,
IntoSystemConfigs, IntoSystemSet, IntoSystemSetConfigs, NextState, OnEnter, OnExit,
OnTransition, Schedule, Schedules, State, States, SystemSet,
},
system::{
adapter as system_adapter,
Expand Down
253 changes: 135 additions & 118 deletions crates/bevy_ecs/src/schedule/config.rs
Expand Up @@ -260,7 +260,7 @@ where
/// # #[derive(SystemSet, Debug, Eq, PartialEq, Hash, Clone, Copy)]
/// # struct C;
/// schedule.add_systems((a, b).run_if(condition));
/// schedule.add_systems((a, b).in_set(C)).configure_set(C.run_if(condition));
/// schedule.add_systems((a, b).in_set(C)).configure_sets(C.run_if(condition));
/// ```
///
/// # Note
Expand Down Expand Up @@ -388,7 +388,7 @@ pub struct SystemSetConfig {
}

impl SystemSetConfig {
fn new(set: BoxedSystemSet) -> Self {
pub(super) fn new(set: BoxedSystemSet) -> Self {
// system type sets are automatically populated
// to avoid unintentionally broad changes, they cannot be configured
assert!(
Expand All @@ -404,111 +404,106 @@ impl SystemSetConfig {
}
}

/// Types that can be converted into a [`SystemSetConfig`].
///
/// This has been implemented for all types that implement [`SystemSet`] and boxed trait objects.
pub trait IntoSystemSetConfig: Sized {
/// Convert into a [`SystemSetConfig`].
#[doc(hidden)]
fn into_config(self) -> SystemSetConfig;
/// Add to the provided `set`.
#[track_caller]
fn in_set(self, set: impl SystemSet) -> SystemSetConfig {
self.into_config().in_set(set)
}
/// Run before all systems in `set`.
fn before<M>(self, set: impl IntoSystemSet<M>) -> SystemSetConfig {
self.into_config().before(set)
}
/// Run after all systems in `set`.
fn after<M>(self, set: impl IntoSystemSet<M>) -> SystemSetConfig {
self.into_config().after(set)
}
/// Run the systems in this set only if the [`Condition`] is `true`.
///
/// The `Condition` will be evaluated at most once (per schedule run),
/// the first time a system in this set prepares to run.
fn run_if<M>(self, condition: impl Condition<M>) -> SystemSetConfig {
self.into_config().run_if(condition)
}
/// Suppress warnings and errors that would result from systems in this set having ambiguities
/// (conflicting access but indeterminate order) with systems in `set`.
fn ambiguous_with<M>(self, set: impl IntoSystemSet<M>) -> SystemSetConfig {
self.into_config().ambiguous_with(set)
}
/// Suppress warnings and errors that would result from systems in this set having ambiguities
/// (conflicting access but indeterminate order) with any other system.
fn ambiguous_with_all(self) -> SystemSetConfig {
self.into_config().ambiguous_with_all()
}
}

impl<S: SystemSet> IntoSystemSetConfig for S {
fn into_config(self) -> SystemSetConfig {
SystemSetConfig::new(Box::new(self))
}
}

impl IntoSystemSetConfig for BoxedSystemSet {
fn into_config(self) -> SystemSetConfig {
SystemSetConfig::new(self)
}
/// A collection of [`SystemSetConfig`].
pub enum SystemSetConfigs {
/// Configuration for a single system set.
SystemSetConfig(SystemSetConfig),
/// Configuration for a tuple of nested `SystemSetConfigs` instances.
Configs {
/// Configuration for each element of the tuple.
configs: Vec<SystemSetConfigs>,
/// Run conditions applied to everything in the tuple.
collective_conditions: Vec<BoxedCondition>,
/// If `true`, adds `before -> after` ordering constraints between the successive elements.
chained: bool,
},
}

impl IntoSystemSetConfig for SystemSetConfig {
fn into_config(self) -> Self {
self
}

#[track_caller]
fn in_set(mut self, set: impl SystemSet) -> Self {
assert!(
set.system_type().is_none(),
"adding arbitrary systems to a system type set is not allowed"
);
self.graph_info.sets.push(Box::new(set));
self
impl SystemSetConfigs {
pub(super) fn in_set_inner(&mut self, set: BoxedSystemSet) {
match self {
SystemSetConfigs::SystemSetConfig(config) => config.graph_info.sets.push(set),
SystemSetConfigs::Configs { configs, .. } => {
for config in configs {
config.in_set_inner(set.dyn_clone());
}
}
}
}

fn before<M>(mut self, set: impl IntoSystemSet<M>) -> Self {
self.graph_info.dependencies.push(Dependency::new(
DependencyKind::Before,
Box::new(set.into_system_set()),
));
self
fn before_inner(&mut self, set: BoxedSystemSet) {
match self {
SystemSetConfigs::SystemSetConfig(config) => {
config
.graph_info
.dependencies
.push(Dependency::new(DependencyKind::Before, set));
}
SystemSetConfigs::Configs { configs, .. } => {
for config in configs {
config.before_inner(set.dyn_clone());
}
}
}
}

fn after<M>(mut self, set: impl IntoSystemSet<M>) -> Self {
self.graph_info.dependencies.push(Dependency::new(
DependencyKind::After,
Box::new(set.into_system_set()),
));
self
fn after_inner(&mut self, set: BoxedSystemSet) {
match self {
SystemSetConfigs::SystemSetConfig(config) => {
config
.graph_info
.dependencies
.push(Dependency::new(DependencyKind::After, set));
}
SystemSetConfigs::Configs { configs, .. } => {
for config in configs {
config.after_inner(set.dyn_clone());
}
}
}
}

fn run_if<M>(mut self, condition: impl Condition<M>) -> Self {
self.conditions.push(new_condition(condition));
self
pub(super) fn run_if_inner(&mut self, condition: BoxedCondition) {
match self {
SystemSetConfigs::SystemSetConfig(config) => {
config.conditions.push(condition);
}
SystemSetConfigs::Configs {
collective_conditions,
..
} => {
collective_conditions.push(condition);
}
}
}

fn ambiguous_with<M>(mut self, set: impl IntoSystemSet<M>) -> Self {
ambiguous_with(&mut self.graph_info, Box::new(set.into_system_set()));
self
fn ambiguous_with_inner(&mut self, set: BoxedSystemSet) {
match self {
SystemSetConfigs::SystemSetConfig(config) => {
ambiguous_with(&mut config.graph_info, set);
}
SystemSetConfigs::Configs { configs, .. } => {
for config in configs {
config.ambiguous_with_inner(set.dyn_clone());
}
}
}
}

fn ambiguous_with_all(mut self) -> Self {
self.graph_info.ambiguous_with = Ambiguity::IgnoreAll;
self
fn ambiguous_with_all_inner(&mut self) {
match self {
SystemSetConfigs::SystemSetConfig(config) => {
config.graph_info.ambiguous_with = Ambiguity::IgnoreAll;
}
SystemSetConfigs::Configs { configs, .. } => {
for config in configs {
config.ambiguous_with_all_inner();
}
}
}
}
}

/// A collection of [`SystemSetConfig`].
pub struct SystemSetConfigs {
pub(super) sets: Vec<SystemSetConfig>,
/// If `true`, adds `before -> after` ordering constraints between the successive elements.
pub(super) chained: bool,
}

/// Types that can convert into a [`SystemSetConfigs`].
pub trait IntoSystemSetConfigs
where
Expand All @@ -534,6 +529,14 @@ where
self.into_configs().after(set)
}

/// Run the systems in this set(s) only if the [`Condition`] is `true`.
///
/// The `Condition` will be evaluated at most once (per schedule run),
/// the first time a system in this set(s) prepares to run.
fn run_if<M>(self, condition: impl Condition<M>) -> SystemSetConfigs {
self.into_configs().run_if(condition)
}

/// Suppress warnings and errors that would result from systems in these sets having ambiguities
/// (conflicting access but indeterminate order) with systems in `set`.
fn ambiguous_with<M>(self, set: impl IntoSystemSet<M>) -> SystemSetConfigs {
Expand Down Expand Up @@ -565,74 +568,88 @@ impl IntoSystemSetConfigs for SystemSetConfigs {
set.system_type().is_none(),
"adding arbitrary systems to a system type set is not allowed"
);
for config in &mut self.sets {
config.graph_info.sets.push(set.dyn_clone());
}
self.in_set_inner(set.dyn_clone());

self
}

fn before<M>(mut self, set: impl IntoSystemSet<M>) -> Self {
let set = set.into_system_set();
for config in &mut self.sets {
config
.graph_info
.dependencies
.push(Dependency::new(DependencyKind::Before, set.dyn_clone()));
}
self.before_inner(set.dyn_clone());

self
}

fn after<M>(mut self, set: impl IntoSystemSet<M>) -> Self {
let set = set.into_system_set();
for config in &mut self.sets {
config
.graph_info
.dependencies
.push(Dependency::new(DependencyKind::After, set.dyn_clone()));
}
self.after_inner(set.dyn_clone());

self
}

fn run_if<M>(mut self, condition: impl Condition<M>) -> SystemSetConfigs {
self.run_if_inner(new_condition(condition));

self
}

fn ambiguous_with<M>(mut self, set: impl IntoSystemSet<M>) -> Self {
let set = set.into_system_set();
for config in &mut self.sets {
ambiguous_with(&mut config.graph_info, set.dyn_clone());
}
self.ambiguous_with_inner(set.dyn_clone());

self
}

fn ambiguous_with_all(mut self) -> Self {
for config in &mut self.sets {
config.graph_info.ambiguous_with = Ambiguity::IgnoreAll;
}
self.ambiguous_with_all_inner();

self
}

fn chain(mut self) -> Self {
self.chained = true;
match &mut self {
SystemSetConfigs::SystemSetConfig(_) => { /* no op */ }
SystemSetConfigs::Configs { chained, .. } => {
*chained = true;
}
}
self
}
}

impl<S: SystemSet> IntoSystemSetConfigs for S {
fn into_configs(self) -> SystemSetConfigs {
SystemSetConfigs::SystemSetConfig(SystemSetConfig::new(Box::new(self)))
}
}

impl IntoSystemSetConfigs for BoxedSystemSet {
fn into_configs(self) -> SystemSetConfigs {
SystemSetConfigs::SystemSetConfig(SystemSetConfig::new(self))
}
}

impl IntoSystemSetConfigs for SystemSetConfig {
fn into_configs(self) -> SystemSetConfigs {
SystemSetConfigs::SystemSetConfig(self)
}
}

macro_rules! impl_system_set_collection {
($($set: ident),*) => {
impl<$($set: IntoSystemSetConfig),*> IntoSystemSetConfigs for ($($set,)*)
impl<$($set: IntoSystemSetConfigs),*> IntoSystemSetConfigs for ($($set,)*)
{
#[allow(non_snake_case)]
fn into_configs(self) -> SystemSetConfigs {
let ($($set,)*) = self;
SystemSetConfigs {
sets: vec![$($set.into_config(),)*],
SystemSetConfigs::Configs {
configs: vec![$($set.into_configs(),)*],
collective_conditions: Vec::new(),
chained: false,
}
}
}
}
}

all_tuples!(impl_system_set_collection, 0, 15, S);
all_tuples!(impl_system_set_collection, 1, 20, S);

0 comments on commit 2ad6fc9

Please sign in to comment.