use std::time::Duration;
use bytes::Buf;
use glam::{IVec3, Vec3};
use insim_core::{Decode, Encode};
use crate::OutsimId;
#[derive(Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
pub struct OutsimPack {
pub time: Duration,
pub angvel: Vec3,
pub heading: f32,
pub pitch: f32,
pub roll: f32,
pub accel: Vec3,
pub vel: Vec3,
pub pos: IVec3,
pub id: Option<OutsimId>,
}
impl Encode for OutsimPack {
fn encode(&self, buf: &mut bytes::BytesMut) -> Result<(), insim_core::EncodeError> {
let time = self.time.as_millis();
(time as u32).encode(buf)?;
self.angvel.encode(buf)?;
self.heading.encode(buf)?;
self.pitch.encode(buf)?;
self.roll.encode(buf)?;
self.accel.encode(buf)?;
self.vel.encode(buf)?;
self.pos.encode(buf)?;
if let Some(id) = self.id {
id.encode(buf)?;
}
Ok(())
}
}
impl Decode for OutsimPack {
fn decode(buf: &mut bytes::Bytes) -> Result<Self, insim_core::DecodeError> {
let time = Duration::from_millis(u32::decode(buf)? as u64);
let angvel = Vec3::decode(buf)?;
let heading = f32::decode(buf)?;
let pitch = f32::decode(buf)?;
let roll = f32::decode(buf)?;
let accel = Vec3::decode(buf)?;
let vel = Vec3::decode(buf)?;
let pos = IVec3::decode(buf)?;
let id = if buf.has_remaining() {
Some(OutsimId::decode(buf)?)
} else {
None
};
Ok(Self {
time,
angvel,
heading,
pitch,
roll,
accel,
vel,
pos,
id,
})
}
}
#[cfg(test)]
mod test {
use bytes::{BufMut, BytesMut};
use super::*;
const RAW: [u8; 64] = [
240, 50, 0, 0, 155, 155, 12, 60, 180, 252, 109, 188, 149, 60, 47, 60, 23, 119, 134, 62, 9, 32, 225, 60, 84, 42, 63, 186, 118, 69, 154, 191, 150, 84, 136, 64, 148, 155, 51, 62, 64, 200, 128, 192, 21, 143, 111, 65, 106, 9, 193, 187, 35, 134, 62, 253, 166, 226, 163, 248, 42, 26, 2, 0, ];
#[test]
fn test_outsim_without_id() {
let mut input = BytesMut::new();
input.extend_from_slice(&RAW);
let mut buf = input.clone().freeze();
let outsim = OutsimPack::decode(&mut buf).unwrap();
assert_eq!(buf.remaining(), 0);
let mut output = BytesMut::new();
outsim.encode(&mut output).unwrap();
assert_eq!(
output.as_ref(),
input.as_ref(),
"assert reads and writes. left=actual, right=expected"
);
}
#[test]
fn test_outsim_with_id() {
let mut input = BytesMut::new();
input.extend_from_slice(&RAW);
input.put_i32_le(10);
let mut buf = input.clone().freeze();
let outsim = OutsimPack::decode(&mut buf).unwrap();
assert_eq!(buf.remaining(), 0);
assert!(matches!(outsim.id, Some(OutsimId(10))));
let mut output = BytesMut::new();
outsim.encode(&mut output).unwrap();
assert_eq!(
output.as_ref(),
input.as_ref(),
"assert reads and writes. left=actual, right=expected"
);
}
}