Skip to content

Commit 1e7cbd8

Browse files
committed
Use TypeInfo to default trait methods
1 parent e87c24b commit 1e7cbd8

File tree

4 files changed

+121
-64
lines changed

4 files changed

+121
-64
lines changed

crates/bevy_reflect/bevy_reflect_derive/src/impls.rs

+5-38
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,6 @@ pub(crate) fn impl_struct(derive_data: &ReflectDeriveData) -> TokenStream {
3636
.active_fields()
3737
.map(|field| field.data.ty.clone())
3838
.collect::<Vec<_>>();
39-
let field_count = field_idents.len();
40-
let field_indices = (0..field_count).collect::<Vec<usize>>();
4139

4240
let hash_fn = derive_data.traits().get_hash_impl(bevy_reflect_path);
4341
let serialize_fn = derive_data.traits().get_serialize_impl(bevy_reflect_path);
@@ -57,7 +55,7 @@ pub(crate) fn impl_struct(derive_data: &ReflectDeriveData) -> TokenStream {
5755
struct_name,
5856
derive_data.generics(),
5957
quote! {
60-
let fields: [#bevy_reflect_path::NamedField; #field_count] = [
58+
let fields = [
6159
#(#bevy_reflect_path::NamedField::new::<#field_types, _>(#field_names),)*
6260
];
6361
let info = #bevy_reflect_path::StructInfo::new::<Self>(&fields);
@@ -89,31 +87,6 @@ pub(crate) fn impl_struct(derive_data: &ReflectDeriveData) -> TokenStream {
8987
}
9088
}
9189

92-
fn field_at(&self, index: usize) -> Option<&dyn #bevy_reflect_path::Reflect> {
93-
match index {
94-
#(#field_indices => Some(&self.#field_idents),)*
95-
_ => None,
96-
}
97-
}
98-
99-
fn field_at_mut(&mut self, index: usize) -> Option<&mut dyn #bevy_reflect_path::Reflect> {
100-
match index {
101-
#(#field_indices => Some(&mut self.#field_idents),)*
102-
_ => None,
103-
}
104-
}
105-
106-
fn name_at(&self, index: usize) -> Option<&str> {
107-
match index {
108-
#(#field_indices => Some(#field_names),)*
109-
_ => None,
110-
}
111-
}
112-
113-
fn field_len(&self) -> usize {
114-
#field_count
115-
}
116-
11790
fn iter_fields(&self) -> #bevy_reflect_path::FieldIter {
11891
#bevy_reflect_path::FieldIter::new(self)
11992
}
@@ -212,8 +185,6 @@ pub(crate) fn impl_tuple_struct(derive_data: &ReflectDeriveData) -> TokenStream
212185
.active_fields()
213186
.map(|field| field.data.ty.clone())
214187
.collect::<Vec<_>>();
215-
let field_count = field_idents.len();
216-
let field_indices = (0..field_count).collect::<Vec<usize>>();
217188

218189
let hash_fn = derive_data.traits().get_hash_impl(bevy_reflect_path);
219190
let serialize_fn = derive_data.traits().get_serialize_impl(bevy_reflect_path);
@@ -233,8 +204,8 @@ pub(crate) fn impl_tuple_struct(derive_data: &ReflectDeriveData) -> TokenStream
233204
struct_name,
234205
derive_data.generics(),
235206
quote! {
236-
let fields: [#bevy_reflect_path::UnnamedField; #field_count] = [
237-
#(#bevy_reflect_path::UnnamedField::new::<#field_types>(#field_indices),)*
207+
let fields = [
208+
#(#bevy_reflect_path::UnnamedField::new::<#field_types>(#field_idents),)*
238209
];
239210
let info = #bevy_reflect_path::TupleStructInfo::new::<Self>(&fields);
240211
#bevy_reflect_path::TypeInfo::TupleStruct(info)
@@ -251,22 +222,18 @@ pub(crate) fn impl_tuple_struct(derive_data: &ReflectDeriveData) -> TokenStream
251222
impl #impl_generics #bevy_reflect_path::TupleStruct for #struct_name #ty_generics #where_clause {
252223
fn field(&self, index: usize) -> Option<&dyn #bevy_reflect_path::Reflect> {
253224
match index {
254-
#(#field_indices => Some(&self.#field_idents),)*
225+
#(#field_idents => Some(&self.#field_idents),)*
255226
_ => None,
256227
}
257228
}
258229

259230
fn field_mut(&mut self, index: usize) -> Option<&mut dyn #bevy_reflect_path::Reflect> {
260231
match index {
261-
#(#field_indices => Some(&mut self.#field_idents),)*
232+
#(#field_idents => Some(&mut self.#field_idents),)*
262233
_ => None,
263234
}
264235
}
265236

