Tui #12
@@ -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)]
|
||||||
|
|||||||
@@ -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(),
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user