Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ struct NoReflect(f32);
fn main() {
let mut foo: Box<dyn Struct> = Box::new(Foo::<NoReflect> { a: NoReflect(42.0) });
//~^ ERROR: `NoReflect` does not provide type registration information
//~| ERROR: `NoReflect` can not provide type information through reflection

// foo doesn't implement Reflect because NoReflect doesn't implement Reflect
foo.get_field::<NoReflect>("a").unwrap();
Expand Down
3 changes: 3 additions & 0 deletions crates/bevy_reflect/derive/src/utility.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,9 @@ impl<'a, 'b> WhereClauseOptions<'a, 'b> {
quote!(
#ty : #reflect_bound
+ #bevy_reflect_path::TypePath
// Needed for `Typed` impls
+ #bevy_reflect_path::MaybeTyped
// Needed for `GetTypeRegistration` impls
+ #bevy_reflect_path::__macro_exports::RegisterForReflection
)
}))
Expand Down
18 changes: 15 additions & 3 deletions crates/bevy_reflect/src/array.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::{
self as bevy_reflect, utility::reflect_hasher, ApplyError, Reflect, ReflectKind, ReflectMut,
ReflectOwned, ReflectRef, TypeInfo, TypePath, TypePathTable,
self as bevy_reflect, utility::reflect_hasher, ApplyError, MaybeTyped, Reflect, ReflectKind,
ReflectMut, ReflectOwned, ReflectRef, TypeInfo, TypePath, TypePathTable,
};
use bevy_reflect_derive::impl_type_path;
use std::{
Expand Down Expand Up @@ -79,6 +79,7 @@ pub trait Array: Reflect {
pub struct ArrayInfo {
type_path: TypePathTable,
type_id: TypeId,
item_info: fn() -> Option<&'static TypeInfo>,
item_type_path: TypePathTable,
item_type_id: TypeId,
capacity: usize,
Expand All @@ -93,10 +94,13 @@ impl ArrayInfo {
///
/// * `capacity`: The maximum capacity of the underlying array.
///
pub fn new<TArray: Array + TypePath, TItem: Reflect + TypePath>(capacity: usize) -> Self {
pub fn new<TArray: Array + TypePath, TItem: Reflect + MaybeTyped + TypePath>(
capacity: usize,
) -> Self {
Self {
type_path: TypePathTable::of::<TArray>(),
type_id: TypeId::of::<TArray>(),
item_info: TItem::maybe_type_info,
item_type_path: TypePathTable::of::<TItem>(),
item_type_id: TypeId::of::<TItem>(),
capacity,
Expand Down Expand Up @@ -143,6 +147,14 @@ impl ArrayInfo {
TypeId::of::<T>() == self.type_id
}

/// The [`TypeInfo`] of the array item.
///
/// Returns `None` if the array item does not contain static type information,
/// such as for dynamic types.
pub fn item_info(&self) -> Option<&'static TypeInfo> {
(self.item_info)()
}

/// A representation of the type path of the array item.
///
/// Provides dynamic access to all methods on [`TypePath`].
Expand Down
18 changes: 18 additions & 0 deletions crates/bevy_reflect/src/enums/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,18 @@ mod tests {
if let VariantInfo::Tuple(variant) = info.variant("B").unwrap() {
assert!(variant.field_at(0).unwrap().is::<usize>());
assert!(variant.field_at(1).unwrap().is::<i32>());
assert!(variant
.field_at(0)
.unwrap()
.type_info()
.unwrap()
.is::<usize>());
assert!(variant
.field_at(1)
.unwrap()
.type_info()
.unwrap()
.is::<i32>());
} else {
panic!("Expected `VariantInfo::Tuple`");
}
Expand All @@ -60,6 +72,12 @@ mod tests {
if let VariantInfo::Struct(variant) = info.variant("C").unwrap() {
assert!(variant.field_at(0).unwrap().is::<f32>());
assert!(variant.field("foo").unwrap().is::<f32>());
assert!(variant
.field("foo")
.unwrap()
.type_info()
.unwrap()
.is::<f32>());
} else {
panic!("Expected `VariantInfo::Struct`");
}
Expand Down
28 changes: 25 additions & 3 deletions crates/bevy_reflect/src/fields.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
use crate::attributes::{impl_custom_attribute_methods, CustomAttributes};
use crate::{Reflect, TypePath, TypePathTable};
use crate::{MaybeTyped, Reflect, TypeInfo, TypePath, TypePathTable};
use std::any::{Any, TypeId};
use std::sync::Arc;

/// The named field of a reflected struct.
#[derive(Clone, Debug)]
pub struct NamedField {
name: &'static str,
type_info: fn() -> Option<&'static TypeInfo>,
type_path: TypePathTable,
type_id: TypeId,
custom_attributes: Arc<CustomAttributes>,
Expand All @@ -16,9 +17,10 @@ pub struct NamedField {

impl NamedField {
/// Create a new [`NamedField`].
pub fn new<T: Reflect + TypePath>(name: &'static str) -> Self {
pub fn new<T: Reflect + MaybeTyped + TypePath>(name: &'static str) -> Self {
Self {
name,
type_info: T::maybe_type_info,
type_path: TypePathTable::of::<T>(),
type_id: TypeId::of::<T>(),
custom_attributes: Arc::new(CustomAttributes::default()),
Expand Down Expand Up @@ -46,6 +48,15 @@ impl NamedField {
self.name
}

/// The [`TypeInfo`] of the field.
///
///
/// Returns `None` if the field does not contain static type information,
/// such as for dynamic types.
pub fn type_info(&self) -> Option<&'static TypeInfo> {
(self.type_info)()
}

/// A representation of the type path of the field.
///
/// Provides dynamic access to all methods on [`TypePath`].
Expand Down Expand Up @@ -86,6 +97,7 @@ impl NamedField {
#[derive(Clone, Debug)]
pub struct UnnamedField {
index: usize,
type_info: fn() -> Option<&'static TypeInfo>,
type_path: TypePathTable,
type_id: TypeId,
custom_attributes: Arc<CustomAttributes>,
Expand All @@ -94,9 +106,10 @@ pub struct UnnamedField {
}

impl UnnamedField {
pub fn new<T: Reflect + TypePath>(index: usize) -> Self {
pub fn new<T: Reflect + MaybeTyped + TypePath>(index: usize) -> Self {
Self {
index,
type_info: T::maybe_type_info,
type_path: TypePathTable::of::<T>(),
type_id: TypeId::of::<T>(),
custom_attributes: Arc::new(CustomAttributes::default()),
Expand Down Expand Up @@ -124,6 +137,15 @@ impl UnnamedField {
self.index
}

/// The [`TypeInfo`] of the field.
///
///
/// Returns `None` if the field does not contain static type information,
/// such as for dynamic types.
pub fn type_info(&self) -> Option<&'static TypeInfo> {
(self.type_info)()
}

/// A representation of the type path of the field.
///
/// Provides dynamic access to all methods on [`TypePath`].
Expand Down
16 changes: 8 additions & 8 deletions crates/bevy_reflect/src/impls/smallvec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ use std::any::Any;
use crate::utility::GenericTypeInfoCell;
use crate::{
self as bevy_reflect, ApplyError, FromReflect, FromType, GetTypeRegistration, List, ListInfo,
ListIter, Reflect, ReflectFromPtr, ReflectKind, ReflectMut, ReflectOwned, ReflectRef, TypeInfo,
TypePath, TypeRegistration, Typed,
ListIter, MaybeTyped, Reflect, ReflectFromPtr, ReflectKind, ReflectMut, ReflectOwned,
ReflectRef, TypeInfo, TypePath, TypeRegistration, Typed,
};

impl<T: SmallArray + TypePath + Send + Sync> List for SmallVec<T>
where
T::Item: FromReflect + TypePath,
T::Item: FromReflect + MaybeTyped + TypePath,
{
fn get(&self, index: usize) -> Option<&dyn Reflect> {
if index < SmallVec::len(self) {
Expand Down Expand Up @@ -79,7 +79,7 @@ where

impl<T: SmallArray + TypePath + Send + Sync> Reflect for SmallVec<T>
where
T::Item: FromReflect + TypePath,
T::Item: FromReflect + MaybeTyped + TypePath,
{
fn get_represented_type_info(&self) -> Option<&'static TypeInfo> {
Some(<Self as Typed>::type_info())
Expand Down Expand Up @@ -149,7 +149,7 @@ where

impl<T: SmallArray + TypePath + Send + Sync + 'static> Typed for SmallVec<T>
where
T::Item: FromReflect + TypePath,
T::Item: FromReflect + MaybeTyped + TypePath,
{
fn type_info() -> &'static TypeInfo {
static CELL: GenericTypeInfoCell = GenericTypeInfoCell::new();
Expand All @@ -161,7 +161,7 @@ impl_type_path!(::smallvec::SmallVec<T: SmallArray>);

impl<T: SmallArray + TypePath + Send + Sync> FromReflect for SmallVec<T>
where
T::Item: FromReflect + TypePath,
T::Item: FromReflect + MaybeTyped + TypePath,
{
fn from_reflect(reflect: &dyn Reflect) -> Option<Self> {
if let ReflectRef::List(ref_list) = reflect.reflect_ref() {
Expand All @@ -178,7 +178,7 @@ where

impl<T: SmallArray + TypePath + Send + Sync> GetTypeRegistration for SmallVec<T>
where
T::Item: FromReflect + TypePath,
T::Item: FromReflect + MaybeTyped + TypePath,
{
fn get_type_registration() -> TypeRegistration {
let mut registration = TypeRegistration::of::<SmallVec<T>>();
Expand All @@ -188,4 +188,4 @@ where
}

#[cfg(feature = "functions")]
crate::func::macros::impl_function_traits!(SmallVec<T>; <T: SmallArray + TypePath + Send + Sync> where T::Item: FromReflect + TypePath);
crate::func::macros::impl_function_traits!(SmallVec<T>; <T: SmallArray + TypePath + Send + Sync> where T::Item: FromReflect + MaybeTyped + TypePath);
Loading