266-
fn field_len(&self) -> usize {
267-
#field_count
268-
}
269-
270237
fn iter_fields(&self) -> #bevy_reflect_path::TupleStructFieldIter {
271238
#bevy_reflect_path::TupleStructFieldIter::new(self)
272239
}

crates/bevy_reflect/src/struct_trait.rs

+81-14
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use crate::utility::TypeInfoCell;
22
use crate::{DynamicInfo, NamedField, Reflect, ReflectMut, ReflectRef, TypeInfo, Typed};
33
use bevy_utils::{Entry, HashMap};
4+
use std::borrow::Borrow;
45
use std::fmt::{Debug, Formatter};
56
use std::{
67
any::{Any, TypeId},
@@ -45,25 +46,91 @@ pub trait Struct: Reflect {
4546
/// `&mut dyn Reflect`.
4647
fn field_mut(&mut self, name: &str) -> Option<&mut dyn Reflect>;
4748

48-
/// Returns a reference to the value of the field with index `index` as a
49-
/// `&dyn Reflect`.
50-
fn field_at(&self, index: usize) -> Option<&dyn Reflect>;
51-
52-
/// Returns a mutable reference to the value of the field with index `index`
53-
/// as a `&mut dyn Reflect`.
54-
fn field_at_mut(&mut self, index: usize) -> Option<&mut dyn Reflect>;
55-
56-
/// Returns the name of the field with index `index`.
57-
fn name_at(&self, index: usize) -> Option<&str>;
58-
59-
/// Returns the number of fields in the struct.
60-
fn field_len(&self) -> usize;
61-
6249
/// Returns an iterator over the values of the struct's fields.
6350
fn iter_fields(&self) -> FieldIter;
6451

6552
/// Clones the struct into a [`DynamicStruct`].
6653
fn clone_dynamic(&self) -> DynamicStruct;
54+
55+
/// Returns the number of fields in the struct.
56+
///
57+
/// # Panics
58+
///
59+
/// Panics if the [`TypeInfo`] returned by [`Reflect::get_type_info()`] is not
60+
/// [`TypeInfo::Struct`]— which should almost never be the case. Notable exceptions
61+
/// include [`DynamicStruct`] which uses its own implementation of this method to
62+
/// prevent the panic.
63+
fn field_len(&self) -> usize {
64+
if let TypeInfo::Struct(info) = self.get_type_info() {
65+
info.field_len()
66+
} else {
67+
panic!(
68+
"tuple `{:?}` is not `TypeInfo::Struct`",
69+
std::any::type_name::<Self>()
70+
);
71+
}
72+
}
73+
74+
/// Returns the name of the field with index `index`.
75+
///
76+
/// # Panics
77+
///
78+
/// Panics if the [`TypeInfo`] returned by [`Reflect::get_type_info()`] is not
79+
/// [`TypeInfo::Struct`]— which should almost never be the case. Notable exceptions
80+
/// include [`DynamicStruct`] which uses its own implementation of this method to
81+
/// prevent the panic.
82+
fn name_at(&self, index: usize) -> Option<&str> {
83+
if let TypeInfo::Struct(info) = self.get_type_info() {
84+
info.field_at(index).map(|field| field.name().borrow())
85+
} else {
86+
panic!(
87+
"tuple `{:?}` is not `TypeInfo::Struct`",
88+
std::any::type_name::<Self>()
89+
);
90+
}
91+
}
92+
93+
/// Returns a reference to the value of the field with index `index` as a
94+
/// `&dyn Reflect`.
95+
///
96+
/// # Panics
97+
///
98+
/// Panics if the [`TypeInfo`] returned by [`Reflect::get_type_info()`] is not
99+
/// [`TypeInfo::Struct`]— which should almost never be the case. Notable exceptions
100+
/// include [`DynamicStruct`] which uses its own implementation of this method to
101+
/// prevent the panic.
102+
fn field_at(&self, index: usize) -> Option<&dyn Reflect> {
103+
if let TypeInfo::Struct(info) = self.get_type_info() {
104+
let name = info.field_at(index)?.name();
105+
self.field(name)
106+
} else {
107+
panic!(
108+
"tuple `{:?}` is not `TypeInfo::Struct`",
109+
std::any::type_name::<Self>()
110+
);
111+
}
112+
}
113+
114+
/// Returns a mutable reference to the value of the field with index `index`
115+
/// as a `&mut dyn Reflect`.
116+
///
117+
/// # Panics
118+
///
119+
/// Panics if the [`TypeInfo`] returned by [`Reflect::get_type_info()`] is not
120+
/// [`TypeInfo::Struct`]— which should almost never be the case. Notable exceptions
121+
/// include [`DynamicStruct`] which uses its own implementation of this method to
122+
/// prevent the panic.
123+
fn field_at_mut(&mut self, index: usize) -> Option<&mut dyn Reflect> {
124+
if let TypeInfo::Struct(info) = self.get_type_info() {
125+
let name = info.field_at(index)?.name();
126+
self.field_mut(name)
127+
} else {
128+
panic!(
129+
"tuple `{:?}` is not `TypeInfo::Struct`",
130+
std::any::type_name::<Self>()
131+
);
132+
}
133+
}
67134
}
68135

69136
/// A container for compile-time struct info

crates/bevy_reflect/src/tuple.rs

+19-9
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,30 @@ pub trait Tuple: Reflect {
3535
/// as a `&mut dyn Reflect`.
3636
fn field_mut(&mut self, index: usize) -> Option<&mut dyn Reflect>;
3737

38-
/// Returns the number of fields in the tuple.
39-
fn field_len(&self) -> usize;
40-
4138
/// Returns an iterator over the values of the tuple's fields.
4239
fn iter_fields(&self) -> TupleFieldIter;
4340

4441
/// Clones the struct into a [`DynamicTuple`].
4542
fn clone_dynamic(&self) -> DynamicTuple;
43+
44+
/// Returns the number of fields in the tuple.
45+
///
46+
/// # Panics
47+
///
48+
/// Panics if the [`TypeInfo`] returned by [`Reflect::get_type_info()`] is not
49+
/// [`TypeInfo::Tuple`]— which should almost never be the case. Notable exceptions
50+
/// include [`DynamicTuple`] which uses its own implementation of this method to
51+
/// prevent the panic.
52+
fn field_len(&self) -> usize {
53+
if let TypeInfo::Tuple(info) = self.get_type_info() {
54+
info.field_len()
55+
} else {
56+
panic!(
57+
"tuple `{:?}` is not `TypeInfo::Tuple`",
58+
std::any::type_name::<Self>()
59+
);
60+
}
61+
}
4662
}
4763

4864
/// An iterator over the field values of a tuple.
@@ -432,12 +448,6 @@ macro_rules! impl_reflect_tuple {
432448
}
433449
}
434450

