extern crate time;
use std::mem;
use {Key, KeyRepeat};
pub struct KeyHandler {
prev_time: f64,
delta_time: f32,
keys: [bool; 512],
keys_down_duration: [f32; 512],
key_repeat_delay: f32,
key_repeat_rate: f32,
}
impl KeyHandler {
pub fn new() -> KeyHandler {
KeyHandler {
keys: [false; 512],
keys_down_duration: [-1.0; 512],
prev_time: time::precise_time_s(),
delta_time: 0.0,
key_repeat_delay: 0.250,
key_repeat_rate: 0.050,
}
}
#[inline]
pub fn set_key_state(&mut self, key: Key, state: bool) {
self.keys[key as usize] = state;
}
pub fn get_keys(&self) -> Option<Vec<Key>> {
let mut index: u16 = 0;
let mut keys: Vec<Key> = Vec::new();
for i in self.keys.iter() {
if *i {
unsafe {
keys.push(mem::transmute(index as u8));
}
}
index += 1;
}
Some(keys)
}
pub fn update(&mut self) {
let current_time = time::precise_time_s();
let delta_time = (current_time - self.prev_time) as f32;
self.prev_time = current_time;
self.delta_time = delta_time;
for i in 0..self.keys.len() {
if self.keys[i] {
if self.keys_down_duration[i] < 0.0 {
self.keys_down_duration[i] = 0.0;
} else {
self.keys_down_duration[i] += delta_time;
}
} else {
self.keys_down_duration[i] = -1.0;
}
}
}
pub fn get_keys_pressed(&self, repeat: KeyRepeat) -> Option<Vec<Key>> {
let mut index: u16 = 0;
let mut keys: Vec<Key> = Vec::new();
for i in self.keys.iter() {
if *i {
unsafe {
if Self::key_pressed(self, index as usize, repeat) {
keys.push(mem::transmute(index as u8));
}
}
}
index += 1;
}
Some(keys)
}
#[inline]
pub fn is_key_down(&self, key: Key) -> bool {
return self.keys[key as usize];
}
#[inline]
pub fn set_key_repeat_delay(&mut self, delay: f32) {
self.key_repeat_delay = delay;
}
#[inline]
pub fn set_key_repeat_rate(&mut self, rate: f32) {
self.key_repeat_rate = rate;
}
pub fn key_pressed(&self, index: usize, repeat: KeyRepeat) -> bool {
let t = self.keys_down_duration[index];
if t == 0.0 {
return true;
}
if repeat == KeyRepeat::Yes && t > self.key_repeat_delay {
let delay = self.key_repeat_delay;
let rate = self.key_repeat_rate;
if ((((t - delay) % rate) > rate * 0.5)) != (((t - delay - self.delta_time) % rate) > rate * 0.5) {
return true;
}
}
return false;
}
pub fn is_key_pressed(&self, key: Key, repeat: KeyRepeat) -> bool {
return Self::key_pressed(self, key as usize, repeat);
}
}