use std::collections::{HashMap, BTreeMap};
use std::sync::mpsc::Receiver;
use std::ops::Range;
pub type Key = i32;
pub type MouseButton = u8;
#[derive(Debug, Copy, Clone, PartialEq)]
pub enum MouseAxis {
X = 0,Y = 1
}
#[derive(Debug, Copy, Clone)]
pub enum Binding {
KBKey(Key), MAxis(MouseAxis), MButton(MouseButton)
}
const NUM_MOUSE_BUTTONS: usize = 8;
#[derive(Debug, Clone)]
struct BindingTree {
keyBindings: BTreeMap<Key, Vec<usize>>, mouseButtonBindings: [Vec<usize>; NUM_MOUSE_BUTTONS],
mouseAxisBindings: [Vec<usize>; 2]
}
impl BindingTree {
fn new() -> BindingTree {
BindingTree {
keyBindings: BTreeMap::new(),
mouseButtonBindings: [Vec::new(), Vec::new(), Vec::new(), Vec::new(), Vec::new(),
Vec::new(), Vec::new(), Vec::new()],
mouseAxisBindings: [Vec::new(), Vec::new()]
}
}
fn get_indicies(&self, typeOf: Binding) -> Option<&Vec<usize>> {
match typeOf {
Binding::KBKey(key) => return self.keyBindings.get(&key),
Binding::MAxis(axis) => return Some(&self.mouseAxisBindings[axis as usize]),
Binding::MButton(btn) => return Some(&self.mouseButtonBindings[btn as usize]),
_ => panic!("NOT YET IMPLEMENTED!")
}
}
fn add_binding(&mut self, binding: Binding, index: usize) {
match binding {
Binding::KBKey(key) => {
if !self.keyBindings.contains_key(&key) {
self.keyBindings.insert(key.clone(), vec![index]);
} else {
self.keyBindings.get_mut(&key).unwrap().push(index);
}
},
Binding::MAxis(axis) => {
self.mouseAxisBindings[axis as usize].push(index);
},
Binding::MButton(btn) => {
self.mouseButtonBindings[btn as usize].push(index);
}
}
}
}
#[derive(Debug, Clone)]
pub struct InputSubsystem {
prevMousePos: (f64, f64),
mouseSens: (f64, f64),
axisNames: HashMap<String, usize>,
axisBindings: BindingTree,
axes: Vec<[f32; 2]>
}
const PRESSED_LOOKUP: [f32; 2] = [0.0, 1.0];
impl InputSubsystem {
pub fn new(mouseSens: (f64, f64)) -> InputSubsystem {
InputSubsystem{
prevMousePos: (0.0, 0.0),
mouseSens,
axisNames: HashMap::new(),
axisBindings: BindingTree::new(),
axes: Vec::new()
}
}
pub fn update_kb_bind(&mut self, key: Key, pressed: bool) {
if let Some(bindings) = self.axisBindings.get_indicies(Binding::KBKey(key)) {
for index in bindings {
self.axes[*index][1] = self.axes[*index][0];
self.axes[*index][0] = PRESSED_LOOKUP[pressed as usize];
}
}
}
pub fn update_mouseaxes_bind(&mut self, axes: (f64, f64)) {
if let Some(bindings) = self.axisBindings.get_indicies(Binding::MAxis(MouseAxis::X)) {
let newVal = (axes.0 - self.prevMousePos.0) * self.mouseSens.1;
for index in bindings {
self.axes[*index][1] = self.axes[*index][0];
self.axes[*index][0] = newVal as f32;
}
}
if let Some(bindings) = self.axisBindings.get_indicies(Binding::MAxis(MouseAxis::Y)) {
let newVal = (axes.1 - self.prevMousePos.1) * self.mouseSens.1;
for index in bindings {
self.axes[*index][1] = self.axes[*index][0];
self.axes[*index][0] = newVal as f32;
}
}
self.prevMousePos = axes;
}
pub fn update_mousebutton_bind(&mut self, btn: MouseButton, pressed: bool) {
if let Some(bindings) = self.axisBindings.get_indicies(Binding::MButton(btn)) {
for index in bindings {
self.axes[*index][1] = self.axes[*index][0];
self.axes[*index][0] = PRESSED_LOOKUP[pressed as usize];
}
}
}
pub fn add_binding(&mut self, name: String, boundTo: Binding)-> usize {
let index = self.axes.len(); self.axes.push([0.0; 2]);
self.axisNames.insert(name, index);
self.axisBindings.add_binding(boundTo, index);
return index;
}
pub fn get_index(&self, name: &String) -> usize {
return self.axisNames[name];
}
pub fn get(&self, index: usize) -> f32 {
return self.axes[index][0];
}
pub fn get_prev(&self, index: usize) -> f32 {
return self.axes[index][1];
}
pub fn get_delta(&self, index: usize) -> f32 {
return self.get(index) - self.get_prev(index);
}
}