diff --git a/crates/bevy_core/src/bytes.rs b/crates/bevy_core/src/bytes.rs index 91e80788d1..cf6f43a55b 100644 --- a/crates/bevy_core/src/bytes.rs +++ b/crates/bevy_core/src/bytes.rs @@ -21,6 +21,7 @@ where let bytes = self.as_bytes(); buffer[0..self.byte_len()].copy_from_slice(bytes) } + fn byte_len(&self) -> usize { std::mem::size_of::() } @@ -30,6 +31,23 @@ pub trait AsBytes { fn as_bytes(&self) -> &[u8]; } +pub trait FromBytes { + fn from_bytes(bytes: &[u8]) -> Self; +} + +impl 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 AsBytes for T where 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 { fn write_bytes(&self, buffer: &mut [u8]) { 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 { fn write_bytes(&self, buffer: &mut [u8]) { 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 { fn write_bytes(&self, buffer: &mut [u8]) { 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 Bytes for Option where T: Bytes, @@ -129,6 +175,19 @@ where } } +impl FromBytes for Option +where + T: FromBytes, +{ + fn from_bytes(bytes: &[u8]) -> Self { + if bytes.len() == 0 { + None + } else { + Some(T::from_bytes(bytes)) + } + } +} + impl Bytes for Vec where T: Sized + Byteable, @@ -141,3 +200,72 @@ where self.as_slice().as_bytes().len() } } + +impl FromBytes for Vec +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::(); + let slice = core::slice::from_raw_parts::(byte_ptr, len); + slice.to_vec() + } + } +} + +#[cfg(test)] +mod tests { + + use super::{FromBytes, Bytes}; + use glam::{Vec3, Vec2, Vec4, Mat4}; + + fn test_round_trip(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::::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()); + } +} diff --git a/crates/bevy_derive/src/render_resource.rs b/crates/bevy_derive/src/render_resource.rs index e0943c9cf0..6141c6a223 100644 --- a/crates/bevy_derive/src/render_resource.rs +++ b/crates/bevy_derive/src/render_resource.rs @@ -9,7 +9,6 @@ pub fn derive_render_resource(input: TokenStream) -> TokenStream { let bevy_render_path: Path = get_path(&modules.bevy_render); 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; TokenStream::from(quote! { @@ -18,7 +17,6 @@ pub fn derive_render_resource(input: TokenStream) -> TokenStream { Some(#bevy_render_path::render_resource::RenderResourceType::Buffer) } fn write_buffer_bytes(&self, buffer: &mut [u8]) { - use #bevy_core_path::bytes::Bytes; self.write_bytes(buffer); } fn buffer_byte_len(&self) -> Option {