435-
#[inline]
436-
fn field_len(&self) -> usize {
437-
let indices: &[usize] = &[$($index as usize),*];
438-
indices.len()
439-
}
440-
441451
#[inline]
442452
fn iter_fields(&self) -> TupleFieldIter {
443453
TupleFieldIter {

crates/bevy_reflect/src/tuple_struct.rs

+16-3
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,27 @@ pub trait TupleStruct: Reflect {
3636
/// as a `&mut dyn Reflect`.
3737
fn field_mut(&mut self, index: usize) -> Option<&mut dyn Reflect>;
3838

39-
/// Returns the number of fields in the tuple struct.
40-
fn field_len(&self) -> usize;
41-
4239
/// Returns an iterator over the values of the tuple struct's fields.
4340
fn iter_fields(&self) -> TupleStructFieldIter;
4441

4542
/// Clones the struct into a [`DynamicTupleStruct`].
4643
fn clone_dynamic(&self) -> DynamicTupleStruct;
44+
45+
/// Returns the number of fields in the tuple struct.
46+
///
47+
/// # Panics
48+
///
49+
/// Panics if the [`TypeInfo`] returned by [`Reflect::get_type_info()`] is not
50+
/// [`TypeInfo::TupleStruct`]— which should almost never be the case. Notable exceptions
51+
/// include [`DynamicTupleStruct`] which uses its own implementation of this method to
52+
/// prevent the panic.
53+
fn field_len(&self) -> usize {
54+
if let TypeInfo::TupleStruct(info) = self.get_type_info() {
55+
info.field_len()
56+
} else {
57+
0
58+
}
59+
}
4760
}
4861

4962
/// A container for compile-time tuple struct info

0 commit comments

Comments
 (0)