use crate::*; use std::time::Duration; use std::thread::{spawn, JoinHandle}; use crossterm::event::{poll, read}; #[derive(Debug, Clone)] pub struct TuiIn(pub Arc, pub Event); impl Input for TuiIn { type Event = Event; type Handled = bool; fn event (&self) -> &Event { &self.1 } fn is_done (&self) -> bool { self.0.fetch_and(true, Relaxed) } fn done (&self) { self.0.store(true, Relaxed); } } impl TuiIn { /// Spawn the input thread. pub fn run_input + 'static> ( engine: &Arc>, state: &Arc>, timer: Duration ) -> JoinHandle<()> { let exited = engine.read().unwrap().exited.clone(); let state = state.clone(); spawn(move || loop { if exited.fetch_and(true, Relaxed) { break } if poll(timer).is_ok() { let event = read().unwrap(); match event { crossterm::event::Event::Key(KeyEvent { code: KeyCode::Char('c'), modifiers: KeyModifiers::CONTROL, kind: KeyEventKind::Press, state: KeyEventState::NONE }) => { exited.store(true, Relaxed); }, _ => { let exited = exited.clone(); if let Err(e) = state.write().unwrap().handle(&TuiIn(exited, event)) { panic!("{e}") } } } } }) } } impl DslInput for TuiIn { fn matches_dsl (&self, token: &str) -> bool { if let Some(event) = KeyMatcher::new(token).build() { &event == self.event() } else { false } } }