Skip to content

Commit 218b0fd

Browse files
bevy_reflect: put serialize into external ReflectSerialize type (#4782)
builds on top of #4780 # Objective `Reflect` and `Serialize` are currently very tied together because `Reflect` has a `fn serialize(&self) -> Option<Serializable<'_>>` method. Because of that, we can either implement `Reflect` for types like `Option<T>` with `T: Serialize` and have `fn serialize` be implemented, or without the bound but having `fn serialize` return `None`. By separating `ReflectSerialize` into a separate type (like how it already is for `ReflectDeserialize`, `ReflectDefault`), we could separately `.register::<Option<T>>()` and `.register_data::<Option<T>, ReflectSerialize>()` only if the type `T: Serialize`. This PR does not change the registration but allows it to be changed in a future PR. ## Solution - add the type ```rust struct ReflectSerialize { .. } impl<T: Reflect + Serialize> FromType<T> for ReflectSerialize { .. } ``` - remove `#[reflect(Serialize)]` special casing. - when serializing reflect value types, look for `ReflectSerialize` in the `TypeRegistry` instead of calling `value.serialize()`
1 parent bb1d524 commit 218b0fd

File tree

18 files changed

+77
-85
lines changed

18 files changed

+77
-85
lines changed

crates/bevy_asset/src/handle.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use crate::{
1010
Asset, Assets,
1111
};
1212
use bevy_ecs::{component::Component, reflect::ReflectComponent};
13-
use bevy_reflect::{FromReflect, Reflect, ReflectDeserialize};
13+
use bevy_reflect::{FromReflect, Reflect, ReflectDeserialize, ReflectSerialize};
1414
use bevy_utils::Uuid;
1515
use crossbeam_channel::{Receiver, Sender};
1616
use serde::{Deserialize, Serialize};

crates/bevy_asset/src/path.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use bevy_reflect::{Reflect, ReflectDeserialize};
1+
use bevy_reflect::{Reflect, ReflectDeserialize, ReflectSerialize};
22
use bevy_utils::AHasher;
33
use serde::{Deserialize, Serialize};
44
use std::{

crates/bevy_core_pipeline/src/clear_color.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use bevy_derive::{Deref, DerefMut};
22
use bevy_ecs::prelude::*;
3-
use bevy_reflect::{Reflect, ReflectDeserialize};
3+
use bevy_reflect::{Reflect, ReflectDeserialize, ReflectSerialize};
44
use bevy_render::{color::Color, extract_resource::ExtractResource};
55
use serde::{Deserialize, Serialize};
66

crates/bevy_core_pipeline/src/core_3d/camera_3d.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::clear_color::ClearColorConfig;
22
use bevy_ecs::{prelude::*, query::QueryItem};
3-
use bevy_reflect::{Reflect, ReflectDeserialize};
3+
use bevy_reflect::{Reflect, ReflectDeserialize, ReflectSerialize};
44
use bevy_render::{
55
camera::{Camera, CameraRenderGraph, Projection},
66
extract_component::ExtractComponent,

crates/bevy_ecs/src/reflect.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use crate::{
88
};
99
use bevy_reflect::{
1010
impl_from_reflect_value, impl_reflect_value, FromType, Reflect, ReflectDeserialize,
11+
ReflectSerialize,
1112
};
1213

1314
#[derive(Clone)]

crates/bevy_reflect/bevy_reflect_derive/src/container_attributes.rs

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ use syn::{Meta, NestedMeta, Path};
1818
const DEBUG_ATTR: &str = "Debug";
1919
const PARTIAL_EQ_ATTR: &str = "PartialEq";
2020
const HASH_ATTR: &str = "Hash";
21-
const SERIALIZE_ATTR: &str = "Serialize";
2221

2322
// The traits listed below are not considered "special" (i.e. they use the `ReflectMyTrait` syntax)
2423
// but useful to know exist nonetheless
@@ -54,7 +53,6 @@ impl Default for TraitImpl {
5453
/// * `Debug`
5554
/// * `Hash`
5655
/// * `PartialEq`
57-
/// * `Serialize`
5856
///
5957
/// When registering a trait, there are a few things to keep in mind:
6058
/// * Traits must have a valid `Reflect{}` struct in scope. For example, `Default`
@@ -110,7 +108,6 @@ pub(crate) struct ReflectTraits {
110108
debug: TraitImpl,
111109
hash: TraitImpl,
112110
partial_eq: TraitImpl,
113-
serialize: TraitImpl,
114111
idents: Vec<Ident>,
115112
}
116113

@@ -133,7 +130,6 @@ impl ReflectTraits {
133130
DEBUG_ATTR => traits.debug = TraitImpl::Implemented,
134131
PARTIAL_EQ_ATTR => traits.partial_eq = TraitImpl::Implemented,
135132
HASH_ATTR => traits.hash = TraitImpl::Implemented,
136-
SERIALIZE_ATTR => traits.serialize = TraitImpl::Implemented,
137133
// We only track reflected idents for traits not considered special
138134
_ => traits.idents.push(utility::get_reflect_ident(&ident)),
139135
}
@@ -156,7 +152,6 @@ impl ReflectTraits {
156152
DEBUG_ATTR => traits.debug = trait_func_ident,
157153
PARTIAL_EQ_ATTR => traits.partial_eq = trait_func_ident,
158154
HASH_ATTR => traits.hash = trait_func_ident,
159-
SERIALIZE_ATTR => traits.serialize = trait_func_ident,
160155
_ => {}
161156
}
162157
}
@@ -230,25 +225,6 @@ impl ReflectTraits {
230225
}
231226
}
232227

233-
/// Returns the implementation of `Reflect::serializable` as a `TokenStream`.
234-
///
235-
/// If `Serialize` was not registered, returns `None`.
236-
pub fn get_serialize_impl(&self, bevy_reflect_path: &Path) -> Option<proc_macro2::TokenStream> {
237-
match &self.serialize {
238-
TraitImpl::Implemented => Some(quote! {
239-
fn serializable(&self) -> Option<#bevy_reflect_path::serde::Serializable> {
240-
Some(#bevy_reflect_path::serde::Serializable::Borrowed(self))
241-
}
242-
}),
243-
TraitImpl::Custom(impl_fn) => Some(quote! {
244-
fn serializable(&self) -> Option<#bevy_reflect_path::serde::Serializable> {
245-
Some(#impl_fn(self))
246-
}
247-
}),
248-
TraitImpl::NotImplemented => None,
249-
}
250-
}
251-
252228
/// Returns the implementation of `Reflect::debug` as a `TokenStream`.
253229
///
254230
/// If `Debug` was not registered, returns `None`.

crates/bevy_reflect/bevy_reflect_derive/src/impls.rs

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ pub(crate) fn impl_struct(derive_data: &ReflectDeriveData) -> TokenStream {
4040
let field_indices = (0..field_count).collect::<Vec<usize>>();
4141

4242
let hash_fn = derive_data.traits().get_hash_impl(bevy_reflect_path);
43-
let serialize_fn = derive_data.traits().get_serialize_impl(bevy_reflect_path);
4443
let partial_eq_fn = derive_data
4544
.traits()
4645
.get_partial_eq_impl(bevy_reflect_path)
@@ -192,8 +191,6 @@ pub(crate) fn impl_struct(derive_data: &ReflectDeriveData) -> TokenStream {
192191
#partial_eq_fn
193192

194193
#debug_fn
195-
196-
#serialize_fn
197194
}
198195
})
199196
}
@@ -216,7 +213,6 @@ pub(crate) fn impl_tuple_struct(derive_data: &ReflectDeriveData) -> TokenStream
216213
let field_indices = (0..field_count).collect::<Vec<usize>>();
217214

