1use anyhow::Result;
2use crossterm::event::{self, Event, KeyEvent};
3use std::time::Duration;
4use tokio::sync::mpsc;
5
6pub enum AppEvent {
7 Key(KeyEvent),
8 Tick,
9}
10
11pub struct EventHandler {
12 rx: mpsc::UnboundedReceiver<AppEvent>,
13}
14
15impl EventHandler {
16 pub fn new(tick_rate_ms: u64) -> Self {
17 let (tx, rx) = mpsc::unbounded_channel();
18 let tick_rate = Duration::from_millis(tick_rate_ms);
19
20 std::thread::spawn(move || {
24 loop {
25 if event::poll(tick_rate).unwrap_or(false) {
26 if let Ok(Event::Key(key)) = event::read() {
27 if tx.send(AppEvent::Key(key)).is_err() {
28 return;
29 }
30 }
31 } else if tx.send(AppEvent::Tick).is_err() {
32 return;
33 }
34 }
35 });
36
37 Self { rx }
38 }
39
40 pub async fn next(&mut self) -> Result<AppEvent> {
41 self.rx
42 .recv()
43 .await
44 .ok_or_else(|| anyhow::anyhow!("Event channel closed"))
45 }
46}