1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283 |
- use crate::app::AppResult;
- use crate::backend::event::BackendEvent;
- use crossterm::event::{self, Event as CrosstermEvent, KeyEvent, MouseEvent};
- use std::sync::mpsc;
- use std::thread;
- use std::time::{Duration, Instant};
- /// Terminal events.
- #[derive(Clone, Debug)]
- pub enum Event {
- /// Terminal tick.
- Tick,
- /// Key press.
- Key(KeyEvent),
- /// Mouse click/scroll.
- Mouse(MouseEvent),
- /// Terminal resize.
- Resize(u16, u16),
- Backend(BackendEvent),
- }
- /// Terminal event handler.
- #[allow(dead_code)]
- #[derive(Debug)]
- pub struct EventHandler {
- /// Event sender channel.
- sender: mpsc::Sender<Event>,
- /// Event receiver channel.
- receiver: mpsc::Receiver<Event>,
- /// Event handler thread.
- handler: thread::JoinHandle<()>,
- }
- impl EventHandler {
- /// Constructs a new instance of [`EventHandler`].
- pub fn new(tick_rate: u64) -> Self {
- let tick_rate = Duration::from_millis(tick_rate);
- let (sender, receiver) = mpsc::channel();
- let handler = {
- let sender = sender.clone();
- thread::spawn(move || {
- let mut last_tick = Instant::now();
- loop {
- let timeout = tick_rate
- .checked_sub(last_tick.elapsed())
- .unwrap_or(tick_rate);
- if event::poll(timeout).expect("no events available") {
- match event::read().expect("unable to read event") {
- CrosstermEvent::Key(e) => sender.send(Event::Key(e)),
- CrosstermEvent::Mouse(e) => sender.send(Event::Mouse(e)),
- CrosstermEvent::Resize(w, h) => sender.send(Event::Resize(w, h)),
- _ => unimplemented!(),
- }
- .expect("failed to send terminal event")
- }
- if last_tick.elapsed() >= tick_rate {
- sender.send(Event::Tick).expect("failed to send tick event");
- last_tick = Instant::now();
- }
- }
- })
- };
- Self {
- sender,
- receiver,
- handler,
- }
- }
- /// Receive the next event from the handler thread.
- ///
- /// This function will always block the current thread if
- /// there is no data available and it's possible for more data to be sent.
- pub fn next(&self) -> AppResult<Event> {
- Ok(self.receiver.recv()?)
- }
- pub fn sender(&self) -> mpsc::Sender<Event> {
- self.sender.clone()
- }
- }
|