pull in ron. use static strings for types

This commit is contained in:
Carter Anderson 2020-05-19 12:20:37 -07:00
parent a88982fbfb
commit dcdd552365
4 changed files with 57 additions and 43 deletions

View file

@ -56,12 +56,13 @@ log = { version = "0.4", features = ["release_max_level_info"] }
[dev-dependencies] [dev-dependencies]
rand = "0.7.2" rand = "0.7.2"
serde = { version = "1", features = ["derive"]} serde = { version = "1", features = ["derive"]}
ron = "0.5.1"
serde_json = "1.0" serde_json = "1.0"
type-uuid = "0.1" type-uuid = "0.1"
env_logger = "0.7" env_logger = "0.7"
[profile.dev] [profile.dev]
opt-level = 3 # opt-level = 3
[[example]] [[example]]
name = "hello_world" name = "hello_world"

View file

@ -6,7 +6,8 @@ edition = "2018"
[dependencies] [dependencies]
legion = { path = "../bevy_legion", features = ["serialize"] } legion = { path = "../bevy_legion", features = ["serialize"] }
serde = { version = "1", features = ["derive"]} serde = { version = "1.0", features = ["derive"]}
erased-serde = "0.3" erased-serde = "0.3"
type-uuid = "0.1" type-uuid = "0.1"
ron = "0.5.1"
uuid = { version = "0.8", features = ["v4", "serde"] } uuid = { version = "0.8", features = ["v4", "serde"] }

View file

