leafwing_input_manager/user_input/
testing_utils.rs

1//! Utilities for testing user input.
2
3use bevy::{
4    app::App,
5    ecs::system::SystemState,
6    input::gamepad::Gamepad,
7    math::Vec2,
8    prelude::{Entity, Query, With, World},
9};
10
11use super::{Axislike, Buttonlike, DualAxislike, updating::CentralInputStore};
12
13#[cfg(feature = "gamepad")]
14use crate::user_input::gamepad::find_gamepad;
15
16#[cfg(not(feature = "gamepad"))]
17fn find_gamepad(_: Option<Query<Entity, With<Gamepad>>>) -> Entity {
18    Entity::PLACEHOLDER
19}
20
21/// A trait used to quickly fetch the value of a given [`UserInput`](crate::user_input::UserInput).
22///
23/// This can be useful for testing purposes.
24pub trait FetchUserInput {
25    /// Returns `true` if the given [`Buttonlike`] input is currently pressed.
26    fn read_pressed(&mut self, input: impl Buttonlike) -> bool;
27
28    /// Returns the value of the given [`Buttonlike`] input.
29    fn read_button_value(&mut self, input: impl Buttonlike) -> f32;
30
31    /// Returns the value of the given [`Axislike`] input.
32    fn read_axis_value(&mut self, input: impl Axislike) -> f32;
33
34    /// Returns the value of the given [`DualAxislike`] input.
35    fn read_dual_axis_values(&mut self, input: impl DualAxislike) -> Vec2;
36}
37
38impl FetchUserInput for World {
39    fn read_pressed(&mut self, input: impl Buttonlike) -> bool {
40        let mut query_state = SystemState::<Query<Entity, With<Gamepad>>>::new(self);
41        let query = query_state.get(self);
42        let gamepad = find_gamepad(Some(query));
43        let input_store = self.resource::<CentralInputStore>();
44
45        input.pressed(input_store, gamepad)
46    }
47
48    fn read_button_value(&mut self, input: impl Buttonlike) -> f32 {
49        let mut query_state = SystemState::<Query<Entity, With<Gamepad>>>::new(self);
50        let query = query_state.get(self);
51        let gamepad = find_gamepad(Some(query));
52        let input_store = self.resource::<CentralInputStore>();
53
54        input.value(input_store, gamepad)
55    }
56
57    fn read_axis_value(&mut self, input: impl Axislike) -> f32 {
58        let mut query_state = SystemState::<Query<Entity, With<Gamepad>>>::new(self);
59        let query = query_state.get(self);
60        let gamepad = find_gamepad(Some(query));
61        let input_store = self.resource::<CentralInputStore>();
62
63        input.value(input_store, gamepad)
64    }
65
66    fn read_dual_axis_values(&mut self, input: impl DualAxislike) -> Vec2 {
67        let mut query_state = SystemState::<Query<Entity, With<Gamepad>>>::new(self);
68        let query = query_state.get(self);
69        let gamepad = find_gamepad(Some(query));
70        let input_store = self.resource::<CentralInputStore>();
71
72        input.axis_pair(input_store, gamepad)
73    }
74}
75
76impl FetchUserInput for App {
77    fn read_pressed(&mut self, input: impl Buttonlike) -> bool {
78        self.world_mut().read_pressed(input)
79    }
80
81    fn read_button_value(&mut self, input: impl Buttonlike) -> f32 {
82        self.world_mut().read_button_value(input)
83    }
84
85    fn read_axis_value(&mut self, input: impl Axislike) -> f32 {
86        self.world_mut().read_axis_value(input)
87    }
88
89    fn read_dual_axis_values(&mut self, input: impl DualAxislike) -> Vec2 {
90        self.world_mut().read_dual_axis_values(input)
91    }
92}