diff --git a/benchmark/src/event.rs b/benchmark/src/event.rs new file mode 100644 index 00000000..e273a9a7 --- /dev/null +++ b/benchmark/src/event.rs @@ -0,0 +1,50 @@ +/// Inspired by https://github.com/orhun/rust-tui-template +use crossterm::event; +use tokio::sync::{mpsc, broadcast}; +use std::time::{Duration, Instant}; + +/// Events +#[derive(Debug)] +pub(crate) enum Event { + /// Terminal tick. + Tick, + /// Key press. + Key(event::KeyEvent), + /// Terminal resize. + Resize(u16, u16), +} + +pub(crate) async fn terminal_event_task(fps: u32, event_sender: mpsc::Sender<Event>, + mut shutdown_receiver: broadcast::Receiver<()>, + _shutdown_guard_sender: mpsc::Sender<()>, +) { + tokio::select! { + _ = event_loop(fps, event_sender) => { + }, + _ = shutdown_receiver.recv() => {} + } +} + +async fn event_loop(fps: u32, event_sender: mpsc::Sender<Event>, +) { + let per_frame = Duration::from_secs(1) / fps as u32; + let mut last_frame = Instant::now(); + loop { + if let Some(sleep) = per_frame.checked_sub(last_frame.elapsed()) { + tokio::time::sleep(sleep).await; + } + + if event::poll(Duration::from_secs(0)).expect("no events available") { + match event::read().expect("unable to read event") { + event::Event::Key(e) => event_sender.send(Event::Key(e)).await.unwrap_or(()), + event::Event::Resize(w, h) => event_sender.send(Event::Resize(w, h)).await.unwrap_or(()), + _ => (), + } + } + + if last_frame.elapsed() >= per_frame { + event_sender.send(Event::Tick).await.unwrap_or(()); + last_frame = Instant::now(); + } + } +} diff --git a/benchmark/src/generation.rs b/benchmark/src/generation.rs index bdc7d084..024b1320 100644 --- a/benchmark/src/generation.rs +++ b/benchmark/src/generation.rs @@ -55,7 +55,6 @@ pub(crate) async fn generation_task( }, _ = shutdown_receiver.recv() => {} } - ; } async fn generate_runs(tokenizer: Tokenizer, diff --git a/benchmark/src/lib.rs b/benchmark/src/lib.rs index 935c11dc..61acc331 100644 --- a/benchmark/src/lib.rs +++ b/benchmark/src/lib.rs @@ -3,6 +3,7 @@ extern crate core; mod ui; mod utils; mod generation; +mod event; use crate::ui::UI; use tokenizers::Tokenizer;