better inputs, log config

This commit is contained in:
2019-07-27 16:47:08 +02:00
parent 39b136d799
commit ee01892a22
7 changed files with 289458 additions and 53 deletions

View File

@@ -1,5 +1,6 @@
use winit::{ScanCode, ModifiersState, MouseButton, ElementState};
use std::collections::{HashMap};
use std::collections::{HashMap, HashSet};
use std::fs;
use toml;
@@ -11,13 +12,20 @@ pub struct VirtualButton {
}
pub struct VirtualAxis {
pub analog_inputs: Vec<AxisInput>
pub axis_inputs: Vec<AxisInput>
}
pub struct InputState {
pub virtual_buttons: HashMap<String, VirtualButton>,
pub virtual_axes: HashMap<String, VirtualAxis>,
pressed_digital: HashMap<DigitalInput, (bool, bool)>
input_events: HashSet<DigitalInputEvent>,
pressed_buttons: HashSet<ScanCode>
}
#[derive(Debug, PartialEq, Eq, Hash)]
pub enum DigitalInputEvent {
Pressed(DigitalInput),
Released(DigitalInput)
}
#[derive(Debug, Serialize, Deserialize)]
@@ -42,14 +50,14 @@ struct InputConfigAxis {
ctrl_negative: Option<bool>
}
type InputHashmapEntry<'a> = (&'a DigitalInput, (bool, bool));
impl InputState {
pub fn new(toml_path: &str) -> InputState {
let mut state = InputState { virtual_buttons: HashMap::new(), virtual_axes: HashMap::new(), pressed_digital: HashMap::new() };
let mut state = InputState { virtual_buttons: HashMap::new(), virtual_axes: HashMap::new(),
input_events: HashSet::new(), pressed_buttons: HashSet::new() };
let config: InputConfig = toml::from_slice(&fs::read(toml_path).expect("Failed to read input config!")).expect("Failed to parse input config!");
let buttons = config.button.iter().for_each(|bn| {
config.button.iter().for_each(|bn| {
let modifiers = ModifiersState {
shift: false,
ctrl: bn.ctrl.is_some(),
@@ -64,7 +72,7 @@ impl InputState {
}
});
let axes = config.axis.iter().for_each(|a| {
config.axis.iter().for_each(|a| {
let modifiers_positive = ModifiersState {
shift: false,
ctrl: a.ctrl_positive.is_some(),
@@ -82,9 +90,9 @@ impl InputState {
DigitalInput::Keyboard(KeyboardInput { scancode: a.scancode_negative, modifiers: modifiers_negative })
);
if let Some(virtual_axis) = state.virtual_axes.get_mut(&a.name) {
virtual_axis.analog_inputs.push(axis);
virtual_axis.axis_inputs.push(axis);
} else {
state.virtual_axes.insert(a.name.clone(), VirtualAxis { analog_inputs: vec![axis] });
state.virtual_axes.insert(a.name.clone(), VirtualAxis { axis_inputs: vec![axis] });
}
});
@@ -92,39 +100,59 @@ impl InputState {
}
pub fn button_down(self: &Self, button_code: &str) -> bool {
if let Some(input) = self.virtual_buttons.get(button_code) {
self.pressed_digital.iter().any(|(registered_input, _)| input.digital_inputs.iter().any(|digital_input| digital_input == registered_input))
} else {
false
match self.virtual_buttons.get(button_code) {
Some(virtual_button) => {
virtual_button.digital_inputs.iter().any(|vi| self.digital_input_pressed(vi))
}
None => {
assert!(false, format!("Button {:?} not found!", button_code));
false
}
}
}
pub fn button_just_pressed(self: &Self, button_code: &str) -> bool {
if let Some(input) = self.virtual_buttons.get(button_code) {
self.pressed_digital.iter()
.filter(|(_, (pressed, _))| *pressed)
.any(|(registered_input, _)| input.digital_inputs.iter().any(|digital_input| digital_input == registered_input))
} else {
false
match self.virtual_buttons.get(button_code) {
Some(virtual_button) => {
self.input_events.iter().any(|input_event| {
if let DigitalInputEvent::Pressed(digital_input) = input_event {
virtual_button.digital_inputs.iter().any(|virtual_button_input| virtual_button_input == digital_input)
} else {
false
}
})
}
None => {
assert!(false, format!("Button {:?} not found!", button_code));
false
}
}
}
pub fn button_just_released(self: &Self, button_code: &str) -> bool {
if let Some(input) = self.virtual_buttons.get(button_code) {
self.pressed_digital.iter()
.filter(|(_, (_, released))| *released)
.any(|(registered_input, _)| input.digital_inputs.iter().any(|digital_input| digital_input == registered_input))
} else {
false
match self.virtual_buttons.get(button_code) {
Some(virtual_button) => {
self.input_events.iter().any(|input_event| {
if let DigitalInputEvent::Released(digital_input) = input_event {
virtual_button.digital_inputs.iter().any(|virtual_button_input| virtual_button_input == digital_input)
} else {
false
}
})
}
None => {
assert!(false, format!("Button {:?} not found!", button_code));
false
}
}
}
pub fn get_axis(self: &Self, axis_code: &str) -> f32 {
if let Some(axis) = self.virtual_axes.get(axis_code) {
axis.analog_inputs.iter().fold(0.0, |fold, item| {
axis.axis_inputs.iter().fold(0.0, |fold, item| {
let val = match item {
AxisInput::Analog(_) => 0.0,
AxisInput::Digital(positive_button, negative_button) => self.button_to_float(positive_button) - self.button_to_float(negative_button),
AxisInput::Analog(_) => 0.0, //TODO
AxisInput::Digital(positive_button, negative_button) => self.digital_input_to_float(positive_button) - self.digital_input_to_float(negative_button),
};
if f32::abs(val) > fold {
val
@@ -138,32 +166,43 @@ impl InputState {
}
}
fn button_to_float(self: &Self, input: &DigitalInput) -> f32 {
if self.pressed_digital.iter().any(|(registered_input, _)| input == registered_input) {
1.0
} else {
0.0
pub fn digital_input_pressed(self: &Self, digital_input: &DigitalInput) -> bool {
match digital_input {
DigitalInput::Keyboard(keyboard_input) =>
self.pressed_buttons.contains(&keyboard_input.scancode)
&& self.modifiers_are_pressed(keyboard_input.modifiers),
DigitalInput::Mouse(_) => false
}
}
fn modifiers_are_pressed(self: &Self, modifiers: ModifiersState) -> bool {
(!modifiers.ctrl || self.pressed_buttons.contains(&29))
&& (!modifiers.shift || self.pressed_buttons.contains(&42) || self.pressed_buttons.contains(&54))
&& (!modifiers.alt || self.pressed_buttons.contains(&56))
&& (!modifiers.logo || self.pressed_buttons.contains(&91) || self.pressed_buttons.contains(&92))
}
fn digital_input_to_float(self: &Self, input: &DigitalInput) -> f32 {
if self.digital_input_pressed(input) { 1.0 } else { 0.0 }
}
pub fn on_keyboard_event(self: &mut Self, state: ElementState, scancode: ScanCode, modifiers: ModifiersState) {
let input = DigitalInput::Keyboard(KeyboardInput { scancode, modifiers });
match state {
ElementState::Pressed => {
self.pressed_digital.insert(DigitalInput::Keyboard(KeyboardInput { scancode, modifiers }), (true, false));
self.input_events.insert(DigitalInputEvent::Pressed(input));
self.pressed_buttons.insert(scancode);
},
ElementState::Released => {
if let Some((_, recent_release)) = self.pressed_digital.get_mut(&DigitalInput::Keyboard(KeyboardInput { scancode, modifiers })) {
*recent_release = true;
}
self.input_events.insert(DigitalInputEvent::Released(input));
self.pressed_buttons.remove(&scancode);
},
}
}
pub fn frame_end(self: &mut Self) {
self.pressed_digital.iter_mut().for_each(|(_, (recent_press, _))| {
if *recent_press { *recent_press = false }
});
self.pressed_digital.retain(|_, (recent_press, recent_release)| *recent_release == false);
self.input_events.clear();
}
}