From c0bec92736ee54091735cb0fdb2d99a2e5eb087c Mon Sep 17 00:00:00 2001 From: kaphula Date: Sat, 19 Oct 2024 00:42:06 +0300 Subject: [PATCH] Switch serialization to bincode. Apply PR fix suggestions. --- .gitignore | 1 - Cargo.toml | 2 +- examples/serialize_to_disk.rs | 204 ++++++++++++++++------------------ 3 files changed, 96 insertions(+), 111 deletions(-) diff --git a/.gitignore b/.gitignore index d889fbf5..69369904 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ /target **/*.rs.bk Cargo.lock -.idea diff --git a/Cargo.toml b/Cargo.toml index cc8c347a..43efa383 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -41,7 +41,7 @@ rand = "0.8.3" trybuild = "1.0.23" serde = { version = "1.0.117", features = ["derive"] } serde_test = "1.0.117" -serde_json = "1.0.117" +bincode = "1.3.3" [[bench]] name = "bench" diff --git a/examples/serialize_to_disk.rs b/examples/serialize_to_disk.rs index 1487b8a5..d3e7eaf4 100644 --- a/examples/serialize_to_disk.rs +++ b/examples/serialize_to_disk.rs @@ -9,131 +9,116 @@ //! Run this example from crate root with: //! `cargo run --example serialize_to_disk --features "column-serialize"` -#[cfg(feature = "column-serialize")] -mod serialize_to_disk_example { - pub use hecs::serialize::column::{ - deserialize_column, try_serialize, try_serialize_id, DeserializeContext, SerializeContext, - }; - pub use hecs::{Archetype, ColumnBatchBuilder, ColumnBatchType, World}; - pub use serde::{Deserialize, Serialize}; - use std::any::TypeId; - pub use std::fs::File; - pub use std::io::{BufReader, Write}; - pub use std::path::Path; +use hecs::serialize::column::{ + deserialize_column, try_serialize, try_serialize_id, DeserializeContext, SerializeContext, +}; +use hecs::{Archetype, ColumnBatchBuilder, ColumnBatchType, World}; +use serde::{Deserialize, Serialize, Serializer}; +use std::any::TypeId; +use std::fs::File; +use std::io::{BufReader, Write}; +use std::path::Path; - // Identifiers for the components we want to include in the serialization process: - #[derive(Serialize, Deserialize)] - enum ComponentId { - TestComponent1, - TestComponent2, - } +// Identifiers for the components we want to include in the serialization process: +#[derive(Serialize, Deserialize)] +enum ComponentId { + ComponentA, + ComponentB, +} - // We need to implement a context type for the hecs serialization process: - #[derive(Default)] - pub struct SaveContext { - pub components: Vec, - } +// We need to implement a context type for the hecs serialization process: +#[derive(Default)] +pub struct SaveContext { + pub components: Vec, +} - // Components of our world. - // Only Serialize and Deserialize derives are necessary. - #[derive(Serialize, Deserialize, Eq, PartialEq, Debug, Clone)] - pub struct ComponentA { - pub data: usize, - } +// Components of our world. +// Only Serialize and Deserialize derives are necessary. +#[derive(Serialize, Deserialize, Eq, PartialEq, Debug, Clone)] +pub struct ComponentA { + pub data: usize, +} - #[derive(Serialize, Deserialize, Eq, PartialEq, Debug, Clone)] - pub struct ComponentB { - pub some_other_data: String, - } +#[derive(Serialize, Deserialize, Eq, PartialEq, Debug, Clone)] +pub struct ComponentB { + pub some_other_data: String, +} - #[cfg(feature = "column-serialize")] - impl DeserializeContext for SaveContext { - fn deserialize_component_ids<'de, A>( - &mut self, - mut seq: A, - ) -> Result - where - A: serde::de::SeqAccess<'de>, - { - self.components.clear(); // Discard data from the previous archetype - let mut batch = ColumnBatchType::new(); - while let Some(id) = seq.next_element()? { - match id { - ComponentId::TestComponent1 => { - batch.add::(); - } - ComponentId::TestComponent2 => { - batch.add::(); - } +#[cfg(feature = "column-serialize")] +impl DeserializeContext for SaveContext { + fn deserialize_component_ids<'de, A>(&mut self, mut seq: A) -> Result + where + A: serde::de::SeqAccess<'de>, + { + self.components.clear(); // Discard data from the previous archetype + let mut batch = ColumnBatchType::new(); + while let Some(id) = seq.next_element()? { + match id { + ComponentId::ComponentA => { + batch.add::(); + } + ComponentId::ComponentB => { + batch.add::(); } - self.components.push(id); } - Ok(batch) + self.components.push(id); } + Ok(batch) + } - fn deserialize_components<'de, A>( - &mut self, - entity_count: u32, - mut seq: A, - batch: &mut ColumnBatchBuilder, - ) -> Result<(), A::Error> - where - A: serde::de::SeqAccess<'de>, - { - // Decode component data in the order that the component IDs appeared - for component in &self.components { - match *component { - ComponentId::TestComponent1 => { - deserialize_column::(entity_count, &mut seq, batch)?; - } - ComponentId::TestComponent2 => { - deserialize_column::(entity_count, &mut seq, batch)?; - } + fn deserialize_components<'de, A>( + &mut self, + entity_count: u32, + mut seq: A, + batch: &mut ColumnBatchBuilder, + ) -> Result<(), A::Error> + where + A: serde::de::SeqAccess<'de>, + { + // Decode component data in the order that the component IDs appeared + for component in &self.components { + match *component { + ComponentId::ComponentA => { + deserialize_column::(entity_count, &mut seq, batch)?; + } + ComponentId::ComponentB => { + deserialize_column::(entity_count, &mut seq, batch)?; } } - Ok(()) } + Ok(()) } +} - impl SerializeContext for SaveContext { - fn component_count(&self, archetype: &Archetype) -> usize { - archetype - .component_types() - .filter(|&t| t == TypeId::of::() || t == TypeId::of::()) - .count() - } +impl SerializeContext for SaveContext { + fn component_count(&self, archetype: &Archetype) -> usize { + archetype + .component_types() + .filter(|&t| t == TypeId::of::() || t == TypeId::of::()) + .count() + } - fn serialize_component_ids( - &mut self, - archetype: &Archetype, - mut out: S, - ) -> Result { - try_serialize_id::( - archetype, - &ComponentId::TestComponent1, - &mut out, - )?; - try_serialize_id::( - archetype, - &ComponentId::TestComponent2, - &mut out, - )?; - out.end() - } + fn serialize_component_ids( + &mut self, + archetype: &Archetype, + mut out: S, + ) -> Result { + try_serialize_id::(archetype, &ComponentId::ComponentA, &mut out)?; + try_serialize_id::(archetype, &ComponentId::ComponentB, &mut out)?; + out.end() + } - fn serialize_components( - &mut self, - archetype: &Archetype, - mut out: S, - ) -> Result { - try_serialize::(archetype, &mut out)?; - try_serialize::(archetype, &mut out)?; - out.end() - } + fn serialize_components( + &mut self, + archetype: &Archetype, + mut out: S, + ) -> Result { + try_serialize::(archetype, &mut out)?; + try_serialize::(archetype, &mut out)?; + out.end() } } -use serialize_to_disk_example::*; pub fn main() { // initialize world: let mut world = World::new(); @@ -149,21 +134,22 @@ pub fn main() { // serialize and save our world to disk: let mut buffer: Vec = Vec::new(); - let mut serializer = serde_json::Serializer::new(buffer); + let options = bincode::options(); + let mut serializer = bincode::Serializer::new(&mut buffer, options); hecs::serialize::column::serialize(&world, &mut context, &mut serializer); let path = Path::new(save_file_name); let mut file = match File::create(&path) { Err(why) => panic!("couldn't create {}: {}", path.display(), why), Ok(file) => file, }; - file.write(&serializer.into_inner()) + file.write(&buffer) .expect(&format!("Failed to write file: {}", save_file_name)); println!("Saved world \'{}\' to disk.", path.display()); // load our world from disk and deserialize it back as world: let open = File::open(path).expect("not found!"); let reader = BufReader::new(open); - let mut deserializer = serde_json::Deserializer::from_reader(reader); + let mut deserializer = bincode::Deserializer::with_reader(reader, options); match hecs::serialize::column::deserialize(&mut context, &mut deserializer) { Ok(world) => { // we loaded world from disk successfully, let us confirm that its data is still