From 2dd7d2f83e3d80869c6c70a474e5d0aeac5e7ccd Mon Sep 17 00:00:00 2001 From: Nahuel Lofeudo Date: Thu, 14 May 2026 08:42:10 +0100 Subject: [PATCH] Checkpoint --- src/gtfs/mod.rs | 5 ++++- src/gtfs/structs.rs | 2 ++ src/main.rs | 31 +++++++++++++++++++------------ src/renderer/mod.rs | 17 ++++++++++------- src/renderer/structs.rs | 13 +++++++------ 5 files changed, 42 insertions(+), 26 deletions(-) diff --git a/src/gtfs/mod.rs b/src/gtfs/mod.rs index 9f7a0e1..5d2f233 100644 --- a/src/gtfs/mod.rs +++ b/src/gtfs/mod.rs @@ -68,10 +68,13 @@ impl Gtfs { if trips.contains_key(&stop_time.trip_id) { let stop_timestamp = stop_time.departure_time.or(stop_time.arrival_time).unwrap(); debug!("Stop timestamp {} current timestamp {}", stop_timestamp, current_timestamp); + let trip= &self.trips.get(&stop_time.trip_id).unwrap(); if current_timestamp < stop_timestamp.into() { let arrival: Arrival = Arrival { - route: self.routes.get(&self.trips.get(&stop_time.trip_id).unwrap().route_id).unwrap(), + route: self.routes.get(&trip.route_id).unwrap(), stop: self.stops.get(&stop_time.stop_id).unwrap(), + stop_time: stop_time, + trip: &trip, departure_time: NaiveTime::from_num_seconds_from_midnight_opt(stop_timestamp, 0).unwrap() }; arrivals.push(arrival); diff --git a/src/gtfs/structs.rs b/src/gtfs/structs.rs index 0bcd116..f33ce5f 100644 --- a/src/gtfs/structs.rs +++ b/src/gtfs/structs.rs @@ -35,4 +35,6 @@ pub struct Arrival<'a> { pub departure_time: NaiveTime, pub route: &'a Route, pub stop: &'a Stop, + pub stop_time: &'a RawStopTime, + pub trip: &'a RawTrip, } \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 8736a07..adcdcdb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,6 @@ mod gtfs; mod renderer; -use std::{collections::{HashSet, btree_map::Entry}, ops::Add, process, thread::Builder, time::SystemTime}; +use std::{collections::{HashSet, btree_map::Entry}, ops::Add, process, rc::Rc, thread::Builder, time::SystemTime}; use chrono::{DateTime, Duration, Local, NaiveTime}; use log::{Metadata, Record, debug, error, info}; use sdl3::event::Event; @@ -15,7 +15,7 @@ struct RefreshDataEvent { } -fn refresh_schedule<'a>(gtfs: &'a Gtfs, screen: &'a Screen<'a>) -> Vec> { +fn refresh_schedule<'a>(gtfs: &'a Gtfs, screen: &mut Screen<'a>) -> Vec> { let current_timestamp = SystemTime::now(); let datetime: DateTime = current_timestamp.clone().into(); let mut next_arrivals: Vec> = gtfs.get_next_arrivals_for(&datetime); @@ -32,17 +32,22 @@ fn refresh_schedule<'a>(gtfs: &'a Gtfs, screen: &'a Screen<'a>) -> Vec>::from(next_arrivals.iter().map(|arrival| { - DisplayEntry { - destination: &String::from("Foo"), - route: &arrival.route.short_name.or(arrival.route.long_name).unwrap(), - due_in: (arrival.departure_time - current_time).num_minutes().try_into().unwrap() - } - }).collect()), + let mut display_data: DisplayData = DisplayData { + lines: Vec::::new(), status: None }; + display_data.lines.extend(next_arrivals.iter().map(|arrival| -> DisplayEntry { + DisplayEntry { + destination: arrival.stop_time.stop_headsign.clone() + .or(arrival.trip.trip_headsign.clone() + .or(Option::Some(String::from("Unknown") + ))).unwrap(), + route: arrival.route.short_name.clone().or(arrival.route.long_name.clone()).unwrap(), + due_in: (arrival.departure_time - current_time).num_minutes().try_into().unwrap() + } + })); + screen.update_information(&display_data); return next_arrivals; } @@ -87,7 +92,7 @@ fn main() { // Init screen info!("Initializing screen..."); - let screen = Screen::init(&screen_prefs); + let mut screen = Screen::init(&screen_prefs); info!("Startup done."); // Register our custom event and obtain the event-related objects to interact with the event loop @@ -110,6 +115,8 @@ fn main() { }; }).unwrap(); + // Do an initial refresh + let _ = refresh_schedule(>fs, &mut screen); // Main event loop loop { @@ -127,7 +134,7 @@ fn main() { let refresh_data = event.as_user_event_type::(); if refresh_data.is_some() { debug!("Received user event: {:#?}", refresh_data.unwrap()); - let _data: Vec> = refresh_schedule(>fs, &screen); + let _data: Vec> = refresh_schedule(>fs, &mut screen); debug!("-------------------------------- Refresh done."); } } diff --git a/src/renderer/mod.rs b/src/renderer/mod.rs index a28bec0..8d1f15a 100644 --- a/src/renderer/mod.rs +++ b/src/renderer/mod.rs @@ -20,7 +20,7 @@ const TEXT_SIZE: u32 = 160; // Size of the font in pixels const XOFFSET_ROUTE: u32 = 24; const XOFFSET_DESTINATION: u32 = 300; const XOFFSEET_TIME_LEFT: u32 = 1606; -const INTER_LINE_SPACE: i32 = -15; +const INTER_LINE_OVERLAP: u32 = 15; impl Screen<'_> { @@ -46,12 +46,14 @@ impl Screen<'_> { let due_in_mins = (entry.due_in / 60) as i32; let arrival_color: Color = self.color_for(due_in_mins); - self.do_print_at(line, entry.route, XOFFSET_ROUTE); - self.do_print_at(line, entry.destination, XOFFSET_DESTINATION); + self.color = COLOR_LCD_AMBER; + self.do_print_at(line, &entry.route, XOFFSET_ROUTE); + self.do_print_at(line, &entry.destination, XOFFSET_DESTINATION); + self.color = arrival_color; self.do_print_at(line, &due_in_mins.to_string(), XOFFSEET_TIME_LEFT); }; - if display_data.status.is_none() { + if display_data.status.is_some() { self.do_print_at(5, display_data.status.as_ref().unwrap(), 0); } self.do_update(); @@ -65,12 +67,12 @@ impl Screen<'_> { fn do_print_at(&mut self, line: u32, text: &str, left: u32) -> u32 { - let rendered_text = self.font.render(text).solid(Color::RED).unwrap(); + let rendered_text = self.font.render(text).solid(self.color).unwrap(); let texture_creator = self.canvas.texture_creator(); let texture = rendered_text.as_texture(&texture_creator).unwrap(); - self.canvas.copy(&texture, + let _= self.canvas.copy(&texture, Rect::new(0, 0, rendered_text.width(), rendered_text.height()), - Rect::new(left.try_into().unwrap(), (line * rendered_text.height()).try_into().unwrap(), rendered_text.width(), rendered_text.height())); + Rect::new(left.try_into().unwrap(), (line * (rendered_text.height() - INTER_LINE_OVERLAP)).try_into().unwrap(), rendered_text.width(), rendered_text.height())); return left + rendered_text.width(); } @@ -112,6 +114,7 @@ impl Screen<'_> { let mut screen: Screen = Screen { canvas: Box::new(window.into_canvas()), font: Box::new(font), + color: COLOR_LCD_AMBER, context: Box::new(sdl_context), }; diff --git a/src/renderer/structs.rs b/src/renderer/structs.rs index e4be284..d15ebd8 100644 --- a/src/renderer/structs.rs +++ b/src/renderer/structs.rs @@ -1,9 +1,10 @@ -use sdl3::{Sdl, render::Canvas, ttf::Font, video::Window}; +use sdl3::{Sdl, pixels::Color, render::Canvas, ttf::Font, video::Window}; pub struct Screen<'a> { pub(crate) canvas: Box>, pub(crate) font: Box>, + pub(crate) color: Color, pub(crate) context: Box } @@ -14,13 +15,13 @@ pub struct Prefs { } -pub struct DisplayEntry<'a> { - pub route: &'a String, - pub destination: &'a String, +pub struct DisplayEntry { + pub route: String, + pub destination: String, pub due_in: i32, } -pub struct DisplayData<'a> { - pub lines: Vec>, +pub struct DisplayData { + pub lines: Vec, pub status: Option }