simetry 0.2.3

Interface with telemetry of various racing and driving sims
Documentation
use crate::assetto_corsa::util;
pub use crate::assetto_corsa_competizione::data::{
    Aids, CarDamage, FlagType, GlobalFlags, Graphics, LapTiming, MfdPitstop, Penalty, Physics,
    RainIntensity, SessionType, StaticData, Status, Time, TrackGripStatus, Vector3, WheelInfo,
    Wheels,
};
use crate::assetto_corsa_competizione::shared_memory_data::{
    PageFileGraphics, PageFilePhysics, PageFileStatic,
};
use crate::{Moment, RacingFlags, Simetry};
use std::borrow::Cow;
use uom::si::angular_velocity::revolution_per_minute;
use uom::si::f64::{AngularVelocity, Velocity};
use uom::si::velocity::kilometer_per_hour;

mod conversions;
mod data;
mod shared_memory_data;

#[derive(Clone, Debug, Default)]
pub struct AssettoCorsaCompetizioneApiVersion;

impl util::AcApiVersion for AssettoCorsaCompetizioneApiVersion {
    const MAJOR_MIN: u16 = 1;
    const MAJOR_MAX: u16 = 1;
    const MINOR_MIN: u16 = 8;
    const MINOR_MAX: u16 = u16::MAX;
    type PageStatic = PageFileStatic;
    type DataStatic = StaticData;
    type PagePhysics = PageFilePhysics;
    type DataPhysics = Physics;
    type PageGraphics = PageFileGraphics;
    type DataGraphics = Graphics;
}

impl util::WithPacketId for PageFilePhysics {
    fn packet_id(&self) -> i32 {
        self.packet_id
    }
}

impl util::WithPacketId for Physics {
    fn packet_id(&self) -> i32 {
        self.packet_id
    }
}

impl util::WithPacketId for PageFileGraphics {
    fn packet_id(&self) -> i32 {
        self.packet_id
    }
}

impl util::WithPacketId for Graphics {
    fn packet_id(&self) -> i32 {
        self.packet_id
    }
}

pub type Client = util::SharedMemoryClient<AssettoCorsaCompetizioneApiVersion>;
pub type SimState = util::SimState<AssettoCorsaCompetizioneApiVersion>;

#[async_trait::async_trait]
impl Simetry for Client {
    fn name(&self) -> &str {
        "AssettoCorsaCompetizione"
    }

    async fn next_moment(&mut self) -> Option<Box<dyn Moment + Send + Sync + 'static>> {
        Some(Box::new(self.next_sim_state().await?))
    }
}

impl Moment for SimState {
    fn vehicle_gear(&self) -> Option<i8> {
        Some((self.physics.gear - 1) as i8)
    }

    fn vehicle_velocity(&self) -> Option<Velocity> {
        Some(Velocity::new::<kilometer_per_hour>(
            self.physics.speed_kmh as f64,
        ))
    }

    fn vehicle_engine_rotation_speed(&self) -> Option<AngularVelocity> {
        Some(AngularVelocity::new::<revolution_per_minute>(
            self.physics.rpm as f64,
        ))
    }

    fn vehicle_max_engine_rotation_speed(&self) -> Option<AngularVelocity> {
        Some(AngularVelocity::new::<revolution_per_minute>(
            self.static_data.max_rpm as f64,
        ))
    }

    fn is_pit_limiter_engaged(&self) -> Option<bool> {
        Some(self.physics.pit_limiter_on)
    }

    fn is_vehicle_in_pit_lane(&self) -> Option<bool> {
        Some(self.graphics.is_in_pit_lane)
    }

    fn flags(&self) -> Option<RacingFlags> {
        let mut flags = RacingFlags::default();
        match self.graphics.flag {
            FlagType::None => {}
            FlagType::Blue => flags.blue = true,
            FlagType::Yellow => flags.yellow = true,
            FlagType::Black => flags.black = true,
            FlagType::White => flags.white = true,
            FlagType::Checkered => flags.checkered = true,
            FlagType::Penalty => flags.black = true,
            FlagType::Green => flags.green = true,
            FlagType::Orange => flags.meatball = true,
        }
        Some(flags)
    }

    fn vehicle_unique_id(&self) -> Option<Cow<str>> {
        Some(self.static_data.car_model.as_str().into())
    }

    fn is_left_turn_indicator_on(&self) -> Option<bool> {
        Some(self.graphics.direction_lights_left)
    }

    fn is_right_turn_indicator_on(&self) -> Option<bool> {
        Some(self.graphics.direction_lights_right)
    }

    fn is_ignition_on(&self) -> Option<bool> {
        Some(self.physics.ignition_on)
    }

    fn is_starter_on(&self) -> Option<bool> {
        Some(self.physics.starter_engine_on)
    }
}