rust_sadari_cli/helper/
event.rs1use std::io;
2use std::sync::mpsc;
3use std::sync::{
4 atomic::{AtomicBool, Ordering},
5 Arc,
6};
7use std::thread;
8use std::time::Duration;
9
10use termion::event::Key;
11use termion::input::TermRead;
12
13pub enum Event<I> {
14 Input(I),
15 Tick,
16}
17
18pub struct Events {
21 rx: mpsc::Receiver<Event<Key>>,
22 _input_handle: thread::JoinHandle<()>,
23 ignore_exit_key: Arc<AtomicBool>,
24 _tick_handle: thread::JoinHandle<()>,
25}
26
27#[derive(Debug, Clone, Copy)]
28pub struct Config {
29 pub exit_key: Key,
30 pub tick_rate: Duration,
31}
32
33impl Default for Config {
34 fn default() -> Config {
35 Config {
36 exit_key: Key::Char('q'),
37 tick_rate: Duration::from_millis(250),
38 }
39 }
40}
41
42impl Events {
43 #[allow(dead_code)]
44 pub fn new() -> Events {
45 Events::with_config(Config::default())
46 }
47
48 pub fn with_config(config: Config) -> Events {
49 let (tx, rx) = mpsc::channel();
50 let ignore_exit_key = Arc::new(AtomicBool::new(false));
51 let input_handle = {
52 let tx = tx.clone();
53 let ignore_exit_key = ignore_exit_key.clone();
54 thread::spawn(move || {
55 let stdin = io::stdin();
56 for evt in stdin.keys() {
57 match evt {
58 Ok(key) => {
59 if let Err(_) = tx.send(Event::Input(key)) {
60 return;
61 }
62 if !ignore_exit_key.load(Ordering::Relaxed) && key == config.exit_key {
63 return;
64 }
65 }
66 Err(_) => {}
67 }
68 }
69 })
70 };
71 let tick_handle = {
72 let tx = tx.clone();
73 thread::spawn(move || {
74 let tx = tx.clone();
75 loop {
76 tx.send(Event::Tick).unwrap();
77 thread::sleep(config.tick_rate);
78 }
79 })
80 };
81 Events {
82 rx,
83 ignore_exit_key,
84 _input_handle: input_handle,
85 _tick_handle: tick_handle,
86 }
87 }
88
89 pub fn next(&self) -> Result<Event<Key>, mpsc::RecvError> {
90 self.rx.recv()
91 }
92
93 #[allow(dead_code)]
94 pub fn disable_exit_key(&mut self) {
95 self.ignore_exit_key.store(true, Ordering::Relaxed);
96 }
97
98 #[allow(dead_code)]
99 pub fn enable_exit_key(&mut self) {
100 self.ignore_exit_key.store(false, Ordering::Relaxed);
101 }
102}