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