use crate::error::Result;
use crossterm::event::{self, Event as CrosstermEvent, KeyEvent};
use std::sync::mpsc;
use std::thread;
use std::time::Duration;
#[derive(Debug)]
pub enum Event {
Key(KeyEvent),
Resize(u16, u16),
Tick,
}
pub struct EventHandler {
receiver: mpsc::Receiver<Event>,
#[allow(dead_code)]
sender: mpsc::Sender<Event>,
}
impl EventHandler {
#[must_use]
pub fn new(tick_rate: u64) -> Self {
let (sender, receiver) = mpsc::channel();
let tick_rate = Duration::from_millis(tick_rate);
let sender_clone = sender.clone();
thread::spawn(move || {
loop {
if event::poll(tick_rate).unwrap_or(false) {
match event::read() {
Ok(CrosstermEvent::Key(key)) => {
if sender_clone.send(Event::Key(key)).is_err() {
break;
}
}
Ok(CrosstermEvent::Resize(w, h)) => {
if sender_clone.send(Event::Resize(w, h)).is_err() {
break;
}
}
_ => {}
}
} else {
if sender_clone.send(Event::Tick).is_err() {
break;
}
}
}
});
Self { receiver, sender }
}
pub fn next(&self) -> Result<Event> {
Ok(self.receiver.recv().unwrap_or(Event::Tick))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_event_handler_creation() {
let handler = EventHandler::new(100);
drop(handler);
}
}