event.rs 2.6 KB

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