tengri/tui/src/tui_engine/tui_input.rs
2025-07-14 22:22:45 +03:00

68 lines
2 KiB
Rust

use crate::*;
use std::time::Duration;
use std::thread::{spawn, JoinHandle};
use crossterm::event::{poll, read};
#[derive(Debug, Clone)]
pub struct TuiIn(
/// Exit flag
pub Arc<AtomicBool>,
/// Input event
pub crossterm::event::Event,
);
impl Input for TuiIn {
type Event = crossterm::event::Event;
type Handled = bool;
fn event (&self) -> &crossterm::event::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 <T: Handle<TuiIn> + Send + Sync + 'static> (
engine: &Arc<RwLock<Tui>>,
state: &Arc<RwLock<T>>,
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}")
}
}
}
}
})
}
}
//#[cfg(feature = "dsl")]
//impl DslInput for TuiIn {
//fn matches_dsl (&self, token: &str) -> bool {
//if let Some(event) = KeyMatcher::new(token).build() {
//&event == self.event()
//} else {
//false
//}
//}
//}