use crate::ac_evo::structs::{
AC_STATUS_LIVE, SPageFileGraphicsEvo, SPageFilePhysicsEvo, SPageFileStaticEvo,
};
use crate::ac_evo::types::{AcGraphicsData, AcPhysicsData, AcStaticData};
use crate::error::SimError;
use crate::shm::SharedMemRegion;
const SHM_PHYSICS: &str = "Local\\acevo_pmf_physics";
const SHM_GRAPHICS: &str = "Local\\acevo_pmf_graphics";
const SHM_STATIC: &str = "Local\\acevo_pmf_static";
#[derive(Clone, Debug, serde::Serialize)]
pub struct AcEvoFrame {
pub physics: AcPhysicsData,
pub graphics: AcGraphicsData,
pub static_data: AcStaticData,
}
pub struct AcEvoConnection {
physics: SharedMemRegion,
graphics: SharedMemRegion,
static_data: SharedMemRegion,
}
impl AcEvoConnection {
pub(crate) fn connect() -> Result<Self, SimError> {
let physics = SharedMemRegion::open(SHM_PHYSICS).map_err(SimError::NotConnected)?;
let graphics = SharedMemRegion::open(SHM_GRAPHICS).map_err(SimError::NotConnected)?;
let static_data = SharedMemRegion::open(SHM_STATIC).map_err(SimError::NotConnected)?;
Ok(Self {
physics,
graphics,
static_data,
})
}
pub fn frame(&self) -> Result<AcEvoFrame, SimError> {
unsafe {
let raw_p =
std::ptr::read_unaligned(self.physics.as_ptr() as *const SPageFilePhysicsEvo);
let raw_g =
std::ptr::read_unaligned(self.graphics.as_ptr() as *const SPageFileGraphicsEvo);
let raw_s =
std::ptr::read_unaligned(self.static_data.as_ptr() as *const SPageFileStaticEvo);
Ok(AcEvoFrame {
physics: AcPhysicsData::from(raw_p),
graphics: AcGraphicsData::from(raw_g),
static_data: AcStaticData::from(raw_s),
})
}
}
pub fn telemetry_snapshot(
&self,
) -> std::collections::HashMap<String, crate::types::TelemetryValue> {
match self.frame() {
Ok(frame) => crate::ac_evo::snapshot::build_snapshot(&frame),
Err(_) => std::collections::HashMap::new(),
}
}
pub fn graphics_shm_len(&self) -> (usize, usize) {
(
self.graphics.len(),
std::mem::size_of::<SPageFileGraphicsEvo>(),
)
}
pub fn is_connected(&self) -> bool {
unsafe {
let offset = std::mem::offset_of!(SPageFileGraphicsEvo, status);
let status = std::ptr::read_unaligned(self.graphics.as_ptr().add(offset) as *const i32);
status == AC_STATUS_LIVE
}
}
pub fn wait_for_data(&self, timeout_ms: u32) {
std::thread::sleep(std::time::Duration::from_millis(timeout_ms as u64));
}
}