Update main to gamelog v0.7.1 and early tui model from dev. #15

Merged
Cutieguwu merged 23 commits from dev into main 2025-04-23 19:02:36 -04:00
2 changed files with 44 additions and 66 deletions
Showing only changes of commit d211c1339c - Show all commits

View File

@@ -2,8 +2,9 @@ mod tui;
use clap::{ArgAction, Parser}; use clap::{ArgAction, Parser};
use core::panic; use core::panic;
use gamelog::{Action, Down, Flags, Key, LogFile, Team}; use gamelog::{Action, Down, Key, LogFile, Team};
use std::path::PathBuf; use std::{io, path::PathBuf, sync::mpsc, thread};
use tui::App;
#[derive(Debug, Parser)] #[derive(Debug, Parser)]
#[clap(author, version, about)] #[clap(author, version, about)]
@@ -22,9 +23,12 @@ struct Args {
// ArgAction::SetTrue by default evaluates to false. // ArgAction::SetTrue by default evaluates to false.
#[arg(short, long, action=ArgAction::SetFalse)] #[arg(short, long, action=ArgAction::SetFalse)]
display_results: bool, display_results: bool,
#[arg(short, long, action=ArgAction::SetTrue)]
no_tui: bool,
} }
fn main() { fn main() -> io::Result<()> {
let config = Args::parse(); let config = Args::parse();
let log: LogFile = match LogFile::try_from(config.logfile_path) { 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), Err(err) => panic!("Error: Failed to open logfile: {:?}", err),
}; };
let mut stats = vec![ if config.no_tui {
TeamStats::new(Team::ArizonaState), return;
#[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.display_results { let mut app = App { exit: false };
// :#? for pretty-printing.
stats.iter().for_each(|team| println!("{:#?}", team)); // Enter Raw terminal mode.
} let mut terminal = ratatui::init();
let (tx, rx) = mpsc::channel::<tui::Event>();
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)] #[derive(Debug)]

View File

@@ -11,16 +11,20 @@ use ratatui::{
widgets::Widget, widgets::Widget,
}; };
enum Event { pub enum Event {
Input(crossterm::event::KeyEvent), Input(crossterm::event::KeyEvent),
} }
pub struct App { pub struct App {
exit: bool, pub exit: bool,
} }
impl App { impl App {
fn run(&mut self, terminal: &mut DefaultTerminal, rx: mpsc::Receiver<Event>) -> io::Result<()> { pub fn run(
&mut self,
terminal: &mut DefaultTerminal,
rx: mpsc::Receiver<Event>,
) -> io::Result<()> {
while !self.exit { while !self.exit {
// Render frame. // Render frame.
terminal.draw(|frame| self.draw(frame))?; terminal.draw(|frame| self.draw(frame))?;
@@ -35,11 +39,11 @@ impl App {
Ok(()) Ok(())
} }
fn draw(&self, frame: &mut Frame) { pub fn draw(&self, frame: &mut Frame) {
frame.render_widget(self, frame.area()); 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') { if key_event.kind == KeyEventKind::Press && key_event.code == KeyCode::Char('q') {
self.exit = true; self.exit = true;
} }
@@ -56,3 +60,13 @@ impl Widget for &App {
let layout: Layout; let layout: Layout;
} }
} }
pub fn input_fetcher(tx: mpsc::Sender<Event>) {
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(),
_ => (),
}
}
}