Skip to content

Commit

Permalink
Short-circuiting and add conflicting_inputs.rs
Browse files Browse the repository at this point in the history
  • Loading branch information
Shute052 committed Feb 20, 2024
1 parent afe6714 commit cd48808
Show file tree
Hide file tree
Showing 3 changed files with 8 additions and 81 deletions.
3 changes: 2 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ pub mod axislike;
pub mod buttonlike;
pub mod clashing_inputs;
pub mod common_conditions;
pub mod conflicting_inputs;
mod display_impl;
pub mod errors;
pub mod input_map;
Expand Down Expand Up @@ -45,9 +46,9 @@ pub mod prelude {
pub use crate::input_mocking::{MockInput, QueryInput};
pub use crate::user_input::{InputKind, Modifier, UserInput};

pub use crate::conflicting_inputs::TrackingInputType;
pub use crate::plugin::ToggleActions;
pub use crate::plugin::{InputManagerPlugin, InputManagerSystem};
pub use crate::systems::TrackingInputType;
pub use crate::{Actionlike, InputManagerBundle};
}

Expand Down
5 changes: 5 additions & 0 deletions src/plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ use crate::axislike::{
};
use crate::buttonlike::{MouseMotionDirection, MouseWheelDirection};
use crate::clashing_inputs::ClashStrategy;
#[cfg(feature = "egui")]
use crate::conflicting_inputs::prioritize_egui_inputs;
#[cfg(all(feature = "ui", not(feature = "no_ui_priority")))]
use crate::conflicting_inputs::prioritize_ui_inputs;
use crate::conflicting_inputs::TrackingInputType;
use crate::input_map::InputMap;
use crate::timing::Timing;
use crate::user_input::{InputKind, Modifier, UserInput};
Expand Down
81 changes: 1 addition & 80 deletions src/systems.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#[cfg(feature = "ui")]
use crate::action_driver::ActionStateDriver;
use crate::conflicting_inputs::TrackingInputType;
use crate::{
action_state::ActionState, clashing_inputs::ClashStrategy, input_map::InputMap,
input_streams::InputStreams, plugin::ToggleActions, Actionlike,
Expand Down Expand Up @@ -58,86 +59,6 @@ pub fn tick_action_state<A: Actionlike>(
*stored_previous_instant = time.last_update();
}

/// Flags to enable specific input type tracking.
///
/// They can be temporarily disabled by setting their fields to `false`
/// and will be re-enabled after handling all conflicting inputs.
///
/// If you are dealing with conflicting input from other crates, this might be useful.
///
/// # Examples
///
/// ```
/// use bevy::prelude::*;
/// use leafwing_input_manager::prelude::*;
///
/// pub fn disable_keyboard(mut tracking_input: ResMut<TrackingInputType>) {
/// tracking_input.keyboard = false;
/// }
///
/// let mut app = App::new();
///
/// // Remember to set
/// app.add_systems(PreUpdate, disable_keyboard.in_set(InputManagerSystem::PreUpdate));
/// ```
#[derive(Resource)]
pub struct TrackingInputType {
/// Is tracking gamepad input?
pub gamepad: bool,

/// Is tracking keyboard input?
pub keyboard: bool,

/// Is tracking mouse input?
pub mouse: bool,
}

impl Default for TrackingInputType {
fn default() -> Self {
Self {
gamepad: true,
keyboard: true,
mouse: true,
}
}
}

/// Allow `bevy::ui` to take priority over actions when processing inputs.
#[cfg(all(feature = "ui", not(feature = "no_ui_priority")))]
pub fn prioritize_ui_inputs(
query_interactions: Query<&Interaction>,
mut tracking_input: ResMut<TrackingInputType>,
) {
for interaction in query_interactions.iter() {
// If use clicks on a button, do not apply them to the game state
if *interaction != Interaction::None {
tracking_input.mouse = false;
}
}
}

/// Allow `egui` to take priority over actions when processing inputs.
#[cfg(feature = "egui")]
pub fn prioritize_egui_inputs(
mut query_egui_context: Query<(Entity, &'static mut EguiContext)>,
mut tracking_input: ResMut<TrackingInputType>,
) {
for (_, mut egui_context) in query_egui_context.iter_mut() {
let context = egui_context.get_mut();

// If egui wants to own inputs, don't also apply them to the game state
if context.wants_keyboard_input() {
tracking_input.keyboard = false;
}

// `wants_pointer_input` sometimes returns `false` after clicking or holding a button over a widget,
// so `is_pointer_over_area` is also needed.
if context.is_pointer_over_area() || context.wants_pointer_input() {
tracking_input.mouse = false;
}
}
}

/// Fetches all of the relevant [`ButtonInput`] resources to update [`ActionState`] according to the [`InputMap`].
///
/// Missing resources will be ignored, and treated as if none of the corresponding inputs were pressed.
Expand Down

0 comments on commit cd48808

Please sign in to comment.