diff --git a/miller/src/main.rs b/miller/src/main.rs index 18c40fa..15bdc7c 100644 --- a/miller/src/main.rs +++ b/miller/src/main.rs @@ -2,8 +2,9 @@ mod tui; use clap::{ArgAction, Parser}; use core::panic; -use gamelog::{Action, Down, Flags, Key, LogFile, Team}; -use std::path::PathBuf; +use gamelog::{Action, Down, Key, LogFile, Team}; +use std::{io, path::PathBuf, sync::mpsc, thread}; +use tui::App; #[derive(Debug, Parser)] #[clap(author, version, about)] @@ -22,9 +23,12 @@ struct Args { // ArgAction::SetTrue by default evaluates to false. #[arg(short, long, action=ArgAction::SetFalse)] display_results: bool, + + #[arg(short, long, action=ArgAction::SetTrue)] + no_tui: bool, } -fn main() { +fn main() -> io::Result<()> { let config = Args::parse(); let log: LogFile = match LogFile::try_from(config.logfile_path) { @@ -32,66 +36,26 @@ fn main() { Err(err) => panic!("Error: Failed to open logfile: {:?}", err), }; - let mut stats = vec![ - TeamStats::new(Team::ArizonaState), - #[allow(deprecated)] - TeamStats::new(Team::BoiseState), - TeamStats::new(Team::Colorado), - TeamStats::new(Team::Iowa), - TeamStats::new(Team::Nebraska), - TeamStats::new(Team::Syracuse), - TeamStats::new(Team::SouthCarolina), - TeamStats::new(Team::TexasAnM), - ]; - - // Work on knocking down the nesting here? - for game in log.0.iter() { - let teams = match game.teams() { - Ok(teams) => teams, - Err(_) => continue, - }; - - for team in teams { - // Skip team if they are to be ignored this game. - if game.flags.contains(&Flags::IgnoreTeam(team.to_owned())) { - continue; - } - - let team_idx = stats - .iter() - .position(|stat| stat.team == team.to_owned()) - .unwrap(); - - stats[team_idx] - .avg_terrain_gain - .push(game.avg_gain(team.to_owned())); - - stats[team_idx] - .avg_terrain_loss - .push(game.avg_loss(team.to_owned())); - - stats[team_idx] - .avg_terrain_delta - .push(game.avg_delta(team.to_owned())); - - stats[team_idx] - .plays_per_quarter - .push(game.avg_plays_per_quarter(team.to_owned())); - - stats[team_idx] - .plays_per_game - .push(game.team_plays(team.to_owned())); - - stats[team_idx] - .penalties_per_game - .push(game.penalties(team.to_owned())); - } + if config.no_tui { + return; } - if config.display_results { - // :#? for pretty-printing. - stats.iter().for_each(|team| println!("{:#?}", team)); - } + let mut app = App { exit: false }; + + // Enter Raw terminal mode. + let mut terminal = ratatui::init(); + + let (tx, rx) = mpsc::channel::(); + + let tx_input_fetcher = tx.clone(); + thread::spawn(move || tui::input_fetcher(tx_input_fetcher)); + + let app_result = app.run(&mut terminal, rx); + + // Exit Raw terminal mode. + ratatui::restore(); + + app_result } #[derive(Debug)] diff --git a/miller/src/tui.rs b/miller/src/tui.rs index 7f7c228..08326e2 100644 --- a/miller/src/tui.rs +++ b/miller/src/tui.rs @@ -11,16 +11,20 @@ use ratatui::{ widgets::Widget, }; -enum Event { +pub enum Event { Input(crossterm::event::KeyEvent), } pub struct App { - exit: bool, + pub exit: bool, } impl App { - fn run(&mut self, terminal: &mut DefaultTerminal, rx: mpsc::Receiver) -> io::Result<()> { + pub fn run( + &mut self, + terminal: &mut DefaultTerminal, + rx: mpsc::Receiver, + ) -> io::Result<()> { while !self.exit { // Render frame. terminal.draw(|frame| self.draw(frame))?; @@ -35,11 +39,11 @@ impl App { Ok(()) } - fn draw(&self, frame: &mut Frame) { + pub fn draw(&self, frame: &mut Frame) { frame.render_widget(self, frame.area()); } - fn handle_key_event(&mut self, key_event: crossterm::event::KeyEvent) -> io::Result<()> { + pub fn handle_key_event(&mut self, key_event: crossterm::event::KeyEvent) -> io::Result<()> { if key_event.kind == KeyEventKind::Press && key_event.code == KeyCode::Char('q') { self.exit = true; } @@ -56,3 +60,13 @@ impl Widget for &App { let layout: Layout; } } + +pub fn input_fetcher(tx: mpsc::Sender) { + loop { + // unwraps, bc what could go wrong? + match crossterm::event::read().unwrap() { + crossterm::event::Event::Key(key_event) => tx.send(Event::Input(key_event)).unwrap(), + _ => (), + } + } +}