Skip to content

Commit 15acd6f

Browse files
committed
bevy_reflect: Small refactor and default Reflect methods (#4739)
# Objective Quick followup to #4712. While updating some [other PRs](#4218), I realized the `ReflectTraits` struct could be improved. The issue with the current implementation is that `ReflectTraits::get_xxx_impl(...)` returns just the _logic_ to the corresponding `Reflect` trait method, rather than the entire function. This makes it slightly more annoying to manage since the variable names need to be consistent across files. For example, `get_partial_eq_impl` uses a `value` variable. But the name "value" isn't defined in the `get_partial_eq_impl` method, it's defined in three other methods in a completely separate file. It's not likely to cause any bugs if we keep it as it is since differing variable names will probably just result in a compile error (except in very particular cases). But it would be useful to someone who wanted to edit/add/remove a method. ## Solution Made `get_hash_impl`, `get_partial_eq_impl` and `get_serialize_impl` return the entire method implementation for `reflect_hash`, `reflect_partial_eq`, and `serializable`, respectively. As a result of this, those three `Reflect` methods were also given default implementations. This was fairly simple to do since all three could just be made to return `None`. --- ## Changelog * Small cleanup/refactor to `ReflectTraits` in `bevy_reflect_derive` * Gave `Reflect::reflect_hash`, `Reflect::reflect_partial_eq`, and `Reflect::serializable` default implementations
1 parent de2b1a4 commit 15acd6f

File tree

9 files changed

+75
-144
lines changed

9 files changed

+75
-144
lines changed

crates/bevy_reflect/bevy_reflect_derive/src/container_attributes.rs

Lines changed: 35 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -171,55 +171,70 @@ impl ReflectTraits {
171171
&self.idents
172172
}
173173

174-
/// Returns the logic for `Reflect::reflect_hash` as a `TokenStream`.
174+
/// Returns the implementation of `Reflect::reflect_hash` as a `TokenStream`.
175175
///
176176
/// If `Hash` was not registered, returns `None`.
177-
pub fn get_hash_impl(&self, path: &Path) -> Option<proc_macro2::TokenStream> {
177+
pub fn get_hash_impl(&self, bevy_reflect_path: &Path) -> Option<proc_macro2::TokenStream> {
178178
match &self.hash {
179179
TraitImpl::Implemented => Some(quote! {
180-
use std::hash::{Hash, Hasher};
181-
let mut hasher = #path::ReflectHasher::default();
182-
Hash::hash(&std::any::Any::type_id(self), &mut hasher);
183-
Hash::hash(self, &mut hasher);
184-
Some(hasher.finish())
180+
fn reflect_hash(&self) -> Option<u64> {
181+
use std::hash::{Hash, Hasher};
182+
let mut hasher = #bevy_reflect_path::ReflectHasher::default();
183+
Hash::hash(&std::any::Any::type_id(self), &mut hasher);
184+
Hash::hash(self, &mut hasher);
185+
Some(hasher.finish())
186+
}
185187
}),
186188
TraitImpl::Custom(impl_fn) => Some(quote! {
187-
Some(#impl_fn(self))
189+
fn reflect_hash(&self) -> Option<u64> {
190+
Some(#impl_fn(self))
191+
}
188192
}),
189193
TraitImpl::NotImplemented => None,
190194
}
191195
}
192196

193-
/// Returns the logic for `Reflect::reflect_partial_eq` as a `TokenStream`.
197+
/// Returns the implementation of `Reflect::reflect_partial_eq` as a `TokenStream`.
194198
///
195199
/// If `PartialEq` was not registered, returns `None`.
196-
pub fn get_partial_eq_impl(&self) -> Option<proc_macro2::TokenStream> {
200+
pub fn get_partial_eq_impl(
201+
&self,
202+
bevy_reflect_path: &Path,
203+
) -> Option<proc_macro2::TokenStream> {
197204
match &self.partial_eq {
198205
TraitImpl::Implemented => Some(quote! {
199-
let value = value.any();
200-
if let Some(value) = value.downcast_ref::<Self>() {
201-
Some(std::cmp::PartialEq::eq(self, value))
202-
} else {
203-
Some(false)
206+
fn reflect_partial_eq(&self, value: &dyn #bevy_reflect_path::Reflect) -> Option<bool> {
207+
let value = value.any();
208+
if let Some(value) = value.downcast_ref::<Self>() {
209+
Some(std::cmp::PartialEq::eq(self, value))
210+
} else {
211+
Some(false)
212+
}
204213
}
205214
}),
206215
TraitImpl::Custom(impl_fn) => Some(quote! {
207-
Some(#impl_fn(self, value))
216+
fn reflect_partial_eq(&self, value: &dyn #bevy_reflect_path::Reflect) -> Option<bool> {
217+
Some(#impl_fn(self, value))
218+
}
208219
}),
209220
TraitImpl::NotImplemented => None,
210221
}
211222
}
212223

213-
/// Returns the logic for `Reflect::serializable` as a `TokenStream`.
224+
/// Returns the implementation of `Reflect::serializable` as a `TokenStream`.
214225
///
215226
/// If `Serialize` was not registered, returns `None`.
216-
pub fn get_serialize_impl(&self, path: &Path) -> Option<proc_macro2::TokenStream> {
227+
pub fn get_serialize_impl(&self, bevy_reflect_path: &Path) -> Option<proc_macro2::TokenStream> {
217228
match &self.serialize {
218229
TraitImpl::Implemented => Some(quote! {
219-
Some(#path::serde::Serializable::Borrowed(self))
230+
fn serializable(&self) -> Option<#bevy_reflect_path::serde::Serializable> {
231+
Some(#bevy_reflect_path::serde::Serializable::Borrowed(self))
232+
}
220233
}),
221234
TraitImpl::Custom(impl_fn) => Some(quote! {
222-
Some(#impl_fn(self))
235+
fn serializable(&self) -> Option<#bevy_reflect_path::serde::Serializable> {
236+
Some(#impl_fn(self))
237+
}
223238
}),
224239
TraitImpl::NotImplemented => None,
225240
}

crates/bevy_reflect/bevy_reflect_derive/src/impls.rs

Lines changed: 25 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -35,20 +35,16 @@ pub(crate) fn impl_struct(derive_data: &ReflectDeriveData) -> TokenStream {
3535
let field_count = field_idents.len();
3636
let field_indices = (0..field_count).collect::<Vec<usize>>();
3737

38-
let hash_fn = derive_data
39-
.traits()
40-
.get_hash_impl(bevy_reflect_path)
41-
.unwrap_or_else(|| quote!(None));
42-
let serialize_fn = derive_data
43-
.traits()
44-
.get_serialize_impl(bevy_reflect_path)
45-
.unwrap_or_else(|| quote!(None));
38+
let hash_fn = derive_data.traits().get_hash_impl(bevy_reflect_path);
39+
let serialize_fn = derive_data.traits().get_serialize_impl(bevy_reflect_path);
4640
let partial_eq_fn = derive_data
4741
.traits()
48-
.get_partial_eq_impl()
42+
.get_partial_eq_impl(bevy_reflect_path)
4943
.unwrap_or_else(|| {
5044
quote! {
51-
#bevy_reflect_path::struct_partial_eq(self, value)
45+
fn reflect_partial_eq(&self, value: &dyn #bevy_reflect_path::Reflect) -> Option<bool> {
46+
#bevy_reflect_path::struct_partial_eq(self, value)
47+
}
5248
}
5349
});
5450

@@ -166,17 +162,11 @@ pub(crate) fn impl_struct(derive_data: &ReflectDeriveData) -> TokenStream {
166162
#bevy_reflect_path::ReflectMut::Struct(self)
167163
}
168164

169-
fn serializable(&self) -> Option<#bevy_reflect_path::serde::Serializable> {
170-
#serialize_fn
171-
}
165+
#hash_fn
172166

173-
fn reflect_hash(&self) -> Option<u64> {
174-
#hash_fn
175-
}
167+
#partial_eq_fn
176168

177-
fn reflect_partial_eq(&self, value: &dyn #bevy_reflect_path::Reflect) -> Option<bool> {
178-
#partial_eq_fn
179-
}
169+
#serialize_fn
180170
}
181171
})
182172
}
@@ -194,20 +184,16 @@ pub(crate) fn impl_tuple_struct(derive_data: &ReflectDeriveData) -> TokenStream
194184
let field_count = field_idents.len();
195185
let field_indices = (0..field_count).collect::<Vec<usize>>();
196186

197-
let hash_fn = derive_data
198-
.traits()
199-
.get_hash_impl(bevy_reflect_path)
200-
.unwrap_or_else(|| quote!(None));
201-
let serialize_fn = derive_data
202-
.traits()
203-
.get_serialize_impl(bevy_reflect_path)
204-
.unwrap_or_else(|| quote!(None));
187+
let hash_fn = derive_data.traits().get_hash_impl(bevy_reflect_path);
188+
let serialize_fn = derive_data.traits().get_serialize_impl(bevy_reflect_path);
205189
let partial_eq_fn = derive_data
206190
.traits()
207-
.get_partial_eq_impl()
191+
.get_partial_eq_impl(bevy_reflect_path)
208192
.unwrap_or_else(|| {
209193
quote! {
210-
#bevy_reflect_path::tuple_struct_partial_eq(self, value)
194+
fn reflect_partial_eq(&self, value: &dyn #bevy_reflect_path::Reflect) -> Option<bool> {
195+
#bevy_reflect_path::tuple_struct_partial_eq(self, value)
196+
}
211197
}
212198
});
213199

@@ -301,17 +287,11 @@ pub(crate) fn impl_tuple_struct(derive_data: &ReflectDeriveData) -> TokenStream
301287
#bevy_reflect_path::ReflectMut::TupleStruct(self)
302288
}
303289

304-
fn serializable(&self) -> Option<#bevy_reflect_path::serde::Serializable> {
305-
#serialize_fn
306-
}
290+
#hash_fn
307291

308-
fn reflect_hash(&self) -> Option<u64> {
309-
#hash_fn
310-
}
292+
#partial_eq_fn
311293

312-
fn reflect_partial_eq(&self, value: &dyn #bevy_reflect_path::Reflect) -> Option<bool> {
313-
#partial_eq_fn
314-
}
294+
#serialize_fn
315295
}
316296
})
317297
}
@@ -322,17 +302,11 @@ pub(crate) fn impl_value(
322302
generics: &Generics,
323303
get_type_registration_impl: proc_macro2::TokenStream,
324304
bevy_reflect_path: &Path,
325-
reflect_attrs: &ReflectTraits,
305+
reflect_traits: &ReflectTraits,
326306
) -> TokenStream {
327-
let hash_fn = reflect_attrs
328-
.get_hash_impl(bevy_reflect_path)
329-
.unwrap_or_else(|| quote!(None));
330-
let partial_eq_fn = reflect_attrs
331-
.get_partial_eq_impl()
332-
.unwrap_or_else(|| quote!(None));
333-
let serialize_fn = reflect_attrs
334-
.get_serialize_impl(bevy_reflect_path)
335-
.unwrap_or_else(|| quote!(None));
307+
let hash_fn = reflect_traits.get_hash_impl(bevy_reflect_path);
308+
let serialize_fn = reflect_traits.get_serialize_impl(bevy_reflect_path);
309+
let partial_eq_fn = reflect_traits.get_partial_eq_impl(bevy_reflect_path);
336310

337311
let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
338312
TokenStream::from(quote! {
@@ -394,17 +368,11 @@ pub(crate) fn impl_value(
394368
#bevy_reflect_path::ReflectMut::Value(self)
395369
}
396370

397-
fn reflect_hash(&self) -> Option<u64> {
398-
#hash_fn
399-
}
371+
#hash_fn
400372

401-
fn reflect_partial_eq(&self, value: &dyn #bevy_reflect_path::Reflect) -> Option<bool> {
402-
#partial_eq_fn
403-
}
373+
#partial_eq_fn
404374

405-
fn serializable(&self) -> Option<#bevy_reflect_path::serde::Serializable> {
406-
#serialize_fn
407-
}
375+
#serialize_fn
408376
}
409377
})
410378
}

