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);
|
||||
/// 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;
|
||||
move || {
|
||||
if !has_run {
|
||||
@ -209,7 +209,7 @@ pub mod common_conditions {
|
||||
/// app.run(&mut world);
|
||||
/// 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
|
||||
T: Resource,
|
||||
{
|
||||
@ -332,7 +332,7 @@ pub mod common_conditions {
|
||||
/// app.run(&mut world);
|
||||
/// 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
|
||||
T: Resource,
|
||||
{
|
||||
@ -389,7 +389,7 @@ pub mod common_conditions {
|
||||
/// app.run(&mut world);
|
||||
/// 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
|
||||
T: Resource,
|
||||
{
|
||||
@ -446,7 +446,7 @@ pub mod common_conditions {
|
||||
/// app.run(&mut world);
|
||||
/// 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
|
||||
T: Resource,
|
||||
{
|
||||
@ -518,7 +518,7 @@ pub mod common_conditions {
|
||||
/// app.run(&mut world);
|
||||
/// 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
|
||||
T: Resource,
|
||||
{
|
||||
@ -573,7 +573,7 @@ pub mod common_conditions {
|
||||
/// app.run(&mut world);
|
||||
/// 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
|
||||
T: Resource,
|
||||
{
|
||||
@ -630,7 +630,7 @@ pub mod common_conditions {
|
||||
/// app.run(&mut world);
|
||||
/// 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()
|
||||
}
|
||||
|
||||
@ -684,7 +684,7 @@ pub mod common_conditions {
|
||||
/// app.run(&mut world);
|
||||
/// 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
|
||||
}
|
||||
|
||||
@ -742,7 +742,7 @@ pub mod common_conditions {
|
||||
/// ```
|
||||
pub fn state_exists_and_equals<S: States>(
|
||||
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 {
|
||||
Some(current_state) => current_state.0 == state,
|
||||
None => false,
|
||||
@ -802,7 +802,7 @@ pub mod common_conditions {
|
||||
/// app.run(&mut world);
|
||||
/// 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()
|
||||
}
|
||||
|
||||
@ -841,7 +841,7 @@ pub mod common_conditions {
|
||||
/// app.run(&mut world);
|
||||
/// 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
|
||||
// calls of the run condition. Simply checking `is_empty` would not be enough.
|
||||
// PERF: note that `count` is efficient (not actually looping/iterating),
|
||||
@ -882,7 +882,7 @@ pub mod common_conditions {
|
||||
/// app.run(&mut world);
|
||||
/// 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()
|
||||
}
|
||||
|
||||
@ -915,7 +915,10 @@ pub mod common_conditions {
|
||||
/// app.run(&mut world);
|
||||
/// 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)
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
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.
|
||||
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
|
||||
T: Copy + Eq + Hash + Send + Sync + 'static,
|
||||
{
|
||||
@ -81,7 +81,7 @@ where
|
||||
///
|
||||
/// # 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
|
||||
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.
|
||||
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
|
||||
T: Copy + Eq + Hash + Send + Sync + 'static,
|
||||
{
|
||||
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
|
||||
/// [`Timer::times_finished_this_tick`] to address the problem mentioned above), or
|
||||
/// 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);
|
||||
move |time: Res<Time>| {
|
||||
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
|
||||
/// than the fixed timestep period, since the timer may complete multiple times in
|
||||
/// 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);
|
||||
move |time: Res<FixedTime>| {
|
||||
timer.tick(time.period);
|
||||
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