input: make new Input resource generic and add Input<MouseButton>

This commit is contained in:
Carter Anderson 2020-06-04 23:34:21 -07:00
parent fcecf78609
commit 5b6f24d6a2
8 changed files with 140 additions and 77 deletions

View file

@ -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();
}
}

View file

@ -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 {

View file

@ -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(),
);
}
}

View file

@ -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),
}
}
}

View file

@ -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),
});
}

View file

@ -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");
}

View file

@ -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

View file

@ -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")]