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
68
69
use std::thread;
use crossbeam_channel::Receiver;
use crossterm::event::Event;
use log::{error, warn};
use crate::io::input::Input;
use crate::io::input_event::InputEvent;
use crate::io::input_source::InputSource;
use crate::io::keys::Key;
pub struct CrosstermInput {
receiver: Receiver<InputEvent>,
}
impl CrosstermInput {
pub fn new() -> Self {
let (send, recv) = crossbeam_channel::unbounded::<InputEvent>();
thread::spawn(move || {
loop {
let event = crossterm::event::read();
match event {
Err(err) => {
error!("received error {:?}, closing crossterm input.", err);
break;
}
Ok(raw_event) => {
let processed_event: Option<InputEvent> = match raw_event {
Event::Key(ckey) => {
let key: Key = ckey.into();
Some(InputEvent::KeyInput(key))
}
Event::Mouse(_) => None,
Event::Resize(_, _) => {
None // TODO
}
Event::FocusGained => None,
Event::FocusLost => None,
//TODO
Event::Paste(..) => None,
};
// debug!("got {:?}", processed_event);
match processed_event {
None => continue,
Some(event) => match send.send(event) {
Ok(_) => continue,
Err(err) => {
warn!("failed sending event {:?} because {}", event, err);
break;
}
},
}
}
};
}
});
CrosstermInput { receiver: recv }
}
}
impl Input for CrosstermInput {
fn source(&self) -> &InputSource {
&self.receiver
}
}