crates/bevy_reflect/src/impls/smallvec.rs

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
use smallvec::SmallVec;
22
use std::any::Any;
33

4-
use crate::{
5-
serde::Serializable, Array, ArrayIter, FromReflect, List, Reflect, ReflectMut, ReflectRef,
6-
};
4+
use crate::{Array, ArrayIter, FromReflect, List, Reflect, ReflectMut, ReflectRef};
75

86
impl<T: smallvec::Array + Send + Sync + 'static> Array for SmallVec<T>
97
where
@@ -100,17 +98,9 @@ where
10098
Box::new(List::clone_dynamic(self))
10199
}
102100

103-
fn reflect_hash(&self) -> Option<u64> {
104-
None
105-
}
106-
107101
fn reflect_partial_eq(&self, value: &dyn Reflect) -> Option<bool> {
108102
crate::list_partial_eq(self, value)
109103
}
110-
111-
fn serializable(&self) -> Option<Serializable> {
112-
None
113-
}
114104
}
115105

116106
impl<T: smallvec::Array + Send + Sync + 'static> FromReflect for SmallVec<T>

crates/bevy_reflect/src/impls/std.rs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -273,17 +273,9 @@ unsafe impl<K: Reflect + Eq + Hash, V: Reflect> Reflect for HashMap<K, V> {
273273
Box::new(self.clone_dynamic())
274274
}
275275

