use crate::utils::UpdatableSignal;
use cotis_utils::interactivity::keyboard::{
KeyboardKey, SimpleKeyboardProvider, SimpleTextProvider,
};
use std::collections::{HashMap, HashSet, VecDeque};
pub struct KeyboardManager {
keys: HashMap<KeyboardKey, UpdatableSignal>,
latest_key: Option<KeyboardKey>,
}
impl Default for KeyboardManager {
fn default() -> Self {
Self::new()
}
}
impl KeyboardManager {
pub fn new() -> KeyboardManager {
Self {
keys: Default::default(),
latest_key: None,
}
}
pub fn update(&mut self, provider: &dyn SimpleKeyboardProvider) {
let keys = provider.get_pressed_keys();
self.latest_key = keys.last().cloned();
let keys: HashSet<_> = keys.into_iter().collect();
for (key, signal) in self.keys.iter_mut() {
if !keys.contains(key) {
signal.update(false);
}
}
for key in keys {
if let Some(signal) = self.keys.get_mut(&key) {
signal.update(true);
} else {
let mut signal = UpdatableSignal::new(false);
signal.update(true);
self.keys.insert(key, signal);
}
}
}
pub fn is_key_pressed(&self, key: KeyboardKey) -> bool {
if let Some(signal) = self.keys.get(&key) {
signal.rising_edge()
} else {
false
}
}
pub fn is_key_pressed_repeat(&self, key: KeyboardKey) -> bool {
if let Some(signal) = self.keys.get(&key) {
signal.is_on_long()
} else {
false
}
}
pub fn is_key_down(&self, key: KeyboardKey) -> bool {
if let Some(signal) = self.keys.get(&key) {
signal.is_on()
} else {
false
}
}
pub fn is_key_up(&self, key: KeyboardKey) -> bool {
!self.is_key_down(key)
}
pub fn is_key_released(&self, key: KeyboardKey) -> bool {
if let Some(signal) = self.keys.get(&key) {
signal.falling_edge()
} else {
false
}
}
pub fn get_key_pressed(&mut self) -> Option<KeyboardKey> {
self.latest_key
}
}
pub struct TextManager {
buffer: VecDeque<char>,
}
impl Default for TextManager {
fn default() -> Self {
Self::new()
}
}
impl TextManager {
pub fn new() -> TextManager {
Self {
buffer: Default::default(),
}
}
pub fn update(&mut self, provider: &dyn SimpleTextProvider) {
for c in provider.get_pressed_chars() {
self.buffer.push_back(c);
}
}
pub fn clear(&mut self) {
self.buffer.clear();
}
pub fn pop(&mut self) -> Option<char> {
self.buffer.pop_front()
}
pub fn peek(&mut self) -> Option<&char> {
self.buffer.front()
}
}