218215
let hash_fn = derive_data.traits().get_hash_impl(bevy_reflect_path);
219-
let serialize_fn = derive_data.traits().get_serialize_impl(bevy_reflect_path);
220216
let partial_eq_fn = derive_data
221217
.traits()
222218
.get_partial_eq_impl(bevy_reflect_path)
@@ -344,8 +340,6 @@ pub(crate) fn impl_tuple_struct(derive_data: &ReflectDeriveData) -> TokenStream
344340
#partial_eq_fn
345341

346342
#debug_fn
347-
348-
#serialize_fn
349343
}
350344
})
351345
}
@@ -359,7 +353,6 @@ pub(crate) fn impl_value(
359353
reflect_traits: &ReflectTraits,
360354
) -> TokenStream {
361355
let hash_fn = reflect_traits.get_hash_impl(bevy_reflect_path);
362-
let serialize_fn = reflect_traits.get_serialize_impl(bevy_reflect_path);
363356
let partial_eq_fn = reflect_traits.get_partial_eq_impl(bevy_reflect_path);
364357
let debug_fn = reflect_traits.get_debug_impl();
365358

@@ -445,8 +438,6 @@ pub(crate) fn impl_value(
445438
#partial_eq_fn
446439

447440
#debug_fn
448-
449-
#serialize_fn
450441
}
451442
})
452443
}

crates/bevy_reflect/src/array.rs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
use crate::{
2-
serde::Serializable, utility::NonGenericTypeInfoCell, DynamicInfo, Reflect, ReflectMut,
3-
ReflectRef, TypeInfo, Typed,
2+
utility::NonGenericTypeInfoCell, DynamicInfo, Reflect, ReflectMut, ReflectRef, TypeInfo, Typed,
43
};
54
use std::{
65
any::{Any, TypeId},
@@ -217,10 +216,6 @@ unsafe impl Reflect for DynamicArray {
217216
fn reflect_partial_eq(&self, value: &dyn Reflect) -> Option<bool> {
218217
array_partial_eq(self, value)
219218
}
220-
221-
fn serializable(&self) -> Option<Serializable> {
222-
None
223-
}
224219
}
225220

226221
impl Array for DynamicArray {

crates/bevy_reflect/src/impls/glam.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate as bevy_reflect;
22
use crate::prelude::ReflectDefault;
33
use crate::reflect::Reflect;
4-
use crate::ReflectDeserialize;
4+
use crate::{ReflectDeserialize, ReflectSerialize};
55
use bevy_reflect_derive::{impl_from_reflect_value, impl_reflect_struct, impl_reflect_value};
66
use glam::*;
77

crates/bevy_reflect/src/impls/std.rs

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use crate as bevy_reflect;
22
use crate::{
3-
map_partial_eq, serde::Serializable, Array, ArrayInfo, ArrayIter, DynamicMap, FromReflect,
4-
FromType, GetTypeRegistration, List, ListInfo, Map, MapInfo, MapIter, Reflect,
5-
ReflectDeserialize, ReflectMut, ReflectRef, TypeInfo, TypeRegistration, Typed, ValueInfo,
3+
map_partial_eq, Array, ArrayInfo, ArrayIter, DynamicMap, FromReflect, FromType,
4+
GetTypeRegistration, List, ListInfo, Map, MapInfo, MapIter, Reflect, ReflectDeserialize,
5+
ReflectMut, ReflectRef, ReflectSerialize, TypeInfo, TypeRegistration, Typed, ValueInfo,
66
};
77

88
use crate::utility::{GenericTypeInfoCell, NonGenericTypeInfoCell};
@@ -159,10 +159,6 @@ unsafe impl<T: FromReflect> Reflect for Vec<T> {
159159
fn reflect_partial_eq(&self, value: &dyn Reflect) -> Option<bool> {
160160
crate::list_partial_eq(self, value)
161161
}
162-
163-
fn serializable(&self) -> Option<Serializable> {
164-
None
165-
}
166162
}
167163

168164
impl<T: FromReflect> Typed for Vec<T> {
@@ -420,11 +416,6 @@ unsafe impl<T: Reflect, const N: usize> Reflect for [T; N] {
420416
fn reflect_partial_eq(&self, value: &dyn Reflect) -> Option<bool> {
421417
crate::array_partial_eq(self, value)
422418
}
423-
424-
#[inline]
425-
fn serializable(&self) -> Option<Serializable> {
426-
None
427-
}
428419
}
429420

430421
impl<T: FromReflect, const N: usize> FromReflect for [T; N] {
@@ -541,10 +532,6 @@ unsafe impl Reflect for Cow<'static, str> {
541532
Some(false)
542533
}
543534
}
544-
545-
fn serializable(&self) -> Option<Serializable> {
546-
Some(Serializable::Borrowed(self))
547-
}
548535
}
549536

550537
impl Typed for Cow<'static, str> {
@@ -558,6 +545,7 @@ impl GetTypeRegistration for Cow<'static, str> {
558545
fn get_type_registration() -> TypeRegistration {
559546
let mut registration = TypeRegistration::of::<Cow<'static, str>>();
560547
registration.insert::<ReflectDeserialize>(FromType::<Cow<'static, str>>::from_type());
548+
registration.insert::<ReflectSerialize>(FromType::<Cow<'static, str>>::from_type());
561549
registration
562550
}
563551
}
@@ -570,13 +558,19 @@ impl FromReflect for Cow<'static, str> {
570558

571559
#[cfg(test)]
572560
mod tests {
573-
use crate::Reflect;
561+
use crate::{Reflect, ReflectSerialize, TypeRegistry};
574562
use bevy_utils::HashMap;
575563
use std::f32::consts::{PI, TAU};
576564

577565
#[test]
578566
fn can_serialize_duration() {
579-
assert!(std::time::Duration::ZERO.serializable().is_some());
567+
let mut type_registry = TypeRegistry::default();
568+
type_registry.register::<std::time::Duration>();
569+
570+
let reflect_serialize = type_registry
571+
.get_type_data::<ReflectSerialize>(std::any::TypeId::of::<std::time::Duration>())
572+
.unwrap();
573+
let _serializable = reflect_serialize.get_serializable(&std::time::Duration::ZERO);
580574
}
581575

582576
#[test]

0 commit comments

Comments
 (0)