Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Merged by Bors] - bevy_reflect: Add statically available type info for reflected types #4042

Closed
wants to merge 53 commits into from
Closed
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
ed5e997
Added TypeInfo
MrGVSV Feb 26, 2022
bfcfa25
Added tests
MrGVSV Feb 26, 2022
190dbc2
Fix clippy warnings
MrGVSV Feb 26, 2022
ea49152
Formatting
MrGVSV Feb 26, 2022
0ec2270
Apply suggestions from code review
MrGVSV Feb 26, 2022
b0dfaa9
Added relevant TypeIds to info structs
MrGVSV Feb 27, 2022
23e276a
Formatting
MrGVSV Feb 27, 2022
83c5e6e
Added convenience methods to TypeInfo
MrGVSV Feb 27, 2022
81c1298
Added Typed trait
MrGVSV Mar 5, 2022
8ad235c
Formatting
MrGVSV Mar 5, 2022
e9f39cf
Impl Typed for dyn Reflect
MrGVSV Mar 5, 2022
ad786ad
Formatting
MrGVSV Mar 5, 2022
a5ca84d
Replaced Cow<'static, str> with &'static str
MrGVSV Mar 5, 2022
f8e57a9
Store fields as Box<[T]>
MrGVSV Mar 5, 2022
fea5343
Added documentation for DynamicInfo
MrGVSV Mar 5, 2022
091e5e8
Added TypeIdentity
MrGVSV Mar 5, 2022
8cf5029
Integrated TypeIdentity across type info structs
MrGVSV Mar 5, 2022
9cbaf28
Fixed doc error
MrGVSV Mar 6, 2022
f6cbb1d
Remove duplicated data
MrGVSV Mar 8, 2022
55e023b
Removed unnecessary methods
MrGVSV Mar 8, 2022
000c327
Clarify comments
MrGVSV Mar 8, 2022
097b1f2
Added static_new method to create field with static str
MrGVSV Mar 8, 2022
d1ddb1f
Use the cow
MrGVSV Mar 8, 2022
4fcc07f
Merge branch 'main' into reflect-type-info
MrGVSV Apr 27, 2022
1f89001
Merge branch 'main' into reflect-type-info
MrGVSV May 9, 2022
018a125
Merge branch 'main' into reflect-type-info
MrGVSV May 11, 2022
8d93a67
Merge branch 'main' into reflect-type-info
MrGVSV May 13, 2022
be284d6
Merge branch 'reflect-type-info' of https://github.com/MrGVSV/bevy in…
MrGVSV May 13, 2022
ab8d022
Resolve merge conflict
MrGVSV May 13, 2022
9a41c85
Formatting
MrGVSV May 13, 2022
16d3ab6
Fix doc wording
MrGVSV May 13, 2022
ea9d34b
Add Reflect::get_type_info
MrGVSV May 18, 2022
d2f8f9f
Merge branch 'main' into reflect-type-info
MrGVSV May 18, 2022
5544557
Renamed name -> type_name
MrGVSV May 18, 2022
5d97ea5
Formatting
MrGVSV May 18, 2022
43dda0a
Remove unused import
MrGVSV May 18, 2022
51e1214
Removed TypeIdentity
MrGVSV May 25, 2022
4c0040a
Change doc wording
MrGVSV May 25, 2022
c3c54cb
Combine constructors
MrGVSV May 25, 2022
a877911
Return static TypeInfo from Typed::type_info()
MrGVSV May 26, 2022
63c284f
Remove extraneous import
MrGVSV May 26, 2022
aa5178e
Fix clippy warnings
MrGVSV May 27, 2022
c18cf5c
Merge branch 'main' into reflect-type-info
MrGVSV May 30, 2022
e87c24b
Fix incorrect non-generic TypeInfoCell
MrGVSV May 30, 2022
1e7cbd8
Use TypeInfo to default trait methods
MrGVSV May 30, 2022
87f1069
Merge branch 'main' into reflect-type-info
MrGVSV May 30, 2022
ee38b76
Improve docs
MrGVSV Jun 4, 2022
f8b4d07
Remove ListInfo capacity
MrGVSV Jun 4, 2022
38b2611
Replace list capacity references
MrGVSV Jun 4, 2022
16b7938
Revert "Use TypeInfo to default trait methods"
MrGVSV Jun 9, 2022
c0495e5
Split up TypeInfoCell
MrGVSV Jun 9, 2022
0fc6b64
Change wording in docs
MrGVSV Jun 9, 2022
6ddb85a
Merge remote-tracking branch 'origin/main' into pr/MrGVSV/4042-1
cart Jun 9, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 38 additions & 3 deletions crates/bevy_reflect/bevy_reflect_derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,10 @@ fn impl_struct(
.unwrap_or_else(|| Member::Unnamed(Index::from(*index)))
})
.collect::<Vec<_>>();
let field_types = active_fields
.iter()
.map(|(field, _index)| field.ty.clone())
.collect::<Vec<_>>();
let field_count = active_fields.len();
let field_indices = (0..field_count).collect::<Vec<usize>>();

