rFactor2_vk_hud/src/overlay/rfactor_data.rs

159 lines
4.4 KiB
Rust
Raw Normal View History

2023-01-12 16:45:06 +00:00
use anyhow::Result;
use rfactor_sm_reader::*;
2023-01-17 11:18:53 +00:00
use std::{cell::RefCell, rc::Rc, time::Instant};
2023-01-16 16:07:39 +00:00
2023-01-15 05:58:23 +00:00
use crate::write_log;
2023-01-17 11:18:53 +00:00
use super::UiOverlay;
2023-01-14 19:15:43 +00:00
2023-01-17 11:18:53 +00:00
pub trait DataReceiver {
2023-01-18 16:02:20 +00:00
fn game_phase_change(&mut self, phase: GamePhase) -> Result<()>;
fn update_for_phase(&self, phase: GamePhase) -> bool;
2023-01-18 07:55:43 +00:00
fn scoring_update(
&mut self,
phase: GamePhase,
vehicle_scoring: &[VehicleScoringInfoV01],
) -> Result<()>;
2023-01-12 16:45:06 +00:00
2023-01-17 11:18:53 +00:00
fn telemetry_update(
&mut self,
player_id: Option<i32>,
telemetries: &[rF2VehicleTelemetry],
) -> Result<()>;
2023-01-16 16:07:39 +00:00
}
2023-01-18 16:02:20 +00:00
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
2023-01-18 07:55:43 +00:00
pub enum GamePhase {
TestDay,
Practice,
Qualifying,
Warmup,
Race,
2023-01-18 16:02:20 +00:00
None,
2023-01-18 07:55:43 +00:00
}
impl TryFrom<i32> for GamePhase {
type Error = anyhow::Error;
fn try_from(value: i32) -> Result<Self> {
Ok(match value {
0 => Self::TestDay,
1..=4 => Self::Practice,
5..=8 => Self::Qualifying,
9 => Self::Warmup,
10..=13 => Self::Race,
_ => return Err(anyhow::anyhow!("Failed to parse GamePhase from: {}", value)),
})
}
}
2023-01-12 16:45:06 +00:00
pub struct RFactorData {
// rf2 memory mapped data
2023-01-14 19:15:43 +00:00
telemetry_reader: TelemetryReader,
scoring_reader: ScoringReader,
2023-01-15 05:58:23 +00:00
start_time: Instant,
2023-01-17 11:18:53 +00:00
player_id: Option<i32>,
2023-01-18 16:02:20 +00:00
previous_game_phase: GamePhase,
2023-01-15 05:58:23 +00:00
2023-01-17 11:18:53 +00:00
receivers: Vec<Rc<RefCell<dyn UiOverlay>>>,
2023-01-12 16:45:06 +00:00
}
impl RFactorData {
2023-01-17 11:18:53 +00:00
pub fn new() -> Result<Self> {
2023-01-15 05:58:23 +00:00
write_log!(" =================== create RFactorData ===================");
let start_time = Instant::now();
Ok(Self {
2023-01-15 05:58:23 +00:00
telemetry_reader: TelemetryReader::new(start_time.elapsed().as_secs_f32())?,
scoring_reader: ScoringReader::new(start_time.elapsed().as_secs_f32())?,
2023-01-14 19:15:43 +00:00
2023-01-15 05:58:23 +00:00
start_time,
2023-01-17 11:18:53 +00:00
player_id: None,
2023-01-18 16:02:20 +00:00
previous_game_phase: GamePhase::None,
2023-01-15 05:58:23 +00:00
2023-01-17 11:18:53 +00:00
receivers: Vec::new(),
})
2023-01-12 16:45:06 +00:00
}
2023-01-17 11:18:53 +00:00
pub fn add_receiver(&mut self, receiver: Rc<RefCell<dyn UiOverlay>>) {
self.receivers.push(receiver);
}
2023-01-15 05:58:23 +00:00
fn now(&self) -> f32 {
self.start_time.elapsed().as_secs_f32()
}
2023-01-12 16:45:06 +00:00
pub fn update(&mut self) -> Result<()> {
2023-01-15 05:58:23 +00:00
write_log!(" =================== update RFactorData ===================");
2023-01-14 19:15:43 +00:00
// get scoring info
2023-01-15 05:58:23 +00:00
if let Some((scoring_info, vehicle_scorings)) =
self.scoring_reader.vehicle_scoring(self.now())
{
write_log!(format!(
"new scoring info: vehicles: {}",
scoring_info.mNumVehicles
));
// check for player id
if scoring_info.mNumVehicles == 0 {
self.player_id = None;
} else if self.player_id.is_none() {
for vehicle_scoring in vehicle_scorings.iter() {
if vehicle_scoring.mIsPlayer != 0 {
write_log!(format!("player found: {}", vehicle_scoring.mID));
self.player_id = Some(vehicle_scoring.mID);
break;
}
2023-01-14 19:15:43 +00:00
}
}
2023-01-16 21:29:23 +00:00
2023-01-18 16:02:20 +00:00
{
let phase = GamePhase::try_from(scoring_info.mSession)?;
if self.previous_game_phase != phase {
self.previous_game_phase = phase;
2023-01-18 07:55:43 +00:00
2023-01-18 16:02:20 +00:00
for receiver in self.receivers.iter() {
receiver
.borrow_mut()
.game_phase_change(self.previous_game_phase)?;
}
}
write_log!(format!("GamePhase: {:?}", self.previous_game_phase));
}
2023-01-18 10:51:16 +00:00
2023-01-17 11:18:53 +00:00
for receiver in self.receivers.iter() {
2023-01-18 16:02:20 +00:00
let mut rec_mut = receiver.borrow_mut();
if rec_mut.update_for_phase(self.previous_game_phase) {
rec_mut.scoring_update(self.previous_game_phase, &vehicle_scorings)?;
}
2023-01-16 21:29:23 +00:00
}
2023-01-14 19:15:43 +00:00
}
2023-01-17 11:18:53 +00:00
// check telemetry data
write_log!("before telemetry update");
if let Some(telemetries) = self.telemetry_reader.query_telemetry(self.now()) {
write_log!("new telemetry update");
2023-01-16 21:29:23 +00:00
2023-01-17 11:18:53 +00:00
for receiver in self.receivers.iter() {
2023-01-18 16:02:20 +00:00
let mut rec_mut = receiver.borrow_mut();
if rec_mut.update_for_phase(self.previous_game_phase) {
rec_mut.telemetry_update(self.player_id, &telemetries)?;
}
2023-01-14 19:15:43 +00:00
}
}
2023-01-12 16:45:06 +00:00
Ok(())
}
}