rush_sync_server/input/
mod.rs1pub mod input;
6pub mod keyboard;
7
8use crossterm::event::{self as crossterm_event, Event as CrosstermEvent, KeyEvent};
10use tokio::sync::mpsc::{self, Sender};
11use tokio::time::{interval, Duration};
12
13#[derive(Debug)]
14pub enum AppEvent {
15 Input(KeyEvent),
16 Tick,
17 Resize(u16, u16),
18}
19
20pub struct EventHandler {
21 rx: mpsc::Receiver<AppEvent>,
22 shutdown_tx: Vec<Sender<()>>,
23}
24
25impl EventHandler {
26 pub fn new(tick_rate: Duration) -> Self {
27 let (tx, rx) = mpsc::channel(100);
28 let mut shutdown_tx = Vec::new();
29
30 let (input_shutdown_tx, mut input_shutdown_rx) = mpsc::channel(1);
32 shutdown_tx.push(input_shutdown_tx);
33
34 let input_tx = tx.clone();
36 tokio::spawn(async move {
37 let mut last_event_time = tokio::time::Instant::now();
38 let min_event_interval = Duration::from_millis(33);
39
40 loop {
41 tokio::select! {
42 _ = input_shutdown_rx.recv() => break,
43 _ = async {
44 if crossterm_event::poll(Duration::from_millis(99)).unwrap() {
45 let now = tokio::time::Instant::now();
46 if now.duration_since(last_event_time) >= min_event_interval {
47 if let Ok(event) = crossterm_event::read() {
48 match event {
49 CrosstermEvent::Key(key) => {
50 let _ = input_tx.send(AppEvent::Input(key)).await;
51 }
52 CrosstermEvent::Resize(width, height) => {
53 let _ = input_tx.send(AppEvent::Resize(width, height)).await;
54 }
55 _ => {}
56 }
57 last_event_time = now;
58 }
59 }
60 }
61 } => {}
62 }
63 }
64 });
65
66 let (tick_shutdown_tx, mut tick_shutdown_rx) = mpsc::channel(1);
68 shutdown_tx.push(tick_shutdown_tx);
69
70 let tick_tx = tx;
71 tokio::spawn(async move {
72 let mut interval = interval(tick_rate);
73 loop {
74 tokio::select! {
75 _ = tick_shutdown_rx.recv() => break,
76 _ = interval.tick() => {
77 let _ = tick_tx.send(AppEvent::Tick).await;
78 }
79 }
80 }
81 });
82
83 EventHandler { rx, shutdown_tx }
84 }
85
86 pub async fn next(&mut self) -> Option<AppEvent> {
87 self.rx.recv().await
88 }
89
90 pub async fn shutdown(&mut self) {
91 for tx in self.shutdown_tx.iter() {
92 let _ = tx.send(()).await;
93 }
94 }
95}