1 use crate::app::AppResult; 2 use crate::backend::event::BackendEvent; 3 use crossterm::event::{self, Event as CrosstermEvent, KeyEvent, MouseEvent}; 4 use std::sync::mpsc; 5 use std::thread; 6 use std::time::{Duration, Instant}; 7 8 /// Terminal events. 9 #[derive(Clone, Debug)] 10 pub enum Event { 11 /// Terminal tick. 12 Tick, 13 /// Key press. 14 Key(KeyEvent), 15 /// Mouse click/scroll. 16 Mouse(MouseEvent), 17 /// Terminal resize. 18 Resize(u16, u16), 19 Backend(BackendEvent), 20 } 21 22 /// Terminal event handler. 23 #[allow(dead_code)] 24 #[derive(Debug)] 25 pub struct EventHandler { 26 /// Event sender channel. 27 sender: mpsc::Sender<Event>, 28 /// Event receiver channel. 29 receiver: mpsc::Receiver<Event>, 30 /// Event handler thread. 31 handler: thread::JoinHandle<()>, 32 } 33 34 impl EventHandler { 35 /// Constructs a new instance of [`EventHandler`]. 36 pub fn new(tick_rate: u64) -> Self { 37 let tick_rate = Duration::from_millis(tick_rate); 38 let (sender, receiver) = mpsc::channel(); 39 let handler = { 40 let sender = sender.clone(); 41 thread::spawn(move || { 42 let mut last_tick = Instant::now(); 43 loop { 44 let timeout = tick_rate 45 .checked_sub(last_tick.elapsed()) 46 .unwrap_or(tick_rate); 47 48 if event::poll(timeout).expect("no events available") { 49 match event::read().expect("unable to read event") { 50 CrosstermEvent::Key(e) => sender.send(Event::Key(e)), 51 CrosstermEvent::Mouse(e) => sender.send(Event::Mouse(e)), 52 CrosstermEvent::Resize(w, h) => sender.send(Event::Resize(w, h)), 53 _ => unimplemented!(), 54 } 55 .expect("failed to send terminal event") 56 } 57 58 if last_tick.elapsed() >= tick_rate { 59 sender.send(Event::Tick).expect("failed to send tick event"); 60 last_tick = Instant::now(); 61 } 62 } 63 }) 64 }; 65 Self { 66 sender, 67 receiver, 68 handler, 69 } 70 } 71 72 /// Receive the next event from the handler thread. 73 /// 74 /// This function will always block the current thread if 75 /// there is no data available and it's possible for more data to be sent. 76 pub fn next(&self) -> AppResult<Event> { 77 Ok(self.receiver.recv()?) 78 } 79 80 pub fn sender(&self) -> mpsc::Sender<Event> { 81 self.sender.clone() 82 } 83 } 84