276-
fn reflect_hash(&self) -> Option<u64> {
277-
None
278-
}
279-
280276
fn reflect_partial_eq(&self, value: &dyn Reflect) -> Option<bool> {
281277
map_partial_eq(self, value)
282278
}
283-
284-
fn serializable(&self) -> Option<Serializable> {
285-
None
286-
}
287279
}
288280

289281
impl<K, V> GetTypeRegistration for HashMap<K, V>

crates/bevy_reflect/src/map.rs

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::any::Any;
22

33
use bevy_utils::{Entry, HashMap};
44

5-
use crate::{serde::Serializable, Reflect, ReflectMut, ReflectRef};
5+
use crate::{Reflect, ReflectMut, ReflectRef};
66

77
/// An ordered mapping between [`Reflect`] values.
88
///
@@ -186,17 +186,9 @@ unsafe impl Reflect for DynamicMap {
186186
Box::new(self.clone_dynamic())
187187
}
188188

189-
fn reflect_hash(&self) -> Option<u64> {
190-
None
191-
}
192-
193189
fn reflect_partial_eq(&self, value: &dyn Reflect) -> Option<bool> {
194190
map_partial_eq(self, value)
195191
}
196-
197-
fn serializable(&self) -> Option<Serializable> {
198-
None
199-
}
200192
}
201193

