mirror of
https://github.com/bevyengine/bevy
synced 2024-09-20 06:22:01 +00:00
input: make new Input resource generic and add Input<MouseButton>
This commit is contained in:
parent
fcecf78609
commit
5b6f24d6a2
8 changed files with 140 additions and 77 deletions
|
@ -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 a new issue