From e57902d80f5d0ccd9e44dc78b0b7763ed6cb4760 Mon Sep 17 00:00:00 2001 From: Scott Pruett Date: Mon, 23 May 2022 20:36:05 -0400 Subject: [PATCH] start adding debugging UI --- learned.json | 1 + src/control_loop.rs | 42 ++++++++++++++++++++++++------------------ src/main.rs | 18 +++++++++++++++--- src/state.rs | 16 +++++++++------- 4 files changed, 49 insertions(+), 28 deletions(-) diff --git a/learned.json b/learned.json index 1c7f325..357b46a 100644 --- a/learned.json +++ b/learned.json @@ -1,5 +1,6 @@ { "learned_images": { + "AAAAAAAAAAA=": "" }, "learned_tracks": {} } \ No newline at end of file diff --git a/src/control_loop.rs b/src/control_loop.rs index 1a592d0..7908621 100644 --- a/src/control_loop.rs +++ b/src/control_loop.rs @@ -13,10 +13,10 @@ use crate::{ capture, image_processing::{self, hash_image, Region, extract_and_filter}, ocr, - state::{AppState, DebugOcrFrame, ParsedFrame, RaceState, SharedAppState}, + state::{AppState, DebugOcrFrame, LapState, RaceState, SharedAppState}, config::Config, }; -fn is_finished_lap(state: &AppState, frame: &ParsedFrame) -> bool { +fn is_finished_lap(state: &AppState, frame: &LapState) -> bool { if let Some(race) = &state.current_race { if let Some(last_finish) = &race.last_lap_record_time { let diff = Instant::now().duration_since(*last_finish); @@ -49,19 +49,19 @@ fn merge_with_max(a: &Option, b: &Option) -> Option { } } -fn merge_frames(prev: &ParsedFrame, next: &ParsedFrame) -> ParsedFrame { - ParsedFrame { +fn merge_frames(prev: &LapState, next: &LapState) -> LapState { + LapState { lap: merge_with_max(&prev.lap, &next.lap), health: merge_with_max(&prev.health, &next.health), gas: merge_with_max(&prev.gas, &next.gas), tyres: merge_with_max(&prev.tyres, &next.tyres), lap_time: merge_with_max(&prev.lap_time, &next.lap_time), best_time: merge_with_max(&prev.best_time, &next.best_time), - striked: false, + ..Default::default() } } -fn handle_new_frame(state: &mut AppState, frame: ParsedFrame, image: &RgbImage) { +fn handle_new_frame(state: &mut AppState, frame: LapState, image: RgbImage) { if frame.lap_time.is_some() { state.last_frame = Some(frame.clone()); state.frames_without_lap = 0; @@ -71,7 +71,7 @@ fn handle_new_frame(state: &mut AppState, frame: ParsedFrame, image: &RgbImage) race.screencap = Some( RetainedImage::from_image_bytes( "screencap", - &image_processing::to_png_bytes(image), + &image_processing::to_png_bytes(&image), ) .expect("failed to save screenshot"), ); @@ -93,6 +93,7 @@ fn handle_new_frame(state: &mut AppState, frame: ParsedFrame, image: &RgbImage) if let Some(lap) = &merged.lap { merged.lap = Some(lap - 1); } + merged.screenshot = Some(image); if let Some(race) = state.current_race.as_mut() { if let Some(prev_lap) = race.laps.last() { @@ -147,26 +148,31 @@ fn run_loop_once(capturer: &mut Capturer, state: &SharedAppState) -> Result<()> let frame = capture::get_frame(capturer)?; let ocr_results = ocr::ocr_all_regions(&frame, config.clone(), learned_config, ocr_cache); - let mut saved_frames = HashMap::new(); - if state.lock().unwrap().debug_frames { - for region in &config.ocr_regions { - add_saved_frame(&mut saved_frames, &frame, region); - } - if let Some(track_region) = &config.track_region { - add_saved_frame(&mut saved_frames, &frame, track_region); - } + let debug_frames = save_frames_from(&frame, config.as_ref()); + state.lock().unwrap().saved_frames = debug_frames; } { let mut state = state.lock().unwrap(); - let mut parsed = ParsedFrame::parse(&ocr_results); - handle_new_frame(&mut state, parsed, &frame); + let parsed = LapState::parse(&ocr_results); + state.raw_data = ocr_results; - state.saved_frames = saved_frames; + handle_new_frame(&mut state, parsed, frame); } Ok(()) } +pub fn save_frames_from(frame: &RgbImage, config: &Config) -> HashMap { + let mut saved_frames = HashMap::new(); + for region in &config.ocr_regions { + add_saved_frame(&mut saved_frames, frame, region); + } + if let Some(track_region) = &config.track_region { + add_saved_frame(&mut saved_frames, frame, track_region); + } + saved_frames +} + pub fn run_control_loop(state: SharedAppState) { let mut capturer = Capturer::new(Display::primary().unwrap()).unwrap(); loop { diff --git a/src/main.rs b/src/main.rs index 642f9de..b3b1e9b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,7 +11,7 @@ mod stats_writer; use std::{ sync::{Arc, Mutex}, thread, - time::{Duration, Instant}, + time::Duration, }; use config::{Config, LearnedConfig}; @@ -20,7 +20,7 @@ use eframe::{ emath::Vec2, epaint::Color32, }; -use state::{AppState, RaceState, SharedAppState, ParsedFrame}; +use state::{AppState, RaceState, SharedAppState, LapState}; use stats_writer::export_race_stats; fn main() -> anyhow::Result<()> { @@ -120,7 +120,7 @@ fn show_race_state(ui: &mut Ui, race_name: &str, race: &mut RaceState) { ui.label("Gas"); ui.label("Tyres"); ui.end_row(); - let mut prev_lap: Option<&ParsedFrame> = None; + let mut prev_lap: Option<&LapState> = None; for (i, lap) in race.laps.iter_mut().enumerate() { if let Some(lap_time) = lap.lap_time { ui.label(format!("#{}", lap.lap.unwrap_or(i + 1))); @@ -156,6 +156,18 @@ fn show_race_state(ui: &mut Ui, race_name: &str, race: &mut RaceState) { } } + if lap.debug { + if ui.button("Hide debug").clicked() { + lap.debug = false; + } + ui.end_row(); + // TODO(DEBUG): ??? + } else { + if ui.button("Debug").clicked( ){ + lap.debug = true; + } + } + ui.end_row(); } prev_lap = Some(lap); diff --git a/src/state.rs b/src/state.rs index c12757a..fe6abf4 100644 --- a/src/state.rs +++ b/src/state.rs @@ -7,8 +7,8 @@ use time::{OffsetDateTime, format_description}; use crate::config::{Config, LearnedConfig}; -#[derive(Debug, Clone)] -pub struct ParsedFrame { +#[derive(Debug, Clone, Default)] +pub struct LapState { pub lap: Option, pub health: Option, @@ -19,6 +19,8 @@ pub struct ParsedFrame { pub lap_time: Option, pub striked: bool, + pub screenshot: Option, + pub debug: bool, } fn parse_duration(time: &str) -> Option { @@ -47,7 +49,7 @@ fn parse_to_0_100(v: Option<&Option>) -> Option { check_0_100(v?.clone()?.parse::().ok()?) } -impl ParsedFrame { +impl LapState { pub fn parse(raw: &HashMap>) -> Self { Self { lap: parse_to_0_100(raw.get("lap")), @@ -56,7 +58,7 @@ impl ParsedFrame { tyres: parse_to_0_100(raw.get("tyres")), best_time: parse_to_duration(raw.get("best")), lap_time: parse_to_duration(raw.get("lap_time")), - striked: false, + ..Default::default() } } } @@ -64,7 +66,7 @@ impl ParsedFrame { #[derive(Default)] pub struct RaceState { pub race_time: Option, - pub laps: Vec, + pub laps: Vec, pub last_lap_record_time: Option, pub screencap: Option, @@ -98,9 +100,9 @@ pub struct DebugOcrFrame { #[derive(Default)] pub struct AppState { pub raw_data: HashMap>, - pub last_frame: Option, + pub last_frame: Option, - pub buffered_frames: VecDeque, + pub buffered_frames: VecDeque, pub frames_without_lap: usize, pub current_race: Option,