diff --git a/src/additional_rfactor.rs b/src/additional_rfactor.rs index 84cb9d1..2d5caa4 100644 --- a/src/additional_rfactor.rs +++ b/src/additional_rfactor.rs @@ -13,11 +13,35 @@ pub const MAX_MAPPED_VEHICLES: usize = 128; pub const MAX_MAPPED_IDS: usize = 512; #[repr(C, packed(4))] -#[derive(Debug, Copy, Clone)] -pub struct rF2Telemetry { +#[derive(Debug, Copy, Clone, Default)] +pub struct VersionHeader { pub version_update_begin: u32, pub version_update_end: u32, pub bytes_update_hint: i32, +} + +impl VersionHeader { + pub const SIZE: usize = mem::size_of::(); + + pub fn check_for_update(&self, other: &Self) -> bool { + self.version_update_begin != other.version_update_begin + || self.version_update_end != other.version_update_end + } +} + +impl From<&[u8]> for VersionHeader { + fn from(value: &[u8]) -> Self { + debug_assert!(value.len() == Self::SIZE); + let fixed_size: [u8; Self::SIZE] = value.try_into().unwrap(); + + unsafe { mem::transmute(fixed_size) } + } +} + +#[repr(C, packed(4))] +#[derive(Debug, Copy, Clone)] +pub struct rF2Telemetry { + pub version_header: VersionHeader, pub num_vehicles: i32, pub vehicle_telemetry: [rF2VehicleTelemetry; MAX_MAPPED_VEHICLES], @@ -43,9 +67,7 @@ impl From<&[u8]> for rF2Telemetry { #[repr(C, packed(4))] #[derive(Debug, Copy, Clone)] pub struct rF2Scoring { - pub version_update_begin: u32, - pub version_update_end: u32, - pub bytes_update_hint: i32, + pub version_header: VersionHeader, pub scoring_info: ScoringInfoV01, pub vehicles: [VehicleScoringInfoV01; MAX_MAPPED_VEHICLES], diff --git a/src/lib.rs b/src/lib.rs index 87ca947..c115a74 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,7 +2,7 @@ pub mod additional_rfactor; #[allow(warnings)] mod rfactor_structs; -use std::{fs::File, marker::PhantomData, path::Path}; +use std::{cell::Cell, fs::File, marker::PhantomData, path::Path}; use additional_rfactor::*; pub use additional_rfactor::{rF2Vec3, rF2VehicleTelemetry, rF2Wheel}; @@ -16,6 +16,8 @@ struct ShMReader { _file: File, shm: Mmap, + version: Cell, + data: PhantomData, } @@ -30,17 +32,35 @@ impl ShMReader { _file: file, shm: mmap, + version: Cell::new(VersionHeader::default()), + data: PhantomData, }) } + + fn check_version_update(&self) -> bool { + let new_version = VersionHeader::from(&self.shm[0..VersionHeader::SIZE]); + + let are_different = self.version.get().check_for_update(&new_version); + + if are_different { + self.version.set(new_version); + } + + are_different + } } impl<'a, T> ShMReader where T: From<&'a [u8]>, { - fn read(&'a self) -> T { - T::from(&self.shm[0..Self::SIZE]) + fn read(&'a self) -> Option { + if self.check_version_update() { + Some(T::from(&self.shm[0..Self::SIZE])) + } else { + None + } } } @@ -55,8 +75,8 @@ impl TelemetryReader { }) } - pub fn query_telemetry(&self) -> Vec { - self.mm_reader.read().vehicles().to_vec() + pub fn query_telemetry(&self) -> Option> { + self.mm_reader.read().map(|v| v.vehicles().to_vec()) } } @@ -71,9 +91,9 @@ impl ScoringReader { }) } - pub fn vehicle_scoring(&self) -> (ScoringInfoV01, Vec) { - let scoring = self.mm_reader.read(); - - (scoring.scoring_info, scoring.vehicles().to_vec()) + pub fn vehicle_scoring(&self) -> Option<(ScoringInfoV01, Vec)> { + self.mm_reader + .read() + .map(|s| (s.scoring_info, s.vehicles().to_vec())) } }