1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
use crate::input::key::Key;
use crate::input::InputEvent;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;
use std::time::Duration;
use tokio::select;
use tokio::time::{interval, Interval};
pub struct Events {
rx: tokio::sync::mpsc::Receiver<InputEvent>,
_tx: tokio::sync::mpsc::Sender<InputEvent>,
stop_capture: Arc<AtomicBool>,
interval: Interval,
}
impl Events {
pub fn new(render_rate: Duration) -> Events {
let (tx, rx) = tokio::sync::mpsc::channel(100);
let stop_capture = Arc::new(AtomicBool::new(false));
let event_tx = tx.clone();
let event_stop_capture = stop_capture.clone();
tokio::spawn(async move {
loop {
if crossterm::event::poll(render_rate).unwrap() {
if let crossterm::event::Event::Key(key) = crossterm::event::read().unwrap() {
let key = Key::from(key);
if let Err(err) = event_tx.send(InputEvent::Input(key)).await {
log::error!("Oops (event)!, {}", err);
}
}
}
if event_stop_capture.load(Ordering::Relaxed) {
break;
}
}
});
Events {
rx,
_tx: tx,
stop_capture,
interval: interval(render_rate),
}
}
pub async fn next(&mut self) -> InputEvent {
select! {
msg = self.rx.recv() => msg.unwrap_or(InputEvent::Quit),
_ = self.interval.tick() => InputEvent::Render,
}
}
}
impl Drop for Events {
fn drop(&mut self) {
self.stop_capture.store(true, Ordering::Relaxed)
}
}