Skip to content

Commit

Permalink
avoid cloning
Browse files Browse the repository at this point in the history
  • Loading branch information
raffaeleragni committed Oct 19, 2023
1 parent 3c88528 commit c3cf9a2
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 75 deletions.
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"] }
Expand Down
4 changes: 2 additions & 2 deletions src/client/track.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(), &registry),
data: compo_to_bin(change.data.as_reflect(), &registry),
})
.unwrap(),
);
Expand Down Expand Up @@ -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(), &registry),
material: compo_to_bin(material.as_reflect(), &registry),
})
.unwrap(),
);
Expand Down
117 changes: 50 additions & 67 deletions src/proto_serde.rs
Original file line number Diff line number Diff line change
@@ -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<dyn Reflect>, registry: &TypeRegistry) -> Vec<u8> {
let serializer = ComponentData {
data: compo.clone_value(),
registry,
};
bincode::serialize(&serializer).unwrap()
pub(crate) fn compo_to_bin(compo: &dyn Reflect, registry: &TypeRegistry) -> Vec<u8> {
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<dyn Reflect> {
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::<DynamicStruct>() {
return data.data;
let data = reflect_deserializer.deserialize(&mut bin_deser).unwrap();
if !data.is::<DynamicStruct>() {
return data;
}
let data = data.data.downcast::<DynamicStruct>().unwrap();
let data = data.downcast::<DynamicStruct>().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
Expand All @@ -39,55 +34,11 @@ pub(crate) fn bin_to_compo(data: &[u8], registry: &TypeRegistry) -> Box<dyn Refl
rfr.from_reflect(&*data).unwrap()
}

struct ComponentData<'a> {
data: Box<dyn Reflect>,
registry: &'a TypeRegistry,
}

impl<'a> Serialize for ComponentData<'a> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut state = serializer.serialize_struct(type_name::<ComponentData>(), 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<D: Deserializer<'de>>(self, deserializer: D) -> Result<Self::Value, D::Error> {
let registry = self.registry;
let data = deserializer.deserialize_struct(type_name::<Self::Value>(), &["data"], self)?;
Ok(ComponentData { data, registry })
}
}

impl<'a: 'de, 'de> Visitor<'de> for ComponentDataDeserializer<'a> {
type Value = Box<dyn Reflect>;

fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str(type_name::<Self::Value>())
}

fn visit_seq<A: serde::de::SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
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},
};
Expand All @@ -108,7 +59,7 @@ mod test {
let mut registry = TypeRegistry::default();
registry.register::<T>();

let data = compo_to_bin(compo_orig.clone_value(), &registry);
let data = compo_to_bin(compo_orig.as_reflect(), &registry);

let compo_result = bin_to_compo(&data, &registry);
let compo_result = compo_result.downcast::<T>().unwrap();
Expand Down Expand Up @@ -136,7 +87,7 @@ mod test {
registry.register_type_data::<Vec3, ReflectFromReflect>();
registry.register_type_data::<Quat, ReflectFromReflect>();

let data = compo_to_bin(compo_orig.clone_value(), &registry);
let data = compo_to_bin(compo_orig.as_reflect(), &registry);

let compo_result = bin_to_compo(&data, &registry);
let compo_result = compo_result.downcast::<Transform>().unwrap();
Expand All @@ -159,13 +110,45 @@ mod test {
registry.register::<Option<Handle<Image>>>();
registry.register::<AlphaMode>();
registry.register::<ParallaxMappingMethod>();
registry.register::<OpaqueRendererMethod>();
registry.register_type_data::<StandardMaterial, ReflectFromReflect>();

let data = compo_to_bin(material_orig.clone_value(), &registry);
let data = compo_to_bin(material_orig.as_reflect(), &registry);

let result = bin_to_compo(&data, &registry);
let result = result.downcast::<StandardMaterial>().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::<StandardMaterial>();
registry.register::<Color>();
registry.register::<Image>();
registry.register::<Handle<Image>>();
registry.register::<Option<Handle<Image>>>();
registry.register::<AlphaMode>();
registry.register::<ParallaxMappingMethod>();
registry.register::<OpaqueRendererMethod>();

// compo_to_bin inlined
let cloned = compo.clone_value();
let serializer = ReflectSerializer::new(cloned.as_reflect(), &registry);
let result = DefaultOptions::new()
.with_fixint_encoding()
.allow_trailing_bytes()
.serialize(&serializer)
.unwrap();

let result = bin_to_compo(&result, &registry);
let result = result.downcast::<StandardMaterial>().unwrap();
assert_eq!(compo.base_color, result.base_color);
}
}
4 changes: 2 additions & 2 deletions src/server/initial_sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ fn check_entity_components(world: &World, result: &mut Vec<Message>) -> 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(), &registry);
let compo_bin = compo_to_bin(component.as_reflect(), &registry);
result.push(Message::ComponentUpdated {
id: e_id,
name: type_name.into(),
Expand Down Expand Up @@ -146,7 +146,7 @@ fn check_materials(world: &World, result: &mut Vec<Message>) -> Result<(), Box<d
};
result.push(Message::StandardMaterialUpdated {
id,
material: compo_to_bin(material.clone_value(), &registry),
material: compo_to_bin(material.as_reflect(), &registry),
});
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/server/track.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ pub(crate) fn react_on_changed_components(
bincode::serialize(&Message::ComponentUpdated {
id: change.change_id.id,
name: change.change_id.name.clone(),
data: compo_to_bin(change.data.clone_value(), &registry),
data: compo_to_bin(change.data.as_reflect(), &registry),
})
.unwrap(),
);
Expand Down Expand Up @@ -178,7 +178,7 @@ pub(crate) fn react_on_changed_materials(
DefaultChannel::ReliableOrdered,
bincode::serialize(&Message::StandardMaterialUpdated {
id: *id,
material: compo_to_bin(material.clone_value(), &registry),
material: compo_to_bin(material.as_reflect(), &registry),
})
.unwrap(),
);
Expand Down

0 comments on commit c3cf9a2

Please sign in to comment.