202194
/// An iterator over the key-value pairs of a [`Map`].

crates/bevy_reflect/src/reflect.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -130,17 +130,23 @@ pub unsafe trait Reflect: Any + Send + Sync {
130130
/// Returns a hash of the value (which includes the type).
131131
///
132132
/// If the underlying type does not support hashing, returns `None`.
133-
fn reflect_hash(&self) -> Option<u64>;
133+
fn reflect_hash(&self) -> Option<u64> {
134+
None
135+
}
134136

135137
/// Returns a "partial equality" comparison result.
136138
///
137139
/// If the underlying type does not support equality testing, returns `None`.
138-
fn reflect_partial_eq(&self, _value: &dyn Reflect) -> Option<bool>;
140+
fn reflect_partial_eq(&self, _value: &dyn Reflect) -> Option<bool> {
141+
None
142+
}
139143

140144
/// Returns a serializable version of the value.
141145
///
142146
/// If the underlying type does not support serialization, returns `None`.
143-
fn serializable(&self) -> Option<Serializable>;
147+
fn serializable(&self) -> Option<Serializable> {
148+
None
149+
}
144150
}
145151

146152
/// A trait for types which can be constructed from a reflected type.

crates/bevy_reflect/src/struct_trait.rs

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::{serde::Serializable, Reflect, ReflectMut, ReflectRef};
1+
use crate::{Reflect, ReflectMut, ReflectRef};
22
use bevy_utils::{Entry, HashMap};
33
use std::{any::Any, borrow::Cow};
44

@@ -312,17 +312,9 @@ unsafe impl Reflect for DynamicStruct {
312312
Ok(())
313313
}
314314

315-
fn reflect_hash(&self) -> Option<u64> {
316-
None
317-
}
318-
319315
fn reflect_partial_eq(&self, value: &dyn Reflect) -> Option<bool> {
320316
struct_partial_eq(self, value)
321317
}
322-
323-
fn serializable(&self) -> Option<Serializable> {
324-
None
325-
}
326318
}
327319

328320
/// Compares a [`Struct`] with a [`Reflect`] value.

crates/bevy_reflect/src/tuple.rs

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::{
2-
serde::Serializable, FromReflect, FromType, GetTypeRegistration, Reflect, ReflectDeserialize,
3-
ReflectMut, ReflectRef, TypeRegistration,
2+
FromReflect, FromType, GetTypeRegistration, Reflect, ReflectDeserialize, ReflectMut,
3+
ReflectRef, TypeRegistration,
44
};
55
use serde::Deserialize;
66
use std::any::Any;
@@ -259,17 +259,9 @@ unsafe impl Reflect for DynamicTuple {
259259
Ok(())
260260
}
261261

262-
fn reflect_hash(&self) -> Option<u64> {
263-
None
264-
}
265-
266262
fn reflect_partial_eq(&self, value: &dyn Reflect) -> Option<bool> {
267263
tuple_partial_eq(self, value)
268264
}
269-
270-
fn serializable(&self) -> Option<Serializable> {
271-
None
272-
}
273265
}
274266

275267
/// Applies the elements of `b` to the corresponding elements of `a`.
@@ -408,17 +400,9 @@ macro_rules! impl_reflect_tuple {
408400
Box::new(self.clone_dynamic())
409401
}
410402

411-
fn reflect_hash(&self) -> Option<u64> {
412-
None
413-
}
414-
415403
fn reflect_partial_eq(&self, value: &dyn Reflect) -> Option<bool> {
416404
crate::tuple_partial_eq(self, value)
417405
}
418-
419-
fn serializable(&self) -> Option<Serializable> {
420-
None
421-
}
422406
}
423407

424408
impl<$($name: Reflect + for<'de> Deserialize<'de>),*> GetTypeRegistration for ($($name,)*) {

0 commit comments

Comments
 (0)