input: Refactor all previous states
Some checks failed
Build legacy Nix package on Ubuntu / build (push) Failing after 7m48s
Some checks failed
Build legacy Nix package on Ubuntu / build (push) Failing after 7m48s
This commit is contained in:
parent
b0f82b0714
commit
5b0ab19207
5 changed files with 135 additions and 118 deletions
86
src/core/input/cache.rs
Normal file
86
src/core/input/cache.rs
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
use std::{
|
||||||
|
collections::HashMap,
|
||||||
|
hash::Hash,
|
||||||
|
ops::{Add, AddAssign, Sub},
|
||||||
|
};
|
||||||
|
|
||||||
|
use winit::event::ElementState;
|
||||||
|
|
||||||
|
pub struct CachedElementState<K: Eq + Hash> {
|
||||||
|
cache: HashMap<K, ElementState>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<K: Eq + Hash> Default for CachedElementState<K> {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
cache: HashMap::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<K: Eq + Hash> CachedElementState<K> {
|
||||||
|
pub fn set_key_state(&mut self, key: K, state: ElementState) -> Option<ElementState> {
|
||||||
|
let key_state = self.cache.get(&key);
|
||||||
|
let new_key_state = match key_state {
|
||||||
|
Some(old) => match state {
|
||||||
|
ElementState::Pressed => match old {
|
||||||
|
ElementState::Released => Some(ElementState::Pressed),
|
||||||
|
ElementState::Pressed => None,
|
||||||
|
},
|
||||||
|
ElementState::Released => match old {
|
||||||
|
ElementState::Released => None,
|
||||||
|
ElementState::Pressed => Some(ElementState::Released),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
None => match state {
|
||||||
|
ElementState::Pressed => Some(ElementState::Pressed),
|
||||||
|
ElementState::Released => Some(ElementState::Released),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
if let Some(new_key_state) = new_key_state {
|
||||||
|
self.cache.insert(key, new_key_state);
|
||||||
|
}
|
||||||
|
new_key_state
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct CachedMovement<T>
|
||||||
|
where
|
||||||
|
T: Sub<Output = T> + Add<Output = T> + Default + Copy,
|
||||||
|
{
|
||||||
|
pub old_value: Option<T>,
|
||||||
|
pub value: T,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> CachedMovement<T>
|
||||||
|
where
|
||||||
|
T: Sub<Output = T> + Add<Output = T> + Default + Copy,
|
||||||
|
{
|
||||||
|
pub fn set_value(&mut self, value: T) {
|
||||||
|
self.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reset(&mut self) -> T {
|
||||||
|
match self.old_value.as_ref() {
|
||||||
|
Some(old_value) => {
|
||||||
|
let diff = self.value - *old_value;
|
||||||
|
self.old_value = Some(self.value);
|
||||||
|
diff
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
self.old_value = Some(self.value);
|
||||||
|
T::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> AddAssign<T> for CachedMovement<T>
|
||||||
|
where
|
||||||
|
T: Add<Output = T> + Sub<Output = T> + Default + Copy,
|
||||||
|
{
|
||||||
|
fn add_assign(&mut self, rhs: T) {
|
||||||
|
self.value = self.value + rhs;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,25 +0,0 @@
|
||||||
use egui_winit_vulkano::egui::ahash::HashMap;
|
|
||||||
use winit::{
|
|
||||||
event::{ElementState, WindowEvent},
|
|
||||||
keyboard::PhysicalKey,
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::{process_new_element_state, virtual_input::VirtualInput};
|
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
|
||||||
pub struct KeyboardState {
|
|
||||||
key_states: HashMap<PhysicalKey, ElementState>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl KeyboardState {
|
|
||||||
pub fn process_window_event(&mut self, event: &WindowEvent, virtual_input: &mut VirtualInput) {
|
|
||||||
if let WindowEvent::KeyboardInput { event, .. } = event {
|
|
||||||
let key_state = self.key_states.get(&event.physical_key);
|
|
||||||
let new_key_state = process_new_element_state(key_state, event.state);
|
|
||||||
if let Some(new_key_state) = new_key_state {
|
|
||||||
self.key_states.insert(event.physical_key, new_key_state);
|
|
||||||
virtual_input.update_key_binding(event.physical_key, new_key_state);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,12 +1,13 @@
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use keyboard_state::KeyboardState;
|
use cache::{CachedElementState, CachedMovement};
|
||||||
use mouse_state::MouseState;
|
|
||||||
use virtual_input::VirtualInput;
|
use virtual_input::VirtualInput;
|
||||||
use winit::event::{ElementState, WindowEvent};
|
use winit::{
|
||||||
|
event::{MouseButton, MouseScrollDelta, WindowEvent},
|
||||||
|
keyboard::PhysicalKey,
|
||||||
|
};
|
||||||
|
|
||||||
mod keyboard_state;
|
mod cache;
|
||||||
mod mouse_state;
|
|
||||||
mod virtual_binding;
|
mod virtual_binding;
|
||||||
mod virtual_input;
|
mod virtual_input;
|
||||||
mod virtual_state;
|
mod virtual_state;
|
||||||
|
@ -14,8 +15,10 @@ pub use virtual_binding::{AxisDirection, VirtualBinding};
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct InputManager {
|
pub struct InputManager {
|
||||||
keyboard_state: KeyboardState,
|
keys_state: CachedElementState<PhysicalKey>,
|
||||||
mouse_state: MouseState,
|
mouse_buttons_state: CachedElementState<MouseButton>,
|
||||||
|
mouse_position_delta: CachedMovement<glam::Vec2>,
|
||||||
|
mouse_wheel_delta: CachedMovement<glam::Vec2>,
|
||||||
virtual_input: VirtualInput,
|
virtual_input: VirtualInput,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,18 +44,45 @@ impl InputManager {
|
||||||
WindowEvent::AxisMotion { axis, value, .. } => {
|
WindowEvent::AxisMotion { axis, value, .. } => {
|
||||||
self.virtual_input.update_axis_binding(*axis, *value as f32);
|
self.virtual_input.update_axis_binding(*axis, *value as f32);
|
||||||
}
|
}
|
||||||
_ => {
|
WindowEvent::KeyboardInput { event, .. } => {
|
||||||
self.keyboard_state
|
let new_key_state = self
|
||||||
.process_window_event(event, &mut self.virtual_input);
|
.keys_state
|
||||||
self.mouse_state
|
.set_key_state(event.physical_key, event.state);
|
||||||
.process_window_event(event, &mut self.virtual_input);
|
if let Some(new_key_state) = new_key_state {
|
||||||
|
self.virtual_input
|
||||||
|
.update_key_binding(event.physical_key, new_key_state);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
WindowEvent::CursorMoved { position, .. } => {
|
||||||
|
self.mouse_position_delta
|
||||||
|
.set_value(glam::Vec2::new(position.x as f32, position.y as f32));
|
||||||
|
}
|
||||||
|
WindowEvent::MouseInput { button, state, .. } => {
|
||||||
|
let new_mouse_button_state =
|
||||||
|
self.mouse_buttons_state.set_key_state(*button, *state);
|
||||||
|
if let Some(new_mouse_button_state) = new_mouse_button_state {
|
||||||
|
self.virtual_input
|
||||||
|
.update_mouse_button_binding(*button, new_mouse_button_state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
WindowEvent::MouseWheel { delta, .. } => {
|
||||||
|
self.mouse_wheel_delta += match delta {
|
||||||
|
MouseScrollDelta::PixelDelta(position) => {
|
||||||
|
glam::Vec2::new(position.x as f32, position.y as f32)
|
||||||
|
}
|
||||||
|
MouseScrollDelta::LineDelta(x, y) => glam::Vec2::new(*x as f32, *y as f32),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Updates deltas before running update
|
/// Updates deltas before running update
|
||||||
pub fn update(&mut self) {
|
pub fn update(&mut self) {
|
||||||
self.mouse_state.update(&mut self.virtual_input);
|
self.virtual_input
|
||||||
|
.update_mouse_move_binding(&self.mouse_position_delta.reset());
|
||||||
|
self.virtual_input
|
||||||
|
.update_mouse_wheel_binding(&self.mouse_wheel_delta.reset());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_virtual_input_state(&self, value_name: &str) -> f32 {
|
pub fn get_virtual_input_state(&self, value_name: &str) -> f32 {
|
||||||
|
@ -63,33 +93,3 @@ impl InputManager {
|
||||||
self.virtual_input.add_bindings(value_name, bindings);
|
self.virtual_input.add_bindings(value_name, bindings);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Maps the old element state to the new element state.
|
|
||||||
/// if is changed, returns Some(new_state), otherwise returns None
|
|
||||||
#[inline]
|
|
||||||
fn process_new_element_state(
|
|
||||||
old: Option<&ElementState>,
|
|
||||||
new: ElementState,
|
|
||||||
) -> Option<ElementState> {
|
|
||||||
match old {
|
|
||||||
Some(old) => match new {
|
|
||||||
ElementState::Pressed => match old {
|
|
||||||
ElementState::Released => Some(ElementState::Pressed),
|
|
||||||
ElementState::Pressed => None,
|
|
||||||
},
|
|
||||||
ElementState::Released => match old {
|
|
||||||
ElementState::Released => None,
|
|
||||||
ElementState::Pressed => Some(ElementState::Released),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
None => match new {
|
|
||||||
ElementState::Pressed => Some(ElementState::Pressed),
|
|
||||||
ElementState::Released => Some(ElementState::Released),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn process_axis_deadzone(value: f32, deadzone: f32) -> f32 {
|
|
||||||
if value.abs() < deadzone { 0.0 } else { value }
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,49 +0,0 @@
|
||||||
use std::collections::HashMap;
|
|
||||||
|
|
||||||
use winit::event::{ElementState, MouseButton, MouseScrollDelta, WindowEvent};
|
|
||||||
|
|
||||||
use super::{process_new_element_state, virtual_input::VirtualInput};
|
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
|
||||||
pub struct MouseState {
|
|
||||||
old_position: glam::Vec2,
|
|
||||||
position: glam::Vec2,
|
|
||||||
delta: glam::Vec2,
|
|
||||||
wheel_delta: glam::Vec2,
|
|
||||||
mouse_button_state: HashMap<MouseButton, ElementState>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl MouseState {
|
|
||||||
pub fn process_window_event(&mut self, event: &WindowEvent, virtual_input: &mut VirtualInput) {
|
|
||||||
match event {
|
|
||||||
WindowEvent::CursorMoved { position, .. } => {
|
|
||||||
self.position = glam::Vec2::new(position.x as f32, position.y as f32);
|
|
||||||
}
|
|
||||||
WindowEvent::MouseWheel { delta, .. } => {
|
|
||||||
self.wheel_delta += match delta {
|
|
||||||
MouseScrollDelta::PixelDelta(position) => {
|
|
||||||
glam::Vec2::new(position.x as f32, position.y as f32)
|
|
||||||
}
|
|
||||||
MouseScrollDelta::LineDelta(x, y) => glam::Vec2::new(*x as f32, *y as f32),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
WindowEvent::MouseInput { button, state, .. } => {
|
|
||||||
let key_state = self.mouse_button_state.get(button);
|
|
||||||
let new_key_state = process_new_element_state(key_state, *state);
|
|
||||||
if let Some(new_key_state) = new_key_state {
|
|
||||||
self.mouse_button_state.insert(*button, new_key_state);
|
|
||||||
virtual_input.update_mouse_button_binding(*button, new_key_state);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn update(&mut self, virtual_input: &mut VirtualInput) {
|
|
||||||
self.delta = self.position - self.old_position;
|
|
||||||
self.old_position = self.position;
|
|
||||||
virtual_input.update_mouse_move_binding(&self.delta);
|
|
||||||
virtual_input.update_mouse_wheel_binding(&self.wheel_delta);
|
|
||||||
self.wheel_delta = glam::Vec2::ZERO;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -3,7 +3,7 @@ use winit::{
|
||||||
keyboard::PhysicalKey,
|
keyboard::PhysicalKey,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{process_axis_deadzone, virtual_binding::VirtualBinding};
|
use super::virtual_binding::VirtualBinding;
|
||||||
|
|
||||||
pub struct VirtualBindingState {
|
pub struct VirtualBindingState {
|
||||||
pub value: f32,
|
pub value: f32,
|
||||||
|
@ -101,3 +101,8 @@ impl VirtualInputState {
|
||||||
self.value = new_value;
|
self.value = new_value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn process_axis_deadzone(value: f32, deadzone: f32) -> f32 {
|
||||||
|
if value.abs() < deadzone { 0.0 } else { value }
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue