Skip to content

Commit 225c5ca

Browse files
committed
WIP migration: Add reflect de/serializer code from bevyengine/bevy#15482
1 parent 84450e6 commit 225c5ca

39 files changed

Lines changed: 3092 additions & 1644 deletions

Cargo.lock

Lines changed: 25 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/bevy_animation_graph/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,4 @@ serde = { version = "1.0.193", features = ["derive", "rc"] }
1616
indexmap = { version = "2.2.1", features = ["serde"] }
1717
regex = "1.10.3"
1818
uuid = "1.0"
19+
rmp-serde = "1.3.0"

crates/bevy_animation_graph/src/core/animation_graph/serial.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ use super::{pin, AnimationGraph, Extra};
44
use crate::{
55
prelude::{AnimationNode, DataSpec, DataValue, NodeLike, ReflectNodeLike},
66
utils::{
7-
reflect_de::{TypedReflectDeserializer, ValueProcessor},
8-
reflect_ser::{ReflectSerializerProcessor, TypedReflectSerializer},
7+
de::TypedReflectDeserializer,
8+
ser::{ReflectSerializerProcessor, TypedReflectSerializer},
99
},
1010
};
1111
use bevy::{
@@ -172,7 +172,7 @@ impl<'de> DeserializeSeed<'de> for AnimationNodeLoadDeserializer<'_, '_> {
172172
deserialize_handle(registration, deserializer, load_context)
173173
}),
174174
};
175-
let reflect_deserializer = TypedReflectDeserializer::new_with_processor(
175+
let reflect_deserializer = TypedReflectDeserializer::with_processor(
176176
type_registration,
177177
type_registry,
178178
&mut processor,
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
use bevy::reflect::{ArrayInfo, DynamicArray, TypeRegistry};
2+
use core::{fmt, fmt::Formatter};
3+
use serde::de::{Error, SeqAccess, Visitor};
4+
5+
use super::{
6+
registration_utils::try_get_registration, ReflectDeserializerProcessor,
7+
TypedReflectDeserializer,
8+
};
9+
10+
/// A [`Visitor`] for deserializing [`Array`] values.
11+
///
12+
/// [`Array`]: crate::Array
13+
pub(super) struct ArrayVisitor<'a, P> {
14+
pub array_info: &'static ArrayInfo,
15+
pub registry: &'a TypeRegistry,
16+
pub processor: Option<&'a mut P>,
17+
}
18+
19+
impl<'de, P: ReflectDeserializerProcessor> Visitor<'de> for ArrayVisitor<'_, P> {
20+
type Value = DynamicArray;
21+
22+
fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
23+
formatter.write_str("reflected array value")
24+
}
25+
26+
fn visit_seq<V>(mut self, mut seq: V) -> Result<Self::Value, V::Error>
27+
where
28+
V: SeqAccess<'de>,
29+
{
30+
let mut vec = Vec::with_capacity(seq.size_hint().unwrap_or_default());
31+
let registration = try_get_registration(self.array_info.item_ty(), self.registry)?;
32+
while let Some(value) = seq.next_element_seed(TypedReflectDeserializer::new_internal(
33+
registration,
34+
self.registry,
35+
self.processor.as_deref_mut(),
36+
))? {
37+
vec.push(value);
38+
}
39+
40+
if vec.len() != self.array_info.capacity() {
41+
return Err(Error::invalid_length(
42+
vec.len(),
43+
&self.array_info.capacity().to_string().as_str(),
44+
));
45+
}
46+
47+
Ok(DynamicArray::new(vec.into_boxed_slice()))
48+
}
49+
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
use bevy::reflect::{erased_serde, FromType, PartialReflect, TypeRegistry};
2+
use serde::Deserializer;
3+
4+
use super::error_utils::make_custom_error;
5+
6+
/// Trait used to provide finer control when deserializing a reflected type with one of
7+
/// the reflection deserializers.
8+
///
9+
/// This trait is the reflection equivalent of `serde`'s [`Deserialize`] trait.
10+
/// The main difference is that this trait provides access to the [`TypeRegistry`],
11+
/// which means that we can use the registry and all its stored type information
12+
/// to deserialize our type.
13+
///
14+
/// This can be useful when writing a custom reflection deserializer where we may
15+
/// want to handle parts of the deserialization process, but temporarily pass control
16+
/// to the standard reflection deserializer for other parts.
17+
///
18+
/// For the serialization equivalent of this trait, see [`SerializeWithRegistry`].
19+
///
20+
/// # Rationale
21+
///
22+
/// Without this trait and its associated [type data], such a deserializer would have to
23+
/// write out all of the deserialization logic itself, possibly including
24+
/// unnecessary code duplication and trivial implementations.
25+
///
26+
/// This is because a normal [`Deserialize`] implementation has no knowledge of the
27+
/// [`TypeRegistry`] and therefore cannot create a reflection-based deserializer for
28+
/// nested items.
29+
///
30+
/// # Implementors
31+
///
32+
/// In order for this to work with the reflection deserializers like [`TypedReflectDeserializer`]
33+
/// and [`ReflectDeserializer`], implementors should be sure to register the
34+
/// [`ReflectDeserializeWithRegistry`] type data.
35+
/// This can be done [via the registry] or by adding `#[reflect(DeserializeWithRegistry)]` to
36+
/// the type definition.
37+
///
38+
/// [`Deserialize`]: ::serde::Deserialize
39+
/// [`SerializeWithRegistry`]: crate::serde::SerializeWithRegistry
40+
/// [type data]: ReflectDeserializeWithRegistry
41+
/// [`TypedReflectDeserializer`]: crate::serde::TypedReflectDeserializer
42+
/// [`ReflectDeserializer`]: crate::serde::ReflectDeserializer
43+
/// [via the registry]: TypeRegistry::register_type_data
44+
pub trait DeserializeWithRegistry<'de>: PartialReflect + Sized {
45+
fn deserialize<D>(deserializer: D, registry: &TypeRegistry) -> Result<Self, D::Error>
46+
where
47+
D: Deserializer<'de>;
48+
}
49+
50+
/// Type data used to deserialize a [`PartialReflect`] type with a custom [`DeserializeWithRegistry`] implementation.
51+
#[derive(Clone)]
52+
pub struct ReflectDeserializeWithRegistry {
53+
deserialize: fn(
54+
deserializer: &mut dyn erased_serde::Deserializer,
55+
registry: &TypeRegistry,
56+
) -> Result<Box<dyn PartialReflect>, erased_serde::Error>,
57+
}
58+
59+
impl ReflectDeserializeWithRegistry {
60+
/// Deserialize a [`PartialReflect`] type with this type data's custom [`DeserializeWithRegistry`] implementation.
61+
pub fn deserialize<'de, D>(
62+
&self,
63+
deserializer: D,
64+
registry: &TypeRegistry,
65+
) -> Result<Box<dyn PartialReflect>, D::Error>
66+
where
67+
D: Deserializer<'de>,
68+
{
69+
let mut erased = <dyn erased_serde::Deserializer>::erase(deserializer);
70+
(self.deserialize)(&mut erased, registry).map_err(make_custom_error)
71+
}
72+
}
73+
74+
impl<T: PartialReflect + for<'de> DeserializeWithRegistry<'de>> FromType<T>
75+
for ReflectDeserializeWithRegistry
76+
{
77+
fn from_type() -> Self {
78+
Self {
79+
deserialize: |deserializer, registry| {
80+
Ok(Box::new(T::deserialize(deserializer, registry)?))
81+
},
82+
}
83+
}
84+
}

0 commit comments

Comments
 (0)