bytes: FromBytes trait and round trip tests
This commit is contained in:
parent
ecea30cadb
commit
17d70f7d67
@ -21,6 +21,7 @@ where
|
|||||||
let bytes = self.as_bytes();
|
let bytes = self.as_bytes();
|
||||||
buffer[0..self.byte_len()].copy_from_slice(bytes)
|
buffer[0..self.byte_len()].copy_from_slice(bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn byte_len(&self) -> usize {
|
fn byte_len(&self) -> usize {
|
||||||
std::mem::size_of::<Self>()
|
std::mem::size_of::<Self>()
|
||||||
}
|
}
|
||||||
@ -30,6 +31,23 @@ pub trait AsBytes {
|
|||||||
fn as_bytes(&self) -> &[u8];
|
fn as_bytes(&self) -> &[u8];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait FromBytes {
|
||||||
|
fn from_bytes(bytes: &[u8]) -> Self;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> FromBytes for T
|
||||||
|
where
|
||||||
|
T: Byteable + Clone,
|
||||||
|
{
|
||||||
|
fn from_bytes(bytes: &[u8]) -> Self {
|
||||||
|
unsafe {
|
||||||
|
let byte_ptr = bytes.as_ptr();
|
||||||
|
let ptr = byte_ptr as *const Self;
|
||||||
|
(*ptr).clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T> AsBytes for T
|
impl<T> AsBytes for T
|
||||||
where
|
where
|
||||||
T: Byteable,
|
T: Byteable,
|
||||||
@ -84,6 +102,13 @@ impl Bytes for Vec2 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl FromBytes for Vec2 {
|
||||||
|
fn from_bytes(bytes: &[u8]) -> Self {
|
||||||
|
let array = <[f32; 2]>::from_bytes(bytes);
|
||||||
|
Vec2::from(array)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Bytes for Vec3 {
|
impl Bytes for Vec3 {
|
||||||
fn write_bytes(&self, buffer: &mut [u8]) {
|
fn write_bytes(&self, buffer: &mut [u8]) {
|
||||||
let array: [f32; 3] = (*self).into();
|
let array: [f32; 3] = (*self).into();
|
||||||
@ -95,6 +120,13 @@ impl Bytes for Vec3 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl FromBytes for Vec3 {
|
||||||
|
fn from_bytes(bytes: &[u8]) -> Self {
|
||||||
|
let array = <[f32; 3]>::from_bytes(bytes);
|
||||||
|
Vec3::from(array)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Bytes for Vec4 {
|
impl Bytes for Vec4 {
|
||||||
fn write_bytes(&self, buffer: &mut [u8]) {
|
fn write_bytes(&self, buffer: &mut [u8]) {
|
||||||
let array: [f32; 4] = (*self).into();
|
let array: [f32; 4] = (*self).into();
|
||||||
@ -105,6 +137,13 @@ impl Bytes for Vec4 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl FromBytes for Vec4 {
|
||||||
|
fn from_bytes(bytes: &[u8]) -> Self {
|
||||||
|
let array = <[f32; 4]>::from_bytes(bytes);
|
||||||
|
Vec4::from(array)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Bytes for Mat4 {
|
impl Bytes for Mat4 {
|
||||||
fn write_bytes(&self, buffer: &mut [u8]) {
|
fn write_bytes(&self, buffer: &mut [u8]) {
|
||||||
let array = self.to_cols_array();
|
let array = self.to_cols_array();
|
||||||
@ -115,6 +154,13 @@ impl Bytes for Mat4 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl FromBytes for Mat4 {
|
||||||
|
fn from_bytes(bytes: &[u8]) -> Self {
|
||||||
|
let array = <[f32; 16]>::from_bytes(bytes);
|
||||||
|
Mat4::from_cols_array(&array)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T> Bytes for Option<T>
|
impl<T> Bytes for Option<T>
|
||||||
where
|
where
|
||||||
T: Bytes,
|
T: Bytes,
|
||||||
@ -129,6 +175,19 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T> FromBytes for Option<T>
|
||||||
|
where
|
||||||
|
T: FromBytes,
|
||||||
|
{
|
||||||
|
fn from_bytes(bytes: &[u8]) -> Self {
|
||||||
|
if bytes.len() == 0 {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(T::from_bytes(bytes))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T> Bytes for Vec<T>
|
impl<T> Bytes for Vec<T>
|
||||||
where
|
where
|
||||||
T: Sized + Byteable,
|
T: Sized + Byteable,
|
||||||
@ -141,3 +200,72 @@ where
|
|||||||
self.as_slice().as_bytes().len()
|
self.as_slice().as_bytes().len()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T> FromBytes for Vec<T>
|
||||||
|
where
|
||||||
|
T: Sized + Clone + Byteable,
|
||||||
|
{
|
||||||
|
fn from_bytes(bytes: &[u8]) -> Self {
|
||||||
|
unsafe {
|
||||||
|
let byte_ptr = bytes.as_ptr() as *const T;
|
||||||
|
let len = bytes.len() / std::mem::size_of::<T>();
|
||||||
|
let slice = core::slice::from_raw_parts::<T>(byte_ptr, len);
|
||||||
|
slice.to_vec()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
|
||||||
|
use super::{FromBytes, Bytes};
|
||||||
|
use glam::{Vec3, Vec2, Vec4, Mat4};
|
||||||
|
|
||||||
|
fn test_round_trip<T: Bytes + FromBytes + std::fmt::Debug + PartialEq>(value: T) {
|
||||||
|
let mut bytes = vec![0; value.byte_len()];
|
||||||
|
value.write_bytes(&mut bytes);
|
||||||
|
let result = T::from_bytes(&bytes);
|
||||||
|
assert_eq!(value, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_u32_bytes_round_trip() {
|
||||||
|
test_round_trip(123u32);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_f64_bytes_round_trip() {
|
||||||
|
test_round_trip(123f64);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_vec_bytes_round_trip() {
|
||||||
|
test_round_trip(vec![1u32, 2u32, 3u32]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_option_bytes_round_trip() {
|
||||||
|
test_round_trip(Some(123u32));
|
||||||
|
test_round_trip(Option::<u32>::None);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_vec2_round_trip() {
|
||||||
|
test_round_trip(Vec2::new(1.0, 2.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_vec3_round_trip() {
|
||||||
|
test_round_trip(Vec3::new(1.0, 2.0, 3.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_vec4_round_trip() {
|
||||||
|
test_round_trip(Vec4::new(1.0, 2.0, 3.0, 4.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_mat4_round_trip() {
|
||||||
|
test_round_trip(Mat4::identity());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -9,7 +9,6 @@ pub fn derive_render_resource(input: TokenStream) -> TokenStream {
|
|||||||
|
|
||||||
let bevy_render_path: Path = get_path(&modules.bevy_render);
|
let bevy_render_path: Path = get_path(&modules.bevy_render);
|
||||||
let bevy_asset_path: Path = get_path(&modules.bevy_asset);
|
let bevy_asset_path: Path = get_path(&modules.bevy_asset);
|
||||||
let bevy_core_path: Path = get_path(&modules.bevy_core);
|
|
||||||
let struct_name = &ast.ident;
|
let struct_name = &ast.ident;
|
||||||
|
|
||||||
TokenStream::from(quote! {
|
TokenStream::from(quote! {
|
||||||
@ -18,7 +17,6 @@ pub fn derive_render_resource(input: TokenStream) -> TokenStream {
|
|||||||
Some(#bevy_render_path::render_resource::RenderResourceType::Buffer)
|
Some(#bevy_render_path::render_resource::RenderResourceType::Buffer)
|
||||||
}
|
}
|
||||||
fn write_buffer_bytes(&self, buffer: &mut [u8]) {
|
fn write_buffer_bytes(&self, buffer: &mut [u8]) {
|
||||||
use #bevy_core_path::bytes::Bytes;
|
|
||||||
self.write_bytes(buffer);
|
self.write_bytes(buffer);
|
||||||
}
|
}
|
||||||
fn buffer_byte_len(&self) -> Option<usize> {
|
fn buffer_byte_len(&self) -> Option<usize> {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user