diff --git a/Cargo.toml b/Cargo.toml index 89fe0dc..6787ebd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,8 +16,8 @@ include = ["/src", "/LICENSE-MIT", "/LICENSE-APACHE"] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -#bevy = { git = "https://github.com/bevyengine/bevy.git" } -bevy = { git = "https://github.com/MrGVSV/bevy.git", branch = "reflect-serialize-dynamics" } +bevy = { git = "https://github.com/bevyengine/bevy.git" } +#bevy = { path = "../bevy" } bevy_renet = { git = "https://github.com/raffaeleragni/renet.git", branch = "bevy_0_12" } bincode = "1.3.3" serde = { version = "1.0.160", features = ["derive"] } diff --git a/src/client/track.rs b/src/client/track.rs index 09cb036..22f2e0c 100644 --- a/src/client/track.rs +++ b/src/client/track.rs @@ -89,7 +89,7 @@ pub(crate) fn react_on_changed_components( bincode::serialize(&Message::ComponentUpdated { id: change.change_id.id, name: change.change_id.name, - data: compo_to_bin(change.data.clone_value(), ®istry), + data: compo_to_bin(change.data.as_reflect(), ®istry), }) .unwrap(), ); @@ -120,7 +120,7 @@ pub(crate) fn react_on_changed_materials( DefaultChannel::ReliableOrdered, bincode::serialize(&Message::StandardMaterialUpdated { id: *id, - material: compo_to_bin(material.clone_value(), ®istry), + material: compo_to_bin(material.as_reflect(), ®istry), }) .unwrap(), ); diff --git a/src/proto_serde.rs b/src/proto_serde.rs index 09d5d4d..9298362 100644 --- a/src/proto_serde.rs +++ b/src/proto_serde.rs @@ -1,36 +1,31 @@ -use std::any::type_name; - use bevy::reflect::{ serde::{ReflectSerializer, UntypedReflectDeserializer}, DynamicStruct, Reflect, ReflectFromReflect, TypeRegistry, }; use bincode::{DefaultOptions, Options}; -use serde::{ - de::{self, DeserializeSeed, Visitor}, - ser::{SerializeStruct, Serializer}, - Deserializer, Serialize, -}; +use serde::de::DeserializeSeed; -pub(crate) fn compo_to_bin(compo: Box, registry: &TypeRegistry) -> Vec { - let serializer = ComponentData { - data: compo.clone_value(), - registry, - }; - bincode::serialize(&serializer).unwrap() +pub(crate) fn compo_to_bin(compo: &dyn Reflect, registry: &TypeRegistry) -> Vec { + let serializer = ReflectSerializer::new(compo, registry); + DefaultOptions::new() + .with_fixint_encoding() + .allow_trailing_bytes() + .serialize(&serializer) + .unwrap() } pub(crate) fn bin_to_compo(data: &[u8], registry: &TypeRegistry) -> Box { + let reflect_deserializer = UntypedReflectDeserializer::new(registry); let binoptions = DefaultOptions::new() .with_fixint_encoding() .allow_trailing_bytes(); let mut bin_deser = bincode::Deserializer::from_slice(data, binoptions); - let deserializer = ComponentDataDeserializer { registry }; - let data = deserializer.deserialize(&mut bin_deser).unwrap(); - if !data.data.is::() { - return data.data; + let data = reflect_deserializer.deserialize(&mut bin_deser).unwrap(); + if !data.is::() { + return data; } - let data = data.data.downcast::().unwrap(); + let data = data.downcast::().unwrap(); let type_path = data.get_represented_type_info().unwrap().type_path(); let registration = registry.get_with_type_path(type_path).unwrap(); let rfr = registry @@ -39,55 +34,11 @@ pub(crate) fn bin_to_compo(data: &[u8], registry: &TypeRegistry) -> Box { - data: Box, - registry: &'a TypeRegistry, -} - -impl<'a> Serialize for ComponentData<'a> { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - let mut state = serializer.serialize_struct(type_name::(), 1)?; - state.serialize_field( - "data", - &ReflectSerializer::new(self.data.as_reflect(), self.registry), - )?; - state.end() - } -} - -struct ComponentDataDeserializer<'a> { - registry: &'a TypeRegistry, -} - -impl<'a: 'de, 'de: 'a> DeserializeSeed<'de> for ComponentDataDeserializer<'a> { - type Value = ComponentData<'a>; - - fn deserialize>(self, deserializer: D) -> Result { - let registry = self.registry; - let data = deserializer.deserialize_struct(type_name::(), &["data"], self)?; - Ok(ComponentData { data, registry }) - } -} - -impl<'a: 'de, 'de> Visitor<'de> for ComponentDataDeserializer<'a> { - type Value = Box; - - fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { - formatter.write_str(type_name::()) - } - - fn visit_seq>(self, mut seq: A) -> Result { - seq.next_element_seed(UntypedReflectDeserializer::new(self.registry))? - .ok_or_else(|| de::Error::invalid_type(de::Unexpected::NewtypeVariant, &self)) - } -} - #[cfg(test)] mod test { + use super::*; use bevy::{ + pbr::OpaqueRendererMethod, prelude::*, reflect::{GetTypeRegistration, Reflect, ReflectFromReflect, TypeRegistry}, }; @@ -108,7 +59,7 @@ mod test { let mut registry = TypeRegistry::default(); registry.register::(); - let data = compo_to_bin(compo_orig.clone_value(), ®istry); + let data = compo_to_bin(compo_orig.as_reflect(), ®istry); let compo_result = bin_to_compo(&data, ®istry); let compo_result = compo_result.downcast::().unwrap(); @@ -136,7 +87,7 @@ mod test { registry.register_type_data::(); registry.register_type_data::(); - let data = compo_to_bin(compo_orig.clone_value(), ®istry); + let data = compo_to_bin(compo_orig.as_reflect(), ®istry); let compo_result = bin_to_compo(&data, ®istry); let compo_result = compo_result.downcast::().unwrap(); @@ -159,13 +110,45 @@ mod test { registry.register::>>(); registry.register::(); registry.register::(); + registry.register::(); registry.register_type_data::(); - let data = compo_to_bin(material_orig.clone_value(), ®istry); + let data = compo_to_bin(material_orig.as_reflect(), ®istry); let result = bin_to_compo(&data, ®istry); let result = result.downcast::().unwrap(); assert_eq!(result.base_color, material_orig.base_color); } + + #[test] + fn reflect_material_no_dependencies() { + let compo = StandardMaterial { + base_color: Color::RED, + ..StandardMaterial::default() + }; + + let mut registry = TypeRegistry::default(); + registry.register::(); + registry.register::(); + registry.register::(); + registry.register::>(); + registry.register::>>(); + registry.register::(); + registry.register::(); + registry.register::(); + + // compo_to_bin inlined + let cloned = compo.clone_value(); + let serializer = ReflectSerializer::new(cloned.as_reflect(), ®istry); + let result = DefaultOptions::new() + .with_fixint_encoding() + .allow_trailing_bytes() + .serialize(&serializer) + .unwrap(); + + let result = bin_to_compo(&result, ®istry); + let result = result.downcast::().unwrap(); + assert_eq!(compo.base_color, result.base_color); + } } diff --git a/src/server/initial_sync.rs b/src/server/initial_sync.rs index d8abd86..53e1977 100644 --- a/src/server/initial_sync.rs +++ b/src/server/initial_sync.rs @@ -89,7 +89,7 @@ fn check_entity_components(world: &World, result: &mut Vec) -> Result<( let entity = world.entity(arch_entity.entity()); let e_id = entity.id(); let component = reflect_component.reflect(entity).ok_or("not registered")?; - let compo_bin = compo_to_bin(component.clone_value(), ®istry); + let compo_bin = compo_to_bin(component.as_reflect(), ®istry); result.push(Message::ComponentUpdated { id: e_id, name: type_name.into(), @@ -146,7 +146,7 @@ fn check_materials(world: &World, result: &mut Vec) -> Result<(), Box