input: make new Input resource generic and add Input<MouseButton>
This commit is contained in:
		
							parent
							
								
									fcecf78609
								
							
						
					
					
						commit
						5b6f24d6a2
					
				@ -1,72 +1,52 @@
 | 
			
		||||
use crate::keyboard::{KeyCode, KeyboardInput, ElementState};
 | 
			
		||||
use bevy_app::{EventReader, Events};
 | 
			
		||||
use legion::prelude::{Res, ResMut};
 | 
			
		||||
use std::collections::HashSet;
 | 
			
		||||
use std::{collections::HashSet, hash::Hash};
 | 
			
		||||
 | 
			
		||||
#[derive(Default)]
 | 
			
		||||
pub struct Input {
 | 
			
		||||
    pressed_keys: HashSet<KeyCode>,
 | 
			
		||||
    just_pressed_keys: HashSet<KeyCode>,
 | 
			
		||||
    just_released_keys: HashSet<KeyCode>,
 | 
			
		||||
pub struct Input<T> {
 | 
			
		||||
    pressed: HashSet<T>,
 | 
			
		||||
    just_pressed: HashSet<T>,
 | 
			
		||||
    just_released: HashSet<T>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Input {
 | 
			
		||||
    pub fn press_key(&mut self, key_code: KeyCode) {
 | 
			
		||||
        if !self.key_pressed(key_code) {
 | 
			
		||||
            self.just_pressed_keys.insert(key_code);
 | 
			
		||||
impl<T> Default for Input<T> {
 | 
			
		||||
    fn default() -> Self {
 | 
			
		||||
        Self {
 | 
			
		||||
            pressed: Default::default(),
 | 
			
		||||
            just_pressed: Default::default(),
 | 
			
		||||
            just_released: Default::default(),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<T> Input<T>
 | 
			
		||||
where
 | 
			
		||||
    T: Copy + Eq + Hash,
 | 
			
		||||
{
 | 
			
		||||
    pub fn press(&mut self, input: T) {
 | 
			
		||||
        if !self.pressed(input) {
 | 
			
		||||
            self.just_pressed.insert(input);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        self.pressed_keys.insert(key_code);
 | 
			
		||||
        self.pressed.insert(input);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn release_key(&mut self, key_code: KeyCode) {
 | 
			
		||||
        self.pressed_keys.remove(&key_code);
 | 
			
		||||
        self.just_released_keys.insert(key_code);
 | 
			
		||||
    pub fn pressed(&self, input: T) -> bool {
 | 
			
		||||
        self.pressed.contains(&input)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn key_pressed(&self, key_code: KeyCode) -> bool {
 | 
			
		||||
        self.pressed_keys.contains(&key_code)
 | 
			
		||||
    pub fn release(&mut self, input: T) {
 | 
			
		||||
        self.pressed.remove(&input);
 | 
			
		||||
        self.just_released.insert(input);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn key_just_pressed(&self, key_code: KeyCode) -> bool {
 | 
			
		||||
        self.just_pressed_keys.contains(&key_code)
 | 
			
		||||
    pub fn just_pressed(&self, input: T) -> bool {
 | 
			
		||||
        self.just_pressed.contains(&input)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn key_just_released(&self, key_code: KeyCode) -> bool {
 | 
			
		||||
        self.just_released_keys.contains(&key_code)
 | 
			
		||||
    pub fn just_released(&self, input: T) -> bool {
 | 
			
		||||
        self.just_released.contains(&input)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn update(&mut self) {
 | 
			
		||||
        self.just_pressed_keys.clear();
 | 
			
		||||
        self.just_released_keys.clear();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Default)]
 | 
			
		||||
pub struct InputState {
 | 
			
		||||
    keyboard_input_event_reader: EventReader<KeyboardInput>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn input_system(
 | 
			
		||||
    mut state: ResMut<InputState>,
 | 
			
		||||
    mut input: ResMut<Input>,
 | 
			
		||||
    keyboard_input_events: Res<Events<KeyboardInput>>,
 | 
			
		||||
) {
 | 
			
		||||
    input.update();
 | 
			
		||||
    for event in state
 | 
			
		||||
        .keyboard_input_event_reader
 | 
			
		||||
        .iter(&keyboard_input_events)
 | 
			
		||||
    {
 | 
			
		||||
        if let KeyboardInput {
 | 
			
		||||
            key_code: Some(key_code),
 | 
			
		||||
            state,
 | 
			
		||||
            ..
 | 
			
		||||
        } = event
 | 
			
		||||
        {
 | 
			
		||||
            match state {
 | 
			
		||||
                ElementState::Pressed => input.press_key(*key_code),
 | 
			
		||||
                ElementState::Released => input.release_key(*key_code),
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        self.just_pressed.clear();
 | 
			
		||||
        self.just_released.clear();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,7 @@
 | 
			
		||||
use bevy_app::{Events, EventReader};
 | 
			
		||||
use legion::prelude::{Res, ResMut};
 | 
			
		||||
use crate::Input;
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Clone)]
 | 
			
		||||
pub struct KeyboardInput {
 | 
			
		||||
    pub scan_code: u32,
 | 
			
		||||
@ -20,6 +24,35 @@ impl ElementState {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Default)]
 | 
			
		||||
pub struct KeyboardInputState {
 | 
			
		||||
    keyboard_input_event_reader: EventReader<KeyboardInput>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn keyboard_input_system(
 | 
			
		||||
    mut state: ResMut<KeyboardInputState>,
 | 
			
		||||
    mut keyboard_input: ResMut<Input<KeyCode>>,
 | 
			
		||||
    keyboard_input_events: Res<Events<KeyboardInput>>,
 | 
			
		||||
) {
 | 
			
		||||
    keyboard_input.update();
 | 
			
		||||
    for event in state
 | 
			
		||||
        .keyboard_input_event_reader
 | 
			
		||||
        .iter(&keyboard_input_events)
 | 
			
		||||
    {
 | 
			
		||||
        if let KeyboardInput {
 | 
			
		||||
            key_code: Some(key_code),
 | 
			
		||||
            state,
 | 
			
		||||
            ..
 | 
			
		||||
        } = event
 | 
			
		||||
        {
 | 
			
		||||
            match state {
 | 
			
		||||
                ElementState::Pressed => keyboard_input.press(*key_code),
 | 
			
		||||
                ElementState::Released => keyboard_input.release(*key_code),
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Hash, Ord, PartialOrd, PartialEq, Eq, Clone, Copy)]
 | 
			
		||||
#[repr(u32)]
 | 
			
		||||
pub enum KeyCode {
 | 
			
		||||
 | 
			
		||||
@ -6,9 +6,12 @@ pub mod system;
 | 
			
		||||
pub use input::*;
 | 
			
		||||
 | 
			
		||||
use bevy_app::{AppBuilder, AppPlugin};
 | 
			
		||||
use keyboard::KeyboardInput;
 | 
			
		||||
use mouse::{MouseButtonInput, MouseMotionInput};
 | 
			
		||||
use keyboard::{keyboard_input_system, KeyCode, KeyboardInput, KeyboardInputState};
 | 
			
		||||
use legion::prelude::IntoSystem;
 | 
			
		||||
use mouse::{
 | 
			
		||||
    mouse_button_input_system, MouseButton, MouseButtonInput, MouseButtonInputState,
 | 
			
		||||
    MouseMotion,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#[derive(Default)]
 | 
			
		||||
pub struct InputPlugin;
 | 
			
		||||
@ -17,9 +20,18 @@ impl AppPlugin for InputPlugin {
 | 
			
		||||
    fn build(&self, app: &mut AppBuilder) {
 | 
			
		||||
        app.add_event::<KeyboardInput>()
 | 
			
		||||
            .add_event::<MouseButtonInput>()
 | 
			
		||||
            .add_event::<MouseMotionInput>()
 | 
			
		||||
            .init_resource::<Input>()
 | 
			
		||||
            .init_resource::<InputState>()
 | 
			
		||||
            .add_system_to_stage(bevy_app::stage::EVENT_UPDATE, input_system.system());
 | 
			
		||||
            .add_event::<MouseMotion>()
 | 
			
		||||
            .init_resource::<Input<KeyCode>>()
 | 
			
		||||
            .init_resource::<KeyboardInputState>()
 | 
			
		||||
            .add_system_to_stage(
 | 
			
		||||
                bevy_app::stage::EVENT_UPDATE,
 | 
			
		||||
                keyboard_input_system.system(),
 | 
			
		||||
            )
 | 
			
		||||
            .init_resource::<Input<MouseButton>>()
 | 
			
		||||
            .init_resource::<MouseButtonInputState>()
 | 
			
		||||
            .add_system_to_stage(
 | 
			
		||||
                bevy_app::stage::EVENT_UPDATE,
 | 
			
		||||
                mouse_button_input_system.system(),
 | 
			
		||||
            );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,8 @@
 | 
			
		||||
use super::keyboard::ElementState;
 | 
			
		||||
use crate::Input;
 | 
			
		||||
use bevy_app::{EventReader, Events};
 | 
			
		||||
use glam::Vec2;
 | 
			
		||||
use legion::prelude::{Res, ResMut};
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Clone)]
 | 
			
		||||
pub struct MouseButtonInput {
 | 
			
		||||
@ -16,6 +19,28 @@ pub enum MouseButton {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Clone)]
 | 
			
		||||
pub struct MouseMotionInput {
 | 
			
		||||
pub struct MouseMotion {
 | 
			
		||||
    pub delta: Vec2,
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Default)]
 | 
			
		||||
pub struct MouseButtonInputState {
 | 
			
		||||
    mouse_button_input_event_reader: EventReader<MouseButtonInput>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn mouse_button_input_system(
 | 
			
		||||
    mut state: ResMut<MouseButtonInputState>,
 | 
			
		||||
    mut mouse_button_input: ResMut<Input<MouseButton>>,
 | 
			
		||||
    mouse_button_input_events: Res<Events<MouseButtonInput>>,
 | 
			
		||||
) {
 | 
			
		||||
    mouse_button_input.update();
 | 
			
		||||
    for event in state
 | 
			
		||||
        .mouse_button_input_event_reader
 | 
			
		||||
        .iter(&mouse_button_input_events)
 | 
			
		||||
    {
 | 
			
		||||
        match event.state {
 | 
			
		||||
            ElementState::Pressed => mouse_button_input.press(event.button),
 | 
			
		||||
            ElementState::Released => mouse_button_input.release(event.button),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -4,7 +4,7 @@ pub use winit_windows::*;
 | 
			
		||||
 | 
			
		||||
use bevy_input::{
 | 
			
		||||
    keyboard::KeyboardInput,
 | 
			
		||||
    mouse::{MouseButtonInput, MouseMotionInput},
 | 
			
		||||
    mouse::{MouseButtonInput, MouseMotion},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
use bevy_app::{App, AppBuilder, AppExit, AppPlugin, EventReader, Events};
 | 
			
		||||
@ -125,8 +125,8 @@ pub fn winit_runner(mut app: App) {
 | 
			
		||||
            event::Event::DeviceEvent { ref event, .. } => match event {
 | 
			
		||||
                DeviceEvent::MouseMotion { delta } => {
 | 
			
		||||
                    let mut mouse_motion_events =
 | 
			
		||||
                        app.resources.get_mut::<Events<MouseMotionInput>>().unwrap();
 | 
			
		||||
                    mouse_motion_events.send(MouseMotionInput {
 | 
			
		||||
                        app.resources.get_mut::<Events<MouseMotion>>().unwrap();
 | 
			
		||||
                    mouse_motion_events.send(MouseMotion {
 | 
			
		||||
                        delta: Vec2::new(delta.0 as f32, delta.1 as f32),
 | 
			
		||||
                    });
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
@ -13,17 +13,17 @@ fn main() {
 | 
			
		||||
fn move_on_input(
 | 
			
		||||
    world: &mut SubWorld,
 | 
			
		||||
    time: Res<Time>,
 | 
			
		||||
    input: Res<Input>,
 | 
			
		||||
    keyboard_input: Res<Input<KeyCode>>,
 | 
			
		||||
    query: &mut Query<(Write<Translation>, Read<Handle<Mesh>>)>,
 | 
			
		||||
) {
 | 
			
		||||
    let moving_left = input.key_pressed(KeyCode::Left);
 | 
			
		||||
    let moving_right = input.key_pressed(KeyCode::Right);
 | 
			
		||||
    let moving_left = keyboard_input.pressed(KeyCode::Left);
 | 
			
		||||
    let moving_right = keyboard_input.pressed(KeyCode::Right);
 | 
			
		||||
 | 
			
		||||
    if input.key_just_pressed(KeyCode::Left) {
 | 
			
		||||
    if keyboard_input.just_pressed(KeyCode::Left) {
 | 
			
		||||
        println!("left just pressed");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if input.key_just_released(KeyCode::Left) {
 | 
			
		||||
    if keyboard_input.just_released(KeyCode::Left) {
 | 
			
		||||
        println!("left just released");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,29 +1,40 @@
 | 
			
		||||
use bevy::{
 | 
			
		||||
    input::mouse::{MouseButtonInput, MouseMotionInput},
 | 
			
		||||
    input::mouse::{MouseButtonInput, MouseMotion},
 | 
			
		||||
    prelude::*,
 | 
			
		||||
    window::CursorMoved,
 | 
			
		||||
};
 | 
			
		||||
use bevy_window::CursorMoved;
 | 
			
		||||
 | 
			
		||||
fn main() {
 | 
			
		||||
    App::build()
 | 
			
		||||
        .add_default_plugins()
 | 
			
		||||
        .init_resource::<State>()
 | 
			
		||||
        .add_system(mouse_input_system.system())
 | 
			
		||||
        .add_system(mouse_click_system.system())
 | 
			
		||||
        .add_system(mouse_input_event_system.system())
 | 
			
		||||
        .run();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn mouse_click_system(mouse_button_input: Res<Input<MouseButton>>) {
 | 
			
		||||
    if mouse_button_input.just_pressed(MouseButton::Left) {
 | 
			
		||||
        println!("left mouse clicked");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if mouse_button_input.just_released(MouseButton::Left) {
 | 
			
		||||
        println!("left mouse released");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Default)]
 | 
			
		||||
struct State {
 | 
			
		||||
    mouse_button_event_reader: EventReader<MouseButtonInput>,
 | 
			
		||||
    mouse_motion_event_reader: EventReader<MouseMotionInput>,
 | 
			
		||||
    mouse_motion_event_reader: EventReader<MouseMotion>,
 | 
			
		||||
    cursor_moved_event_reader: EventReader<CursorMoved>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// prints out mouse events as they come in
 | 
			
		||||
fn mouse_input_system(
 | 
			
		||||
/// prints out all mouse events as they come in
 | 
			
		||||
fn mouse_input_event_system(
 | 
			
		||||
    mut state: ResMut<State>,
 | 
			
		||||
    mouse_button_input_events: Res<Events<MouseButtonInput>>,
 | 
			
		||||
    mouse_motion_events: Res<Events<MouseMotionInput>>,
 | 
			
		||||
    mouse_motion_events: Res<Events<MouseMotion>>,
 | 
			
		||||
    cursor_moved_events: Res<Events<CursorMoved>>,
 | 
			
		||||
) {
 | 
			
		||||
    for event in state
 | 
			
		||||
 | 
			
		||||
@ -9,6 +9,8 @@ pub use crate::core::{
 | 
			
		||||
pub use crate::derive::*;
 | 
			
		||||
#[cfg(feature = "diagnostic")]
 | 
			
		||||
pub use crate::diagnostic::DiagnosticsPlugin;
 | 
			
		||||
#[cfg(feature = "input")]
 | 
			
		||||
pub use crate::input::{Input, mouse::MouseButton, keyboard::KeyCode};
 | 
			
		||||
#[cfg(feature = "pbr")]
 | 
			
		||||
pub use crate::pbr::{entity::*, light::Light, material::StandardMaterial};
 | 
			
		||||
#[cfg(feature = "property")]
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user