Expand Down Expand Up @@ -318,6 +322,16 @@ fn impl_struct(
#partial_eq_fn
}
}

impl #impl_generics #bevy_reflect_path::Typed for #struct_name #ty_generics #where_clause {
fn type_info() -> #bevy_reflect_path::TypeInfo {
let fields: [#bevy_reflect_path::NamedField; #field_count] = [
MrGVSV marked this conversation as resolved.
Show resolved Hide resolved
#(#bevy_reflect_path::NamedField::static_new::<#field_types>(#field_names),)*
];
let info = #bevy_reflect_path::StructInfo::new::<Self>(&fields);
#bevy_reflect_path::TypeInfo::Struct(info)
}
}
})
}

Expand All @@ -333,6 +347,10 @@ fn impl_tuple_struct(
.iter()
.map(|(_field, index)| Member::Unnamed(Index::from(*index)))
.collect::<Vec<_>>();
let field_types = active_fields
.iter()
.map(|(field, _index)| field.ty.clone())
.collect::<Vec<_>>();
let field_count = active_fields.len();
let field_indices = (0..field_count).collect::<Vec<usize>>();

Expand All @@ -346,11 +364,11 @@ fn impl_tuple_struct(
TraitImpl::Implemented | TraitImpl::Custom(_) => reflect_attrs.get_partial_eq_impl(),
};

let (impl_generics, ty_generics, _where_clause) = generics.split_for_impl();
let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
MrGVSV marked this conversation as resolved.
Show resolved Hide resolved
TokenStream::from(quote! {
#get_type_registration_impl

impl #impl_generics #bevy_reflect_path::TupleStruct for #struct_name #ty_generics {
impl #impl_generics #bevy_reflect_path::TupleStruct for #struct_name #ty_generics #where_clause {
fn field(&self, index: usize) -> Option<&dyn #bevy_reflect_path::Reflect> {
match index {
#(#field_indices => Some(&self.#field_idents),)*
Expand Down Expand Up @@ -382,7 +400,7 @@ fn impl_tuple_struct(
}

// SAFE: any and any_mut both return self
unsafe impl #impl_generics #bevy_reflect_path::Reflect for #struct_name #ty_generics {
unsafe impl #impl_generics #bevy_reflect_path::Reflect for #struct_name #ty_generics #where_clause {
#[inline]
fn type_name(&self) -> &str {
std::any::type_name::<Self>()
Expand Down Expand Up @@ -439,6 +457,16 @@ fn impl_tuple_struct(
#partial_eq_fn
}
}

impl #impl_generics #bevy_reflect_path::Typed for #struct_name #ty_generics #where_clause {
fn type_info() -> #bevy_reflect_path::TypeInfo {
let fields: [#bevy_reflect_path::UnnamedField; #field_count] = [
#(#bevy_reflect_path::UnnamedField::new::<#field_types>(#field_indices),)*
];
let info = #bevy_reflect_path::TupleStructInfo::new::<Self>(&fields);
#bevy_reflect_path::TypeInfo::TupleStruct(info)
}
}
})
}

Expand Down Expand Up @@ -515,6 +543,13 @@ fn impl_value(
#serialize_fn
}
}

impl #impl_generics #bevy_reflect_path::Typed for #type_name #ty_generics #where_clause {
fn type_info() -> #bevy_reflect_path::TypeInfo {
let info = #bevy_reflect_path::ValueInfo::new::<Self>();
#bevy_reflect_path::TypeInfo::Value(info)
}
}
})
}
struct ReflectDef {
Expand Down
66 changes: 66 additions & 0 deletions crates/bevy_reflect/src/fields.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
use crate::{Reflect, TypeIdentity};
use std::borrow::Cow;

/// The named field of a reflected struct
#[derive(Clone, Debug)]
pub struct NamedField {
name: Cow<'static, str>,
id: TypeIdentity,
}

impl NamedField {
/// Create a new [`NamedField`]
pub fn new<T: Reflect>(name: &str) -> Self {
MrGVSV marked this conversation as resolved.
Show resolved Hide resolved
Self {
name: Cow::Owned(name.into()),
id: TypeIdentity::of::<T>(),
}
}

/// Create a new [`NamedField`] using a static string
///
/// This helps save an allocation when the string has a static lifetime, such
/// as when using [`std::any::type_name`].
pub fn static_new<T: Reflect>(name: &'static str) -> Self {
MrGVSV marked this conversation as resolved.
Show resolved Hide resolved
Self {
name: Cow::Borrowed(name),
id: TypeIdentity::of::<T>(),
}
}

/// The name of the field
pub fn name(&self) -> &Cow<'static, str> {
&self.name
}

/// The [`TypeIdentity`] of the field
pub fn id(&self) -> &TypeIdentity {
&self.id
}
}

