diff --git a/crates/bevy_ecs/src/schedule/condition.rs b/crates/bevy_ecs/src/schedule/condition.rs index 52630acc2b..fa631d3834 100644 --- a/crates/bevy_ecs/src/schedule/condition.rs +++ b/crates/bevy_ecs/src/schedule/condition.rs @@ -8,13 +8,55 @@ use crate::system::{CombinatorSystem, Combine, IntoSystem, ReadOnlySystem, Syste use crate::world::unsafe_world_cell::UnsafeWorldCell; use crate::world::World; -pub type BoxedCondition = Box>; +pub type BoxedCondition = Box>; /// A system that determines if one or more scheduled systems should run. /// -/// Implemented for functions and closures that convert into [`System`](crate::system::System) +/// Implemented for functions and closures that convert into [`System`](crate::system::System) /// with [read-only](crate::system::ReadOnlySystemParam) parameters. -pub trait Condition: sealed::Condition { +/// +/// # Examples +/// A condition that returns true every other time it's called. +/// ``` +/// # use bevy_ecs::prelude::*; +/// fn every_other_time() -> impl Condition<()> { +/// IntoSystem::into_system(|mut flag: Local| { +/// *flag = !*flag; +/// *flag +/// }) +/// } +/// +/// # #[derive(Resource)] struct DidRun(bool); +/// # fn my_system(mut did_run: ResMut) { did_run.0 = true; } +/// # let mut schedule = Schedule::new(); +/// schedule.add_systems(my_system.run_if(every_other_time())); +/// # let mut world = World::new(); +/// # world.insert_resource(DidRun(false)); +/// # schedule.run(&mut world); +/// # assert!(world.resource::().0); +/// # world.insert_resource(DidRun(false)); +/// # schedule.run(&mut world); +/// # assert!(!world.resource::().0); +/// ``` +/// +/// A condition that takes a bool as an input and returns it unchanged. +/// +/// ``` +/// # use bevy_ecs::prelude::*; +/// fn identity() -> impl Condition<(), bool> { +/// IntoSystem::into_system(|In(x)| x) +/// } +/// +/// # fn always_true() -> bool { true } +/// # let mut schedule = Schedule::new(); +/// # #[derive(Resource)] struct DidRun(bool); +/// # fn my_system(mut did_run: ResMut) { did_run.0 = true; } +/// schedule.add_systems(my_system.run_if(always_true.pipe(identity()))); +/// # let mut world = World::new(); +/// # world.insert_resource(DidRun(false)); +/// # schedule.run(&mut world); +/// # assert!(world.resource::().0); +pub trait Condition: sealed::Condition { /// Returns a new run condition that only returns `true` /// if both this one and the passed `and_then` return `true`. /// @@ -59,7 +101,7 @@ pub trait Condition: sealed::Condition { /// Note that in this case, it's better to just use the run condition [`resource_exists_and_equals`]. /// /// [`resource_exists_and_equals`]: common_conditions::resource_exists_and_equals - fn and_then>(self, and_then: C) -> AndThen { + fn and_then>(self, and_then: C) -> AndThen { let a = IntoSystem::into_system(self); let b = IntoSystem::into_system(and_then); let name = format!("{} && {}", a.name(), b.name()); @@ -106,7 +148,7 @@ pub trait Condition: sealed::Condition { /// # app.run(&mut world); /// # assert!(world.resource::().0); /// ``` - fn or_else>(self, or_else: C) -> OrElse { + fn or_else>(self, or_else: C) -> OrElse { let a = IntoSystem::into_system(self); let b = IntoSystem::into_system(or_else); let name = format!("{} || {}", a.name(), b.name()); @@ -114,22 +156,22 @@ pub trait Condition: sealed::Condition { } } -impl Condition for F where F: sealed::Condition {} +impl Condition for F where F: sealed::Condition {} mod sealed { use crate::system::{IntoSystem, ReadOnlySystem}; - pub trait Condition: - IntoSystem<(), bool, Marker, System = Self::ReadOnlySystem> + pub trait Condition: + IntoSystem { // This associated type is necessary to let the compiler // know that `Self::System` is `ReadOnlySystem`. - type ReadOnlySystem: ReadOnlySystem; + type ReadOnlySystem: ReadOnlySystem; } - impl Condition for F + impl Condition for F where - F: IntoSystem<(), bool, Marker>, + F: IntoSystem, F::System: ReadOnlySystem, { type ReadOnlySystem = F::System;