use nalgebra::{Scalar, Vector3, Matrix3};
pub trait PackInt {
fn size() -> usize;
fn pack_int_to(&self, buffer: &mut [i32]);
}
pub trait PackFloat {
fn size() -> usize;
fn pack_float_to(&self, buffer: &mut [f32]);
}
pub trait Pack {
fn size_int() -> usize;
fn size_float() -> usize;
fn pack_to(&self, buffer_int: &mut [i32], buffer_float: &mut [f32]);
}
pub trait PackerInt {
fn pack<T: PackInt>(self, t: &T) -> Self;
}
impl<'a> PackerInt for &'a mut [i32] {
fn pack<T: PackInt>(self, t: &T) -> Self {
t.pack_int_to(self);
&mut self[T::size()..]
}
}
pub trait PackerFloat {
fn pack<T: PackFloat>(self, t: &T) -> Self;
}
impl<'a> PackerFloat for &'a mut [f32] {
fn pack<T: PackFloat>(self, t: &T) -> Self {
t.pack_float_to(self);
&mut self[T::size()..]
}
}
pub struct Packer<'a> {
buffer_int: &'a mut [i32],
buffer_float: &'a mut [f32],
}
impl<'a> Packer<'a> {
pub fn new(buffer_int: &'a mut [i32], buffer_float: &'a mut [f32]) -> Self {
Self { buffer_int, buffer_float }
}
pub fn pack<T: Pack>(self, t: &T) -> Self {
t.pack_to(self.buffer_int, self.buffer_float);
Self {
buffer_int: &mut self.buffer_int[T::size_int()..],
buffer_float: &mut self.buffer_float[T::size_float()..],
}
}
}
impl PackInt for i32 {
fn size() -> usize { 1 }
fn pack_int_to(&self, buffer: &mut [i32]) {
buffer[0] = *self;
}
}
impl Pack for i32 {
fn size_int() -> usize { 1 }
fn size_float() -> usize { 0 }
fn pack_to(&self, buffer_int: &mut [i32], _buffer_float: &mut [f32]) {
buffer_int[0] = *self;
}
}
impl PackInt for u32 {
fn size() -> usize { 1 }
fn pack_int_to(&self, buffer: &mut [i32]) {
buffer[0] = *self as i32;
}
}
impl Pack for u32 {
fn size_int() -> usize { 1 }
fn size_float() -> usize { 0 }
fn pack_to(&self, buffer_int: &mut [i32], _buffer_float: &mut [f32]) {
buffer_int[0] = *self as i32;
}
}
impl PackFloat for f32 {
fn size() -> usize { 1 }
fn pack_float_to(&self, buffer: &mut [f32]) {
buffer[0] = *self;
}
}
impl Pack for f32 {
fn size_int() -> usize { 0 }
fn size_float() -> usize { 1 }
fn pack_to(&self, _buffer_int: &mut [i32], buffer_float: &mut [f32]) {
buffer_float[0] = *self;
}
}
impl PackFloat for f64 {
fn size() -> usize { 1 }
fn pack_float_to(&self, buffer: &mut [f32]) {
buffer[0] = *self as f32;
}
}
impl Pack for f64 {
fn size_int() -> usize { 0 }
fn size_float() -> usize { 1 }
fn pack_to(&self, _buffer_int: &mut [i32], buffer_float: &mut [f32]) {
buffer_float[0] = *self as f32;
}
}
impl<T: PackFloat + Scalar> PackFloat for Vector3<T> {
fn size() -> usize { 3*T::size() }
fn pack_float_to(&self, mut buffer: &mut [f32]) {
for x in self.as_slice() {
buffer = buffer.pack(x);
}
}
}
impl<T: Pack + Scalar> Pack for Vector3<T> {
fn size_int() -> usize { 3*T::size_int() }
fn size_float() -> usize { 3*T::size_float() }
fn pack_to(&self, buffer_int: &mut [i32], buffer_float: &mut [f32]) {
let mut packer = Packer::new(buffer_int, buffer_float);
for x in self.as_slice() {
packer = packer.pack(x);
}
}
}
impl<T: PackFloat + Scalar> PackFloat for Matrix3<T> {
fn size() -> usize { 9*T::size() }
fn pack_float_to(&self, mut buffer: &mut [f32]) {
for x in self.as_slice() {
buffer = buffer.pack(x);
}
}
}
impl<T: Pack + Scalar> Pack for Matrix3<T> {
fn size_int() -> usize { 9*T::size_int() }
fn size_float() -> usize { 9*T::size_float() }
fn pack_to(&self, buffer_int: &mut [i32], buffer_float: &mut [f32]) {
let mut packer = Packer::new(buffer_int, buffer_float);
for x in self.as_slice() {
packer = packer.pack(x);
}
}
}