/// The unnamed field of a reflected tuple or tuple struct
#[derive(Clone, Debug)]
pub struct UnnamedField {
index: usize,
id: TypeIdentity,
}

impl UnnamedField {
pub fn new<T: Reflect>(index: usize) -> Self {
Self {
index,
id: TypeIdentity::of::<T>(),
}
}

/// Returns the index of the field
pub fn index(&self) -> usize {
self.index
}

/// The [`TypeIdentity`] of the field
pub fn id(&self) -> &TypeIdentity {
&self.id
}
}
14 changes: 13 additions & 1 deletion crates/bevy_reflect/src/impls/smallvec.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
use smallvec::{Array, SmallVec};
use std::any::Any;

use crate::{serde::Serializable, FromReflect, List, ListIter, Reflect, ReflectMut, ReflectRef};
use crate::{
serde::Serializable, FromReflect, List, ListInfo, ListIter, Reflect, ReflectMut, ReflectRef,
TypeInfo, Typed,
};

impl<T: Array + Send + Sync + 'static> List for SmallVec<T>
where
Expand Down Expand Up @@ -98,6 +101,15 @@ where
}
}

impl<T: Array + Send + Sync + 'static> Typed for SmallVec<T>
where
T::Item: FromReflect + Clone,
{
fn type_info() -> TypeInfo {
TypeInfo::List(ListInfo::new::<Self, T::Item>(Some(T::size())))
}
}

impl<T: Array + Send + Sync + 'static> FromReflect for SmallVec<T>
where
T::Item: FromReflect + Clone,
Expand Down
22 changes: 20 additions & 2 deletions crates/bevy_reflect/src/impls/std.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use crate as bevy_reflect;
use crate::{
map_partial_eq, serde::Serializable, DynamicMap, FromReflect, FromType, GetTypeRegistration,
List, ListIter, Map, MapIter, Reflect, ReflectDeserialize, ReflectMut, ReflectRef,
TypeRegistration,
List, ListInfo, ListIter, Map, MapInfo, MapIter, Reflect, ReflectDeserialize, ReflectMut,
ReflectRef, TypeInfo, TypeRegistration, Typed, ValueInfo,
};

use bevy_reflect_derive::{impl_from_reflect_value, impl_reflect_value};
Expand Down Expand Up @@ -144,6 +144,12 @@ unsafe impl<T: FromReflect> Reflect for Vec<T> {
}
}

impl<T: FromReflect> Typed for Vec<T> {
fn type_info() -> TypeInfo {
TypeInfo::List(ListInfo::new::<Self, T>(None))
}
}

impl<T: FromReflect + for<'de> Deserialize<'de>> GetTypeRegistration for Vec<T> {
fn get_type_registration() -> TypeRegistration {
let mut registration = TypeRegistration::of::<Vec<T>>();
Expand Down Expand Up @@ -262,6 +268,12 @@ unsafe impl<K: Reflect + Eq + Hash, V: Reflect> Reflect for HashMap<K, V> {
}
}

impl<K: Reflect + Eq + Hash, V: Reflect> Typed for HashMap<K, V> {
fn type_info() -> TypeInfo {
TypeInfo::Map(MapInfo::new::<Self, K, V>())
}
}

impl<K, V> GetTypeRegistration for HashMap<K, V>
where
K: Reflect + Clone + Eq + Hash + for<'de> Deserialize<'de>,
Expand Down Expand Up @@ -351,6 +363,12 @@ unsafe impl Reflect for Cow<'static, str> {
}
}

impl Typed for Cow<'static, str> {
fn type_info() -> TypeInfo {
TypeInfo::Value(ValueInfo::new::<Self>())
}
}

impl GetTypeRegistration for Cow<'static, str> {
fn get_type_registration() -> TypeRegistration {
let mut registration = TypeRegistration::of::<Cow<'static, str>>();
Expand Down
Loading