use std::{cell::OnceCell, future::Future, rc::Rc, time::Duration}; use futures_util::FutureExt; use ratatui::crossterm::event; use thecockpit::app::{App, AppExecutor}; struct TokioExecutor; impl AppExecutor for TokioExecutor { fn execute( &self, future: impl Future + 'static, output_cell: Rc>, ) { tokio::task::spawn_local(future.map(move |output| output_cell.set(output))); } } fn main() { let rt = tokio::runtime::Builder::new_current_thread() .enable_all() .build() .unwrap(); let local = tokio::task::LocalSet::new(); local.spawn_local(async { let mut terminal = ratatui::init(); let mut app = App::new(TokioExecutor); loop { terminal.draw(|frame| app.draw(frame)).unwrap(); if event::poll(Duration::from_secs(0)).unwrap() { match event::read().unwrap() { event::Event::Key(event::KeyEvent { code: event::KeyCode::Char('q'), .. }) => break, event::Event::Key(event::KeyEvent { code: event::KeyCode::Left, .. }) => app.prev_tab(), event::Event::Key(event::KeyEvent { code: event::KeyCode::Right, .. }) => app.next_tab(), event::Event::Key(event::KeyEvent { code: event::KeyCode::Up, .. }) => app.prev_item(), event::Event::Key(event::KeyEvent { code: event::KeyCode::Down, .. }) => app.next_item(), event::Event::Key(event::KeyEvent { code: event::KeyCode::Char(c), .. }) => app.add_char_to_number_guess(c), _ => {} } } tokio::task::yield_now().await; } ratatui::restore(); }); rt.block_on(local); }