Leaderboard improvements

This commit is contained in:
hodasemi 2023-01-19 07:40:16 +01:00
parent eec17e1039
commit 3f914ffdeb
2 changed files with 81 additions and 23 deletions

View file

@ -1,6 +1,6 @@
<?xml-model href="../gui.xsd" type="application/xml" schematypens="http://www.w3.org/2001/XMLSchema"?>
<root>
<grid id="grid" x_dim="11" y_dim="1">
<grid x_dim="11" y_dim="1" padding="2" margin="2">
<label id="place" x_slot="0" y_slot="0" text_color="black" text_alignment="right"></label>
<label
id="name"

View file

@ -16,7 +16,7 @@ use crate::write_log;
pub struct LeaderBoard {
gui_handler: Arc<GuiHandler>,
gui: Arc<GuiBuilder>,
leaderboard: Arc<GuiBuilder>,
main_grid: Arc<Grid>,
entries: Vec<LeaderBoardEntry>,
@ -36,7 +36,7 @@ impl LeaderBoard {
Ok(Self {
gui_handler: gui_handler.clone(),
gui,
leaderboard: gui,
main_grid,
entries: Vec::new(),
@ -85,7 +85,15 @@ impl LeaderBoard {
vehicle_scoring.mID,
driver_name,
vehicle_scoring.mPlace,
vehicle_scoring.mTimeBehindLeader,
{
let laps_behind = vehicle_scoring.mLapsBehindLeader;
if laps_behind != 0 {
BehindLeader::Laps(laps_behind)
} else {
BehindLeader::Time(vehicle_scoring.mTimeBehindLeader)
}
},
vehicle_scoring.mTimeBehindNext,
vehicle_scoring.mBestLapTime,
)?;
@ -133,7 +141,13 @@ impl LeaderBoard {
fn race_leaderboard(&mut self, vehicle_scorings: &[VehicleScoringInfoV01]) -> Result<()> {
self.update_leaderboard(vehicle_scorings, |entry, scoring| {
entry.update_time_behind_leader(scoring.mTimeBehindLeader)
let laps_behind = scoring.mLapsBehindLeader;
if laps_behind != 0 {
entry.update_time_behind_leader(BehindLeader::Laps(laps_behind))
} else {
entry.update_time_behind_leader(BehindLeader::Time(scoring.mTimeBehindLeader))
}
})
}
@ -149,9 +163,25 @@ impl UiOverlay for LeaderBoard {}
impl DataReceiver for LeaderBoard {
fn game_phase_change(&mut self, phase: GamePhase) -> Result<()> {
match phase {
GamePhase::Practice | GamePhase::Qualifying | GamePhase::Race => self.gui.enable(),
_ => self.gui.disable(),
GamePhase::Practice | GamePhase::Qualifying => {
for entry in self.entries.iter_mut() {
entry.update_best_lap(-1.0)?;
}
self.leaderboard.enable()?
}
GamePhase::Race => {
for entry in self.entries.iter_mut() {
entry.update_time_behind_leader(BehindLeader::Time(0.0))?;
}
self.leaderboard.enable()?;
}
_ => self.leaderboard.disable()?,
}
Ok(())
}
fn update_for_phase(&self, phase: GamePhase) -> bool {
@ -198,18 +228,23 @@ impl DataReceiver for LeaderBoard {
}
}
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
enum BehindLeader {
Time(f64),
Laps(i32),
}
struct LeaderBoardEntry {
id: i32,
name: String,
place: u8,
time_behind_leader: f64,
behind: BehindLeader,
time_behind_next: f64,
best_lap: f64,
snippet: Arc<GuiSnippet>,
grid: Arc<Grid>,
name_label: Arc<Label>,
place_label: Arc<Label>,
time_label: Arc<Label>,
@ -223,13 +258,12 @@ impl LeaderBoardEntry {
id: i32,
name: String,
place: u8,
time_behind_leader: f64,
behind: BehindLeader,
time_behind_next: f64,
best_lap: f64,
) -> Result<Self> {
let snippet = GuiSnippet::from_str(gui_handler, LeaderBoard::ENTRY)?;
let background = snippet.element("grid")?;
let name_label: Arc<Label> = snippet.element("name")?;
let place_label: Arc<Label> = snippet.element("place")?;
let time_label: Arc<Label> = snippet.element("time")?;
@ -243,13 +277,12 @@ impl LeaderBoardEntry {
name,
place,
time_behind_leader,
behind,
time_behind_next,
best_lap,
snippet,
grid: background,
name_label,
place_label,
time_label,
@ -281,7 +314,11 @@ impl LeaderBoardEntry {
}
pub fn change_background_color(&self, color: Color) -> Result<()> {
self.grid.set_background(color)
self.name_label.set_background(color)?;
self.place_label.set_background(color)?;
self.time_label.set_background(color)?;
Ok(())
}
pub fn update_place(&mut self, place: u8) -> Result<()> {
@ -294,16 +331,37 @@ impl LeaderBoardEntry {
self.place_label.set_text(self.place)
}
pub fn update_time_behind_leader(&mut self, time: f64) -> Result<()> {
if self.time_behind_leader != time {
self.time_behind_leader = time;
pub fn update_time_behind_leader(&mut self, behind: BehindLeader) -> Result<()> {
if self.behind != behind {
self.behind = behind;
// check if we are leader
if self.time_behind_leader == 0.0 {
self.time_label.set_text("---")?;
} else {
self.time_label
.set_text(format!("+{:.3}", self.time_behind_leader))?;
match self.behind {
BehindLeader::Time(time_behind) => {
// check if we are leader
if time_behind == 0.0 {
self.time_label.set_text("---")?;
} else {
let text = if time_behind > 60.0 {
let full_minutes = (self.best_lap / 60.0).floor();
let remainder = self.best_lap - (full_minutes * 60.0);
format!("+{:.0}:{:.0}", full_minutes, remainder)
} else {
format!("+{:.3}", time_behind)
};
self.time_label.set_text(text)?;
}
}
BehindLeader::Laps(laps_behind) => {
let text = if laps_behind == 1 {
format!("+{} Lap", laps_behind)
} else {
format!("+{} Laps", laps_behind)
};
self.time_label.set_text(text)?;
}
}
}