add Clone to common conditions (#8060)
This commit is contained in:
parent
884b9b62af
commit
7c4a0eb768
@ -169,7 +169,7 @@ pub mod common_conditions {
|
|||||||
/// app.run(&mut world);
|
/// app.run(&mut world);
|
||||||
/// assert_eq!(world.resource::<Counter>().0, 1);
|
/// assert_eq!(world.resource::<Counter>().0, 1);
|
||||||
/// ```
|
/// ```
|
||||||
pub fn run_once() -> impl FnMut() -> bool {
|
pub fn run_once() -> impl FnMut() -> bool + Clone {
|
||||||
let mut has_run = false;
|
let mut has_run = false;
|
||||||
move || {
|
move || {
|
||||||
if !has_run {
|
if !has_run {
|
||||||
@ -209,7 +209,7 @@ pub mod common_conditions {
|
|||||||
/// app.run(&mut world);
|
/// app.run(&mut world);
|
||||||
/// assert_eq!(world.resource::<Counter>().0, 1);
|
/// assert_eq!(world.resource::<Counter>().0, 1);
|
||||||
/// ```
|
/// ```
|
||||||
pub fn resource_exists<T>() -> impl FnMut(Option<Res<T>>) -> bool
|
pub fn resource_exists<T>() -> impl FnMut(Option<Res<T>>) -> bool + Clone
|
||||||
where
|
where
|
||||||
T: Resource,
|
T: Resource,
|
||||||
{
|
{
|
||||||
@ -332,7 +332,7 @@ pub mod common_conditions {
|
|||||||
/// app.run(&mut world);
|
/// app.run(&mut world);
|
||||||
/// assert_eq!(world.resource::<Counter>().0, 1);
|
/// assert_eq!(world.resource::<Counter>().0, 1);
|
||||||
/// ```
|
/// ```
|
||||||
pub fn resource_added<T>() -> impl FnMut(Option<Res<T>>) -> bool
|
pub fn resource_added<T>() -> impl FnMut(Option<Res<T>>) -> bool + Clone
|
||||||
where
|
where
|
||||||
T: Resource,
|
T: Resource,
|
||||||
{
|
{
|
||||||
@ -389,7 +389,7 @@ pub mod common_conditions {
|
|||||||
/// app.run(&mut world);
|
/// app.run(&mut world);
|
||||||
/// assert_eq!(world.resource::<Counter>().0, 51);
|
/// assert_eq!(world.resource::<Counter>().0, 51);
|
||||||
/// ```
|
/// ```
|
||||||
pub fn resource_changed<T>() -> impl FnMut(Res<T>) -> bool
|
pub fn resource_changed<T>() -> impl FnMut(Res<T>) -> bool + Clone
|
||||||
where
|
where
|
||||||
T: Resource,
|
T: Resource,
|
||||||
{
|
{
|
||||||
@ -446,7 +446,7 @@ pub mod common_conditions {
|
|||||||
/// app.run(&mut world);
|
/// app.run(&mut world);
|
||||||
/// assert_eq!(world.resource::<Counter>().0, 51);
|
/// assert_eq!(world.resource::<Counter>().0, 51);
|
||||||
/// ```
|
/// ```
|
||||||
pub fn resource_exists_and_changed<T>() -> impl FnMut(Option<Res<T>>) -> bool
|
pub fn resource_exists_and_changed<T>() -> impl FnMut(Option<Res<T>>) -> bool + Clone
|
||||||
where
|
where
|
||||||
T: Resource,
|
T: Resource,
|
||||||
{
|
{
|
||||||
@ -518,7 +518,7 @@ pub mod common_conditions {
|
|||||||
/// app.run(&mut world);
|
/// app.run(&mut world);
|
||||||
/// assert_eq!(world.contains_resource::<MyResource>(), true);
|
/// assert_eq!(world.contains_resource::<MyResource>(), true);
|
||||||
/// ```
|
/// ```
|
||||||
pub fn resource_changed_or_removed<T>() -> impl FnMut(Option<Res<T>>) -> bool
|
pub fn resource_changed_or_removed<T>() -> impl FnMut(Option<Res<T>>) -> bool + Clone
|
||||||
where
|
where
|
||||||
T: Resource,
|
T: Resource,
|
||||||
{
|
{
|
||||||
@ -573,7 +573,7 @@ pub mod common_conditions {
|
|||||||
/// app.run(&mut world);
|
/// app.run(&mut world);
|
||||||
/// assert_eq!(world.resource::<Counter>().0, 1);
|
/// assert_eq!(world.resource::<Counter>().0, 1);
|
||||||
/// ```
|
/// ```
|
||||||
pub fn resource_removed<T>() -> impl FnMut(Option<Res<T>>) -> bool
|
pub fn resource_removed<T>() -> impl FnMut(Option<Res<T>>) -> bool + Clone
|
||||||
where
|
where
|
||||||
T: Resource,
|
T: Resource,
|
||||||
{
|
{
|
||||||
@ -630,7 +630,7 @@ pub mod common_conditions {
|
|||||||
/// app.run(&mut world);
|
/// app.run(&mut world);
|
||||||
/// assert_eq!(world.resource::<Counter>().0, 1);
|
/// assert_eq!(world.resource::<Counter>().0, 1);
|
||||||
/// ```
|
/// ```
|
||||||
pub fn state_exists<S: States>() -> impl FnMut(Option<Res<State<S>>>) -> bool {
|
pub fn state_exists<S: States>() -> impl FnMut(Option<Res<State<S>>>) -> bool + Clone {
|
||||||
move |current_state: Option<Res<State<S>>>| current_state.is_some()
|
move |current_state: Option<Res<State<S>>>| current_state.is_some()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -684,7 +684,7 @@ pub mod common_conditions {
|
|||||||
/// app.run(&mut world);
|
/// app.run(&mut world);
|
||||||
/// assert_eq!(world.resource::<Counter>().0, 0);
|
/// assert_eq!(world.resource::<Counter>().0, 0);
|
||||||
/// ```
|
/// ```
|
||||||
pub fn in_state<S: States>(state: S) -> impl FnMut(Res<State<S>>) -> bool {
|
pub fn in_state<S: States>(state: S) -> impl FnMut(Res<State<S>>) -> bool + Clone {
|
||||||
move |current_state: Res<State<S>>| current_state.0 == state
|
move |current_state: Res<State<S>>| current_state.0 == state
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -742,7 +742,7 @@ pub mod common_conditions {
|
|||||||
/// ```
|
/// ```
|
||||||
pub fn state_exists_and_equals<S: States>(
|
pub fn state_exists_and_equals<S: States>(
|
||||||
state: S,
|
state: S,
|
||||||
) -> impl FnMut(Option<Res<State<S>>>) -> bool {
|
) -> impl FnMut(Option<Res<State<S>>>) -> bool + Clone {
|
||||||
move |current_state: Option<Res<State<S>>>| match current_state {
|
move |current_state: Option<Res<State<S>>>| match current_state {
|
||||||
Some(current_state) => current_state.0 == state,
|
Some(current_state) => current_state.0 == state,
|
||||||
None => false,
|
None => false,
|
||||||
@ -802,7 +802,7 @@ pub mod common_conditions {
|
|||||||
/// app.run(&mut world);
|
/// app.run(&mut world);
|
||||||
/// assert_eq!(world.resource::<Counter>().0, 2);
|
/// assert_eq!(world.resource::<Counter>().0, 2);
|
||||||
/// ```
|
/// ```
|
||||||
pub fn state_changed<S: States>() -> impl FnMut(Res<State<S>>) -> bool {
|
pub fn state_changed<S: States>() -> impl FnMut(Res<State<S>>) -> bool + Clone {
|
||||||
move |current_state: Res<State<S>>| current_state.is_changed()
|
move |current_state: Res<State<S>>| current_state.is_changed()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -841,7 +841,7 @@ pub mod common_conditions {
|
|||||||
/// app.run(&mut world);
|
/// app.run(&mut world);
|
||||||
/// assert_eq!(world.resource::<Counter>().0, 1);
|
/// assert_eq!(world.resource::<Counter>().0, 1);
|
||||||
/// ```
|
/// ```
|
||||||
pub fn on_event<T: Event>() -> impl FnMut(EventReader<T>) -> bool {
|
pub fn on_event<T: Event>() -> impl FnMut(EventReader<T>) -> bool + Clone {
|
||||||
// The events need to be consumed, so that there are no false positives on subsequent
|
// The events need to be consumed, so that there are no false positives on subsequent
|
||||||
// calls of the run condition. Simply checking `is_empty` would not be enough.
|
// calls of the run condition. Simply checking `is_empty` would not be enough.
|
||||||
// PERF: note that `count` is efficient (not actually looping/iterating),
|
// PERF: note that `count` is efficient (not actually looping/iterating),
|
||||||
@ -882,7 +882,7 @@ pub mod common_conditions {
|
|||||||
/// app.run(&mut world);
|
/// app.run(&mut world);
|
||||||
/// assert_eq!(world.resource::<Counter>().0, 1);
|
/// assert_eq!(world.resource::<Counter>().0, 1);
|
||||||
/// ```
|
/// ```
|
||||||
pub fn any_with_component<T: Component>() -> impl FnMut(Query<(), With<T>>) -> bool {
|
pub fn any_with_component<T: Component>() -> impl FnMut(Query<(), With<T>>) -> bool + Clone {
|
||||||
move |query: Query<(), With<T>>| !query.is_empty()
|
move |query: Query<(), With<T>>| !query.is_empty()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -915,7 +915,10 @@ pub mod common_conditions {
|
|||||||
/// app.run(&mut world);
|
/// app.run(&mut world);
|
||||||
/// assert_eq!(world.resource::<Counter>().0, 0);
|
/// assert_eq!(world.resource::<Counter>().0, 0);
|
||||||
/// ```
|
/// ```
|
||||||
pub fn not<Marker>(condition: impl Condition<Marker>) -> impl Condition<()> {
|
pub fn not<Marker, T>(condition: T) -> impl Condition<()>
|
||||||
|
where
|
||||||
|
T: Condition<Marker>,
|
||||||
|
{
|
||||||
condition.pipe(|In(val): In<bool>| !val)
|
condition.pipe(|In(val): In<bool>| !val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ use std::hash::Hash;
|
|||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
pub fn input_toggle_active<T>(default: bool, input: T) -> impl FnMut(Res<Input<T>>) -> bool
|
pub fn input_toggle_active<T>(default: bool, input: T) -> impl FnMut(Res<Input<T>>) -> bool + Clone
|
||||||
where
|
where
|
||||||
T: Copy + Eq + Hash + Send + Sync + 'static,
|
T: Copy + Eq + Hash + Send + Sync + 'static,
|
||||||
{
|
{
|
||||||
@ -60,7 +60,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Run condition that is active if [`Input::pressed`] is true for the given input.
|
/// Run condition that is active if [`Input::pressed`] is true for the given input.
|
||||||
pub fn input_pressed<T>(input: T) -> impl FnMut(Res<Input<T>>) -> bool
|
pub fn input_pressed<T>(input: T) -> impl FnMut(Res<Input<T>>) -> bool + Clone
|
||||||
where
|
where
|
||||||
T: Copy + Eq + Hash + Send + Sync + 'static,
|
T: Copy + Eq + Hash + Send + Sync + 'static,
|
||||||
{
|
{
|
||||||
@ -81,7 +81,7 @@ where
|
|||||||
///
|
///
|
||||||
/// # fn jump() {}
|
/// # fn jump() {}
|
||||||
/// ```
|
/// ```
|
||||||
pub fn input_just_pressed<T>(input: T) -> impl FnMut(Res<Input<T>>) -> bool
|
pub fn input_just_pressed<T>(input: T) -> impl FnMut(Res<Input<T>>) -> bool + Clone
|
||||||
where
|
where
|
||||||
T: Copy + Eq + Hash + Send + Sync + 'static,
|
T: Copy + Eq + Hash + Send + Sync + 'static,
|
||||||
{
|
{
|
||||||
@ -89,9 +89,29 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Run condition that is active if [`Input::just_released`] is true for the given input.
|
/// Run condition that is active if [`Input::just_released`] is true for the given input.
|
||||||
pub fn input_just_released<T>(input: T) -> impl FnMut(Res<Input<T>>) -> bool
|
pub fn input_just_released<T>(input: T) -> impl FnMut(Res<Input<T>>) -> bool + Clone
|
||||||
where
|
where
|
||||||
T: Copy + Eq + Hash + Send + Sync + 'static,
|
T: Copy + Eq + Hash + Send + Sync + 'static,
|
||||||
{
|
{
|
||||||
move |inputs: Res<Input<T>>| inputs.just_released(input)
|
move |inputs: Res<Input<T>>| inputs.just_released(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use bevy::prelude::{IntoSystemConfigs, KeyCode, Schedule};
|
||||||
|
|
||||||
|
fn test_system() {}
|
||||||
|
|
||||||
|
// Ensure distributive_run_if compiles with the common conditions.
|
||||||
|
#[test]
|
||||||
|
fn distributive_run_if_compiles() {
|
||||||
|
Schedule::default().add_systems(
|
||||||
|
(test_system, test_system)
|
||||||
|
.distributive_run_if(input_toggle_active(false, KeyCode::Escape))
|
||||||
|
.distributive_run_if(input_pressed(KeyCode::Escape))
|
||||||
|
.distributive_run_if(input_just_pressed(KeyCode::Escape))
|
||||||
|
.distributive_run_if(input_just_released(KeyCode::Escape)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -32,7 +32,7 @@ use bevy_utils::Duration;
|
|||||||
/// For more accurate timers, use the [`Timer`] class directly (see
|
/// For more accurate timers, use the [`Timer`] class directly (see
|
||||||
/// [`Timer::times_finished_this_tick`] to address the problem mentioned above), or
|
/// [`Timer::times_finished_this_tick`] to address the problem mentioned above), or
|
||||||
/// use fixed timesteps that allow systems to run multiple times per frame.
|
/// use fixed timesteps that allow systems to run multiple times per frame.
|
||||||
pub fn on_timer(duration: Duration) -> impl FnMut(Res<Time>) -> bool {
|
pub fn on_timer(duration: Duration) -> impl FnMut(Res<Time>) -> bool + Clone {
|
||||||
let mut timer = Timer::new(duration, TimerMode::Repeating);
|
let mut timer = Timer::new(duration, TimerMode::Repeating);
|
||||||
move |time: Res<Time>| {
|
move |time: Res<Time>| {
|
||||||
timer.tick(time.delta());
|
timer.tick(time.delta());
|
||||||
@ -67,10 +67,28 @@ pub fn on_timer(duration: Duration) -> impl FnMut(Res<Time>) -> bool {
|
|||||||
/// Note that this run condition may not behave as expected if `duration` is smaller
|
/// Note that this run condition may not behave as expected if `duration` is smaller
|
||||||
/// than the fixed timestep period, since the timer may complete multiple times in
|
/// than the fixed timestep period, since the timer may complete multiple times in
|
||||||
/// one fixed update.
|
/// one fixed update.
|
||||||
pub fn on_fixed_timer(duration: Duration) -> impl FnMut(Res<FixedTime>) -> bool {
|
pub fn on_fixed_timer(duration: Duration) -> impl FnMut(Res<FixedTime>) -> bool + Clone {
|
||||||
let mut timer = Timer::new(duration, TimerMode::Repeating);
|
let mut timer = Timer::new(duration, TimerMode::Repeating);
|
||||||
move |time: Res<FixedTime>| {
|
move |time: Res<FixedTime>| {
|
||||||
timer.tick(time.period);
|
timer.tick(time.period);
|
||||||
timer.just_finished()
|
timer.just_finished()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use bevy_ecs::schedule::{IntoSystemConfigs, Schedule};
|
||||||
|
|
||||||
|
fn test_system() {}
|
||||||
|
|
||||||
|
// Ensure distributive_run_if compiles with the common conditions.
|
||||||
|
#[test]
|
||||||
|
fn distributive_run_if_compiles() {
|
||||||
|
Schedule::default().add_systems(
|
||||||
|
(test_system, test_system)
|
||||||
|
.distributive_run_if(on_timer(Duration::new(1, 0)))
|
||||||
|
.distributive_run_if(on_fixed_timer(Duration::new(1, 0))),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user