bevy/crates/bevy_ecs/src/schedule/system_set.rs
Daniel McNab c893b99224 Optional .system (#2398)
This can be your 6 months post-christmas present.

# Objective

- Make `.system` optional
- yeet
- It's ugly
- Alternative title: `.system` is dead; long live `.system`
- **yeet**

## Solution

- Use a higher ranked lifetime, and some trait magic.

N.B. This PR does not actually remove any `.system`s, except in a couple of examples. Once this is merged we can do that piecemeal across crates, and decide on syntax for labels.
2021-06-27 00:40:09 +00:00

151 lines
4.4 KiB
Rust

use crate::{
component::Component,
schedule::{
AmbiguitySetLabel, BoxedAmbiguitySetLabel, BoxedSystemLabel, IntoRunCriteria,
RunCriteriaDescriptorOrLabel, State, SystemDescriptor, SystemLabel,
},
};
use std::{fmt::Debug, hash::Hash};
use super::IntoSystemDescriptor;
/// A builder for describing several systems at the same time.
pub struct SystemSet {
pub(crate) systems: Vec<SystemDescriptor>,
pub(crate) run_criteria: Option<RunCriteriaDescriptorOrLabel>,
pub(crate) labels: Vec<BoxedSystemLabel>,
pub(crate) before: Vec<BoxedSystemLabel>,
pub(crate) after: Vec<BoxedSystemLabel>,
pub(crate) ambiguity_sets: Vec<BoxedAmbiguitySetLabel>,
}
impl Default for SystemSet {
fn default() -> SystemSet {
SystemSet {
systems: Vec::new(),
run_criteria: None,
labels: Vec::new(),
before: Vec::new(),
after: Vec::new(),
ambiguity_sets: Vec::new(),
}
}
}
impl SystemSet {
pub fn new() -> Self {
Default::default()
}
pub fn on_update<T>(s: T) -> SystemSet
where
T: Component + Debug + Clone + Eq + Hash,
{
Self::new().with_run_criteria(State::<T>::on_update(s))
}
pub fn on_inactive_update<T>(s: T) -> SystemSet
where
T: Component + Debug + Clone + Eq + Hash,
{
Self::new().with_run_criteria(State::<T>::on_inactive_update(s))
}
pub fn on_in_stack_update<T>(s: T) -> SystemSet
where
T: Component + Debug + Clone + Eq + Hash,
{
Self::new().with_run_criteria(State::<T>::on_in_stack_update(s))
}
pub fn on_enter<T>(s: T) -> SystemSet
where
T: Component + Debug + Clone + Eq + Hash,
{
Self::new().with_run_criteria(State::<T>::on_enter(s))
}
pub fn on_exit<T>(s: T) -> SystemSet
where
T: Component + Debug + Clone + Eq + Hash,
{
Self::new().with_run_criteria(State::<T>::on_exit(s))
}
pub fn on_pause<T>(s: T) -> SystemSet
where
T: Component + Debug + Clone + Eq + Hash,
{
Self::new().with_run_criteria(State::<T>::on_pause(s))
}
pub fn on_resume<T>(s: T) -> SystemSet
where
T: Component + Debug + Clone + Eq + Hash,
{
Self::new().with_run_criteria(State::<T>::on_resume(s))
}
pub fn in_ambiguity_set(mut self, set: impl AmbiguitySetLabel) -> Self {
self.ambiguity_sets.push(Box::new(set));
self
}
pub fn with_system<Params>(mut self, system: impl IntoSystemDescriptor<Params>) -> Self {
self.systems.push(system.into_descriptor());
self
}
pub fn with_run_criteria<Marker>(mut self, run_criteria: impl IntoRunCriteria<Marker>) -> Self {
self.run_criteria = Some(run_criteria.into());
self
}
pub fn label(mut self, label: impl SystemLabel) -> Self {
self.labels.push(Box::new(label));
self
}
pub fn before(mut self, label: impl SystemLabel) -> Self {
self.before.push(Box::new(label));
self
}
pub fn after(mut self, label: impl SystemLabel) -> Self {
self.after.push(Box::new(label));
self
}
pub(crate) fn bake(self) -> (Option<RunCriteriaDescriptorOrLabel>, Vec<SystemDescriptor>) {
let SystemSet {
mut systems,
run_criteria,
labels,
before,
after,
ambiguity_sets,
} = self;
for descriptor in &mut systems {
match descriptor {
SystemDescriptor::Parallel(descriptor) => {
descriptor.labels.extend(labels.iter().cloned());
descriptor.before.extend(before.iter().cloned());
descriptor.after.extend(after.iter().cloned());
descriptor
.ambiguity_sets
.extend(ambiguity_sets.iter().cloned());
}
SystemDescriptor::Exclusive(descriptor) => {
descriptor.labels.extend(labels.iter().cloned());
descriptor.before.extend(before.iter().cloned());
descriptor.after.extend(after.iter().cloned());
descriptor
.ambiguity_sets
.extend(ambiguity_sets.iter().cloned());
}
}
}
(run_criteria, systems)
}
}