2023-01-12 16:45:06 +00:00
|
|
|
use anyhow::Result;
|
2023-01-13 07:11:53 +00:00
|
|
|
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-13 07:11:53 +00:00
|
|
|
|
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 {
|
2023-01-13 07:11:53 +00:00
|
|
|
// rf2 memory mapped data
|
2023-01-14 19:15:43 +00:00
|
|
|
telemetry_reader: TelemetryReader,
|
|
|
|
scoring_reader: ScoringReader,
|
2023-01-13 07:11:53 +00:00
|
|
|
|
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();
|
2023-01-13 07:11:53 +00:00
|
|
|
|
|
|
|
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-13 07:11:53 +00:00
|
|
|
})
|
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 09:46:22 +00:00
|
|
|
}
|
|
|
|
|
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(())
|
|
|
|
}
|
2023-01-16 06:32:32 +00:00
|
|
|
}
|