zond_engine/core/
input.rs1use crossterm::{
8 event::{self, Event, KeyCode, KeyEventKind, KeyModifiers},
9 terminal::{disable_raw_mode, enable_raw_mode},
10};
11use std::{sync::mpsc, thread};
12
13pub struct InputHandle {
14 rx: mpsc::Receiver<Event>,
15 tx: Option<mpsc::Sender<Event>>,
16}
17
18impl Default for InputHandle {
19 fn default() -> Self {
20 Self::new()
21 }
22}
23
24impl InputHandle {
25 pub fn new() -> Self {
26 let (tx, rx) = mpsc::channel();
27 Self { rx, tx: Some(tx) }
28 }
29
30 pub fn start(&mut self) {
31 if let Some(tx) = self.tx.take() {
32 thread::spawn(move || {
33 enable_raw_mode().expect("failed to enable raw mode");
34 loop {
35 if let Ok(Event::Key(key_event)) = event::read() {
36 let is_q = key_event.code == KeyCode::Char('q');
37 let is_ctrl_c = key_event.code == KeyCode::Char('c')
38 && key_event.modifiers.contains(KeyModifiers::CONTROL);
39
40 if (is_q || is_ctrl_c) && key_event.kind == KeyEventKind::Press {
41 let _ = tx.send(Event::Key(key_event));
42 break;
43 }
44 }
45 }
46 let _ = disable_raw_mode();
47 });
48 }
49 }
50
51 pub fn should_interrupt(&self) -> bool {
52 match self.rx.try_recv() {
53 Ok(Event::Key(event)) => {
54 event.code == KeyCode::Char('q') || event.code == KeyCode::Char('c')
55 }
56 _ => false,
57 }
58 }
59}
60
61impl Drop for InputHandle {
62 fn drop(&mut self) {
63 let _ = disable_raw_mode();
64 }
65}