use crate::system::BoxedSystem; pub type BoxedCondition = BoxedSystem<(), bool>; /// A system that determines if one or more scheduled systems should run. /// /// Implemented for functions and closures that convert into [`System`](crate::system::System) /// with [read-only](crate::system::ReadOnlySystemParam) parameters. pub trait Condition: sealed::Condition {} impl Condition for F where F: sealed::Condition {} mod sealed { use crate::system::{IntoSystem, IsFunctionSystem, ReadOnlySystemParam, SystemParamFunction}; pub trait Condition: IntoSystem<(), bool, Params> {} impl Condition<(IsFunctionSystem, Params, Marker)> for F where F: SystemParamFunction<(), bool, Params, Marker> + Send + Sync + 'static, Params: ReadOnlySystemParam + 'static, Marker: 'static, { } } pub mod common_conditions { use crate::schedule::{State, States}; use crate::system::{Res, Resource}; /// Generates a [`Condition`](super::Condition)-satisfying closure that returns `true` /// if the first time the condition is run and false every time after pub fn run_once() -> impl FnMut() -> bool { let mut has_run = false; move || { if !has_run { has_run = true; true } else { false } } } /// Generates a [`Condition`](super::Condition)-satisfying closure that returns `true` /// if the resource exists. pub fn resource_exists() -> impl FnMut(Option>) -> bool where T: Resource, { move |res: Option>| res.is_some() } /// Generates a [`Condition`](super::Condition)-satisfying closure that returns `true` /// if the resource is equal to `value`. /// /// # Panics /// /// The condition will panic if the resource does not exist. pub fn resource_equals(value: T) -> impl FnMut(Res) -> bool where T: Resource + PartialEq, { move |res: Res| *res == value } /// Generates a [`Condition`](super::Condition)-satisfying closure that returns `true` /// if the resource exists and is equal to `value`. /// /// The condition will return `false` if the resource does not exist. pub fn resource_exists_and_equals(value: T) -> impl FnMut(Option>) -> bool where T: Resource + PartialEq, { move |res: Option>| match res { Some(res) => *res == value, None => false, } } /// Generates a [`Condition`](super::Condition)-satisfying closure that returns `true` /// if the state machine exists. pub fn state_exists() -> impl FnMut(Option>>) -> bool { move |current_state: Option>>| current_state.is_some() } /// Generates a [`Condition`](super::Condition)-satisfying closure that returns `true` /// if the state machine is currently in `state`. /// /// # Panics /// /// The condition will panic if the resource does not exist. pub fn state_equals(state: S) -> impl FnMut(Res>) -> bool { move |current_state: Res>| current_state.0 == state } /// Generates a [`Condition`](super::Condition)-satisfying closure that returns `true` /// if the state machine exists and is currently in `state`. /// /// The condition will return `false` if the state does not exist. pub fn state_exists_and_equals( state: S, ) -> impl FnMut(Option>>) -> bool { move |current_state: Option>>| match current_state { Some(current_state) => current_state.0 == state, None => false, } } }