@ -101,7 +101,7 @@ impl<'de, 'a, T: for<'b> Deserialize<'b> + 'static> Visitor<'de>
#[derive(Clone)] #[derive(Clone)]
pub struct TagRegistration { pub struct TagRegistration {
uuid: type_uuid::Bytes, uuid: type_uuid::Bytes,
ty: String, ty: &'static str,
tag_serialize_fn: fn(&TagStorage, &mut dyn FnMut(&dyn erased_serde::Serialize)), tag_serialize_fn: fn(&TagStorage, &mut dyn FnMut(&dyn erased_serde::Serialize)),
tag_deserialize_fn: fn( tag_deserialize_fn: fn(
deserializer: &mut dyn erased_serde::Deserializer, deserializer: &mut dyn erased_serde::Deserializer,
@ -123,7 +123,7 @@ impl TagRegistration {
>() -> Self { >() -> Self {
Self { Self {
uuid: T::UUID, uuid: T::UUID,
ty: type_name::<T>().to_string(), ty: type_name::<T>(),
tag_serialize_fn: |tag_storage, serialize_fn| { tag_serialize_fn: |tag_storage, serialize_fn| {
// it's safe because we know this is the correct type due to lookup // it's safe because we know this is the correct type due to lookup
let slice = unsafe { tag_storage.data_slice::<T>() }; let slice = unsafe { tag_storage.data_slice::<T>() };
@ -150,7 +150,7 @@ impl TagRegistration {
#[derive(Clone)] #[derive(Clone)]
pub struct ComponentRegistration { pub struct ComponentRegistration {
uuid: type_uuid::Bytes, uuid: type_uuid::Bytes,
ty: String, ty: &'static str,
comp_serialize_fn: fn(&ComponentResourceSet, &mut dyn FnMut(&dyn erased_serde::Serialize)), comp_serialize_fn: fn(&ComponentResourceSet, &mut dyn FnMut(&dyn erased_serde::Serialize)),
comp_deserialize_fn: fn( comp_deserialize_fn: fn(
deserializer: &mut dyn erased_serde::Deserializer, deserializer: &mut dyn erased_serde::Deserializer,
@ -164,7 +164,7 @@ impl ComponentRegistration {
{ {
Self { Self {
uuid: T::UUID, uuid: T::UUID,
ty: type_name::<T>().to_string(), ty: type_name::<T>(),
comp_serialize_fn: |comp_storage, serialize_fn| { comp_serialize_fn: |comp_storage, serialize_fn| {
// it's safe because we know this is the correct type due to lookup // it's safe because we know this is the correct type due to lookup
let slice = unsafe { comp_storage.data_slice::<T>() }; let slice = unsafe { comp_storage.data_slice::<T>() };
@ -192,8 +192,8 @@ struct SerializedArchetypeDescription {
} }
pub struct SerializeImpl { pub struct SerializeImpl {
pub tag_types: HashMap<String, TagRegistration>, pub tag_types: HashMap<&'static str, TagRegistration>,
pub comp_types: HashMap<String, ComponentRegistration>, pub comp_types: HashMap<&'static str, ComponentRegistration>,
pub entity_map: RefCell<HashMap<Entity, uuid::Bytes>>, pub entity_map: RefCell<HashMap<Entity, uuid::Bytes>>,
} }
@ -337,8 +337,8 @@ impl legion::serialize::ser::WorldSerializer for SerializeImpl {
} }
pub struct DeserializeImpl { pub struct DeserializeImpl {
pub tag_types: HashMap<String, TagRegistration>, pub tag_types: HashMap<&'static str, TagRegistration>,
pub comp_types: HashMap<String, ComponentRegistration>, pub comp_types: HashMap<&'static str, ComponentRegistration>,
pub tag_types_by_uuid: HashMap<type_uuid::Bytes, TagRegistration>, pub tag_types_by_uuid: HashMap<type_uuid::Bytes, TagRegistration>,
pub comp_types_by_uuid: HashMap<type_uuid::Bytes, ComponentRegistration>, pub comp_types_by_uuid: HashMap<type_uuid::Bytes, ComponentRegistration>,
pub entity_map: RefCell<HashMap<uuid::Bytes, Entity>>, pub entity_map: RefCell<HashMap<uuid::Bytes, Entity>>,
@ -346,8 +346,8 @@ pub struct DeserializeImpl {
impl DeserializeImpl { impl DeserializeImpl {
pub fn new( pub fn new(
component_types: HashMap<String, ComponentRegistration>, component_types: HashMap<&'static str, ComponentRegistration>,
tag_types: HashMap<String, TagRegistration>, tag_types: HashMap<&'static str, TagRegistration>,
entity_map: RefCell<HashMap<Entity, uuid::Bytes>>, entity_map: RefCell<HashMap<Entity, uuid::Bytes>>,
) -> Self { ) -> Self {
DeserializeImpl { DeserializeImpl {

View file

@ -1,36 +1,12 @@
use bevy::{prelude::*, serialization::*}; use bevy::{prelude::*, serialization::*};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use ron::ser::{to_string_pretty, PrettyConfig};
use type_uuid::TypeUuid; use type_uuid::TypeUuid;
fn main() { fn main() {
let mut app = App::build(); App::build()
app.add_default_plugins().add_startup_system(setup); .add_plugin(ScheduleRunnerPlugin::run_once())
.add_startup_system(setup)
let comp_registrations = [ComponentRegistration::of::<Test>()]; .run();
let tag_registrations = [];
let ser_helper = SerializeImpl::new(&comp_registrations, &tag_registrations);
let serializable = legion::serialize::ser::serializable_world(&app.world(), &ser_helper);
let serialized_data = serde_json::to_string(&serializable).unwrap();
println!("{}", serialized_data);
let de_helper = DeserializeImpl::new(
ser_helper.comp_types,
ser_helper.tag_types,
ser_helper.entity_map,
);
let mut new_world = app.universe().create_world();
let mut deserializer = serde_json::Deserializer::from_str(&serialized_data);
legion::serialize::de::deserialize(&mut new_world, &de_helper, &mut deserializer).unwrap();
let ser_helper = SerializeImpl::new_with_map(
&comp_registrations,
&tag_registrations,
de_helper.entity_map.into_inner(),
);
let serializable = legion::serialize::ser::serializable_world(&new_world, &ser_helper);
let roundtrip_data = serde_json::to_string(&serializable).unwrap();
println!("{}", roundtrip_data);
assert_eq!(roundtrip_data, serialized_data);
} }
#[derive(Serialize, Deserialize, TypeUuid)] #[derive(Serialize, Deserialize, TypeUuid)]
@ -40,7 +16,43 @@ struct Test {
pub y: f32, pub y: f32,
} }
fn setup(world: &mut World, _resources: &mut Resources) { fn setup(world: &mut World, resources: &mut Resources) {
// plane
world.insert((), vec![(Test { x: 3.0, y: 4.0 },)]); world.insert((), vec![(Test { x: 3.0, y: 4.0 },)]);
let comp_registrations = [ComponentRegistration::of::<Test>()];
let tag_registrations = [];
let ser_helper = SerializeImpl::new(&comp_registrations, &tag_registrations);
let serializable = legion::serialize::ser::serializable_world(world, &ser_helper);
let serialized_data = serde_json::to_string(&serializable).unwrap();
// println!("{}", serialized_data);
let pretty = PrettyConfig {
depth_limit: 2,
separate_tuple_members: true,
enumerate_arrays: true,
..Default::default()
};
let s = to_string_pretty(&serializable, pretty).expect("Serialization failed");
println!("{}", s);
let de_helper = DeserializeImpl::new(
ser_helper.comp_types,
ser_helper.tag_types,
ser_helper.entity_map,
);
let universe = resources.get_mut::<Universe>().unwrap();
let mut new_world = universe.create_world();
let mut deserializer = serde_json::Deserializer::from_str(&serialized_data);
legion::serialize::de::deserialize(&mut new_world, &de_helper, &mut deserializer).unwrap();
let ser_helper = SerializeImpl::new_with_map(
&comp_registrations,
&tag_registrations,
de_helper.entity_map.into_inner(),
);
let serializable = legion::serialize::ser::serializable_world(&new_world, &ser_helper);
let roundtrip_data = serde_json::to_string(&serializable).unwrap();
// println!("{}", roundtrip_data);
assert_eq!(roundtrip_data, serialized_data);
} }