Add ReflectKind (#11664)

# Objective

Fix https://github.com/bevyengine/bevy/issues/11657

## Solution

Add a `ReflectKind` enum, add `Reflect::reflect_kind` which returns a
`ReflectKind`, and add `kind` method implementions to `ReflectRef`,
`ReflectMut`, and `ReflectOwned`, which returns a `ReflectKind`.

I also changed `AccessError` to use this new struct instead of it's own
`TypeKind` struct.

---

## Changelog

- Added `ReflectKind`, an enumeration over the kinds of a reflected type
without its data.
- Added `Reflect::reflect_kind` (with default implementation)
- Added implementation for the `kind` method on `ReflectRef`,
`ReflectMut`, and `ReflectOwned` which gives their kind without any
information, as a `ReflectKind`
This commit is contained in:
Doonv 2024-02-07 02:36:23 +02:00 committed by GitHub
parent 4c86ad6aed
commit 054134fba2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
20 changed files with 224 additions and 129 deletions

View File

@ -2,8 +2,8 @@ use crate::io::AssetSourceId;
use bevy_reflect::{
std_traits::ReflectDefault, utility::NonGenericTypeInfoCell, FromReflect, FromType,
GetTypeRegistration, Reflect, ReflectDeserialize, ReflectFromPtr, ReflectFromReflect,
ReflectMut, ReflectOwned, ReflectRef, ReflectSerialize, TypeInfo, TypePath, TypeRegistration,
Typed, ValueInfo,
ReflectKind, ReflectMut, ReflectOwned, ReflectRef, ReflectSerialize, TypeInfo, TypePath,
TypeRegistration, Typed, ValueInfo,
};
use bevy_utils::CowArc;
use serde::{de::Visitor, Deserialize, Serialize};
@ -681,6 +681,9 @@ impl Reflect for AssetPath<'static> {
*self = <dyn bevy_reflect::Reflect>::take(value)?;
Ok(())
}
fn reflect_kind(&self) -> ReflectKind {
ReflectKind::Value
}
fn reflect_ref(&self) -> ReflectRef {
ReflectRef::Value(self)
}

View File

@ -264,6 +264,10 @@ pub(crate) fn impl_enum(reflect_enum: &ReflectEnum) -> proc_macro2::TokenStream
}
}
fn reflect_kind(&self) -> #bevy_reflect_path::ReflectKind {
#bevy_reflect_path::ReflectKind::Enum
}
fn reflect_ref(&self) -> #bevy_reflect_path::ReflectRef {
#bevy_reflect_path::ReflectRef::Enum(self)
}

View File

@ -219,6 +219,10 @@ pub(crate) fn impl_struct(reflect_struct: &ReflectStruct) -> proc_macro2::TokenS
}
}
fn reflect_kind(&self) -> #bevy_reflect_path::ReflectKind {
#bevy_reflect_path::ReflectKind::Struct
}
fn reflect_ref(&self) -> #bevy_reflect_path::ReflectRef {
#bevy_reflect_path::ReflectRef::Struct(self)
}

View File

@ -187,6 +187,10 @@ pub(crate) fn impl_tuple_struct(reflect_struct: &ReflectStruct) -> proc_macro2::
}
}
fn reflect_kind(&self) -> #bevy_reflect_path::ReflectKind {
#bevy_reflect_path::ReflectKind::TupleStruct
}
fn reflect_ref(&self) -> #bevy_reflect_path::ReflectRef {
#bevy_reflect_path::ReflectRef::TupleStruct(self)
}

View File

@ -101,6 +101,10 @@ pub(crate) fn impl_value(meta: &ReflectMeta) -> proc_macro2::TokenStream {
#FQResult::Ok(())
}
fn reflect_kind(&self) -> #bevy_reflect_path::ReflectKind {
#bevy_reflect_path::ReflectKind::Value
}
fn reflect_ref(&self) -> #bevy_reflect_path::ReflectRef {
#bevy_reflect_path::ReflectRef::Value(self)
}

View File

@ -1,6 +1,6 @@
use crate::{
self as bevy_reflect, utility::reflect_hasher, Reflect, ReflectMut, ReflectOwned, ReflectRef,
TypeInfo, TypePath, TypePathTable,
self as bevy_reflect, utility::reflect_hasher, Reflect, ReflectKind, ReflectMut, ReflectOwned,
ReflectRef, TypeInfo, TypePath, TypePathTable,
};
use bevy_reflect_derive::impl_type_path;
use std::{
@ -268,6 +268,11 @@ impl Reflect for DynamicArray {
Ok(())
}
#[inline]
fn reflect_kind(&self) -> ReflectKind {
ReflectKind::Array
}
#[inline]
fn reflect_ref(&self) -> ReflectRef {
ReflectRef::Array(self)

View File

@ -2,8 +2,8 @@ use bevy_reflect_derive::impl_type_path;
use crate::{
self as bevy_reflect, enum_debug, enum_hash, enum_partial_eq, DynamicStruct, DynamicTuple,
Enum, Reflect, ReflectMut, ReflectOwned, ReflectRef, Struct, Tuple, TypeInfo, VariantFieldIter,
VariantType,
Enum, Reflect, ReflectKind, ReflectMut, ReflectOwned, ReflectRef, Struct, Tuple, TypeInfo,
VariantFieldIter, VariantType,
};
use std::any::Any;
use std::fmt::Formatter;
@ -379,6 +379,11 @@ impl Reflect for DynamicEnum {
Ok(())
}
#[inline]
fn reflect_kind(&self) -> ReflectKind {
ReflectKind::Enum
}
#[inline]
fn reflect_ref(&self) -> ReflectRef {
ReflectRef::Enum(self)

View File

@ -7,7 +7,7 @@ use std::any::Any;
use crate::utility::GenericTypeInfoCell;
use crate::{
self as bevy_reflect, FromReflect, FromType, GetTypeRegistration, List, ListInfo, ListIter,
Reflect, ReflectFromPtr, ReflectMut, ReflectOwned, ReflectRef, TypeInfo, TypePath,
Reflect, ReflectFromPtr, ReflectKind, ReflectMut, ReflectOwned, ReflectRef, TypeInfo, TypePath,
TypeRegistration, Typed,
};
@ -119,6 +119,10 @@ where
Ok(())
}
fn reflect_kind(&self) -> ReflectKind {
ReflectKind::List
}
fn reflect_ref(&self) -> ReflectRef {
ReflectRef::List(self)
}

View File

@ -3,8 +3,8 @@ use crate::{self as bevy_reflect, ReflectFromPtr, ReflectFromReflect, ReflectOwn
use crate::{
impl_type_path, map_apply, map_partial_eq, Array, ArrayInfo, ArrayIter, DynamicEnum,
DynamicMap, Enum, EnumInfo, FromReflect, FromType, GetTypeRegistration, List, ListInfo,
ListIter, Map, MapInfo, MapIter, Reflect, ReflectDeserialize, ReflectMut, ReflectRef,
ReflectSerialize, TupleVariantInfo, TypeInfo, TypePath, TypeRegistration, Typed,
ListIter, Map, MapInfo, MapIter, Reflect, ReflectDeserialize, ReflectKind, ReflectMut,
ReflectRef, ReflectSerialize, TupleVariantInfo, TypeInfo, TypePath, TypeRegistration, Typed,
UnitVariantInfo, UnnamedField, ValueInfo, VariantFieldIter, VariantInfo, VariantType,
};
@ -317,6 +317,10 @@ macro_rules! impl_reflect_for_veclike {
Ok(())
}
fn reflect_kind(&self) -> ReflectKind {
ReflectKind::List
}
fn reflect_ref(&self) -> ReflectRef {
ReflectRef::List(self)
}
@ -535,6 +539,10 @@ macro_rules! impl_reflect_for_hashmap {
Ok(())
}
fn reflect_kind(&self) -> ReflectKind {
ReflectKind::Map
}
fn reflect_ref(&self) -> ReflectRef {
ReflectRef::Map(self)
}
@ -687,6 +695,11 @@ impl<T: Reflect + TypePath, const N: usize> Reflect for [T; N] {
Ok(())
}
#[inline]
fn reflect_kind(&self) -> ReflectKind {
ReflectKind::Array
}
#[inline]
fn reflect_ref(&self) -> ReflectRef {
ReflectRef::Array(self)
@ -935,6 +948,10 @@ impl<T: FromReflect + TypePath> Reflect for Option<T> {
Ok(())
}
fn reflect_kind(&self) -> ReflectKind {
ReflectKind::Enum
}
fn reflect_ref(&self) -> ReflectRef {
ReflectRef::Enum(self)
}
@ -1080,6 +1097,10 @@ impl Reflect for Cow<'static, str> {
Ok(())
}
fn reflect_kind(&self) -> ReflectKind {
ReflectKind::Value
}
fn reflect_ref(&self) -> ReflectRef {
ReflectRef::Value(self)
}
@ -1257,6 +1278,10 @@ impl<T: FromReflect + Clone + TypePath> Reflect for Cow<'static, [T]> {
Ok(())
}
fn reflect_kind(&self) -> ReflectKind {
ReflectKind::List
}
fn reflect_ref(&self) -> ReflectRef {
ReflectRef::List(self)
}
@ -1454,6 +1479,10 @@ impl Reflect for &'static Path {
Ok(())
}
fn reflect_kind(&self) -> ReflectKind {
ReflectKind::Value
}
fn reflect_ref(&self) -> ReflectRef {
ReflectRef::Value(self)
}
@ -1551,6 +1580,10 @@ impl Reflect for Cow<'static, Path> {
Ok(())
}
fn reflect_kind(&self) -> ReflectKind {
ReflectKind::Value
}
fn reflect_ref(&self) -> ReflectRef {
ReflectRef::Value(self)
}

View File

@ -93,8 +93,8 @@
//! Since most data is passed around as `dyn Reflect`,
//! the `Reflect` trait has methods for going to and from these subtraits.
//!
//! [`Reflect::reflect_ref`], [`Reflect::reflect_mut`], and [`Reflect::reflect_owned`] all return
//! an enum that respectively contains immutable, mutable, and owned access to the type as a subtrait object.
//! [`Reflect::reflect_kind`], [`Reflect::reflect_ref`], [`Reflect::reflect_mut`], and [`Reflect::reflect_owned`] all return
//! an enum that respectively contains zero-sized, immutable, mutable, and owned access to the type as a subtrait object.
//!
//! For example, we can get out a `dyn Tuple` from our reflected tuple type using one of these methods.
//!

View File

@ -6,8 +6,8 @@ use bevy_reflect_derive::impl_type_path;
use crate::utility::reflect_hasher;
use crate::{
self as bevy_reflect, FromReflect, Reflect, ReflectMut, ReflectOwned, ReflectRef, TypeInfo,
TypePath, TypePathTable,
self as bevy_reflect, FromReflect, Reflect, ReflectKind, ReflectMut, ReflectOwned, ReflectRef,
TypeInfo, TypePath, TypePathTable,
};
/// A trait used to power [list-like] operations via [reflection].
@ -318,6 +318,11 @@ impl Reflect for DynamicList {
Ok(())
}
#[inline]
fn reflect_kind(&self) -> ReflectKind {
ReflectKind::List
}
#[inline]
fn reflect_ref(&self) -> ReflectRef {
ReflectRef::List(self)

View File

@ -6,8 +6,8 @@ use bevy_reflect_derive::impl_type_path;
use bevy_utils::{Entry, HashMap};
use crate::{
self as bevy_reflect, Reflect, ReflectMut, ReflectOwned, ReflectRef, TypeInfo, TypePath,
TypePathTable,
self as bevy_reflect, Reflect, ReflectKind, ReflectMut, ReflectOwned, ReflectRef, TypeInfo,
TypePath, TypePathTable,
};
/// A trait used to power [map-like] operations via [reflection].
@ -354,6 +354,10 @@ impl Reflect for DynamicMap {
Ok(())
}
fn reflect_kind(&self) -> ReflectKind {
ReflectKind::Map
}
fn reflect_ref(&self) -> ReflectRef {
ReflectRef::Map(self)
}

View File

@ -2,8 +2,8 @@
use std::{borrow::Cow, fmt};
use super::error::{AccessErrorKind, TypeKind};
use crate::{AccessError, Reflect, ReflectMut, ReflectRef, VariantType};
use super::error::AccessErrorKind;
use crate::{AccessError, Reflect, ReflectKind, ReflectMut, ReflectRef, VariantType};
type InnerResult<T> = Result<T, AccessErrorKind>;
@ -55,7 +55,7 @@ impl<'a> Access<'a> {
offset: Option<usize>,
) -> Result<&'r dyn Reflect, AccessError<'a>> {
self.element_inner(base)
.and_then(|opt| opt.ok_or(AccessErrorKind::MissingField(base.into())))
.and_then(|opt| opt.ok_or(AccessErrorKind::MissingField(base.reflect_kind())))
.map_err(|err| err.with_access(self.clone(), offset))
}
@ -78,7 +78,7 @@ impl<'a> Access<'a> {
},
(Self::Field(_) | Self::FieldIndex(_), actual) => {
Err(AccessErrorKind::IncompatibleTypes {
expected: TypeKind::Struct,
expected: ReflectKind::Struct,
actual: actual.into(),
})
}
@ -90,14 +90,14 @@ impl<'a> Access<'a> {
actual => Err(invalid_variant(VariantType::Tuple, actual)),
},
(Self::TupleIndex(_), actual) => Err(AccessErrorKind::IncompatibleTypes {
expected: TypeKind::Tuple,
expected: ReflectKind::Tuple,
actual: actual.into(),
}),
(&Self::ListIndex(index), List(list)) => Ok(list.get(index)),
(&Self::ListIndex(index), Array(list)) => Ok(list.get(index)),
(Self::ListIndex(_), actual) => Err(AccessErrorKind::IncompatibleTypes {
expected: TypeKind::List,
expected: ReflectKind::List,
actual: actual.into(),
}),
}
@ -108,7 +108,7 @@ impl<'a> Access<'a> {
base: &'r mut dyn Reflect,
offset: Option<usize>,
) -> Result<&'r mut dyn Reflect, AccessError<'a>> {
let kind = base.into();
let kind = base.reflect_kind();
self.element_inner_mut(base)
.and_then(|maybe| maybe.ok_or(AccessErrorKind::MissingField(kind)))
@ -137,7 +137,7 @@ impl<'a> Access<'a> {
},
(Self::Field(_) | Self::FieldIndex(_), actual) => {
Err(AccessErrorKind::IncompatibleTypes {
expected: TypeKind::Struct,
expected: ReflectKind::Struct,
actual: actual.into(),
})
}
@ -149,14 +149,14 @@ impl<'a> Access<'a> {
actual => Err(invalid_variant(VariantType::Tuple, actual)),
},
(Self::TupleIndex(_), actual) => Err(AccessErrorKind::IncompatibleTypes {
expected: TypeKind::Tuple,
expected: ReflectKind::Tuple,
actual: actual.into(),
}),
(&Self::ListIndex(index), List(list)) => Ok(list.get_mut(index)),
(&Self::ListIndex(index), Array(list)) => Ok(list.get_mut(index)),
(Self::ListIndex(_), actual) => Err(AccessErrorKind::IncompatibleTypes {
expected: TypeKind::List,
expected: ReflectKind::List,
actual: actual.into(),
}),
}

View File

@ -1,22 +1,22 @@
use std::fmt;
use super::Access;
use crate::{Reflect, ReflectMut, ReflectRef, VariantType};
use crate::{ReflectKind, VariantType};
/// The kind of [`AccessError`], along with some kind-specific information.
#[derive(Debug, PartialEq, Eq, Clone)]
pub enum AccessErrorKind {
/// An error that occurs when a certain type doesn't
/// contain the value referenced by the [`Access`].
MissingField(TypeKind),
MissingField(ReflectKind),
/// An error that occurs when using an [`Access`] on the wrong type.
/// (i.e. a [`ListIndex`](Access::ListIndex) on a struct, or a [`TupleIndex`](Access::TupleIndex) on a list)
IncompatibleTypes {
/// The [`TypeKind`] that was expected based on the [`Access`].
expected: TypeKind,
/// The actual [`TypeKind`] that was found.
actual: TypeKind,
/// The [`ReflectKind`] that was expected based on the [`Access`].
expected: ReflectKind,
/// The actual [`ReflectKind`] that was found.
actual: ReflectKind,
},
/// An error that occurs when using an [`Access`] on the wrong enum variant.
@ -127,81 +127,3 @@ impl std::fmt::Display for AccessError<'_> {
}
}
impl std::error::Error for AccessError<'_> {}
/// The kind of the type trying to be accessed.
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
#[allow(missing_docs /* Variants are self-explanatory */)]
pub enum TypeKind {
Struct,
TupleStruct,
Tuple,
List,
Array,
Map,
Enum,
Value,
Unit,
}
impl fmt::Display for TypeKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
TypeKind::Struct => f.pad("struct"),
TypeKind::TupleStruct => f.pad("tuple struct"),
TypeKind::Tuple => f.pad("tuple"),
TypeKind::List => f.pad("list"),
TypeKind::Array => f.pad("array"),
TypeKind::Map => f.pad("map"),
TypeKind::Enum => f.pad("enum"),
TypeKind::Value => f.pad("value"),
TypeKind::Unit => f.pad("unit"),
}
}
}
impl From<ReflectRef<'_>> for TypeKind {
fn from(value: ReflectRef) -> Self {
match value {
ReflectRef::Struct(_) => TypeKind::Struct,
ReflectRef::TupleStruct(_) => TypeKind::TupleStruct,
ReflectRef::Tuple(_) => TypeKind::Tuple,
ReflectRef::List(_) => TypeKind::List,
ReflectRef::Array(_) => TypeKind::Array,
ReflectRef::Map(_) => TypeKind::Map,
ReflectRef::Enum(_) => TypeKind::Enum,
ReflectRef::Value(_) => TypeKind::Value,
}
}
}
impl From<&dyn Reflect> for TypeKind {
fn from(value: &dyn Reflect) -> Self {
value.reflect_ref().into()
}
}
impl From<ReflectMut<'_>> for TypeKind {
fn from(value: ReflectMut) -> Self {
match value {
ReflectMut::Struct(_) => TypeKind::Struct,
ReflectMut::TupleStruct(_) => TypeKind::TupleStruct,
ReflectMut::Tuple(_) => TypeKind::Tuple,
ReflectMut::List(_) => TypeKind::List,
ReflectMut::Array(_) => TypeKind::Array,
ReflectMut::Map(_) => TypeKind::Map,
ReflectMut::Enum(_) => TypeKind::Enum,
ReflectMut::Value(_) => TypeKind::Value,
}
}
}
impl From<&mut dyn Reflect> for TypeKind {
fn from(value: &mut dyn Reflect) -> Self {
value.reflect_ref().into()
}
}
impl From<VariantType> for TypeKind {
fn from(value: VariantType) -> Self {
match value {
VariantType::Struct => TypeKind::Struct,
VariantType::Tuple => TypeKind::Tuple,
VariantType::Unit => TypeKind::Unit,
}
}
}

View File

@ -491,7 +491,7 @@ mod tests {
use super::*;
use crate as bevy_reflect;
use crate::*;
use error::{AccessErrorKind, TypeKind};
use error::AccessErrorKind;
#[derive(Reflect)]
struct A {
@ -562,8 +562,8 @@ mod tests {
fn invalid_access(
offset: usize,
actual: TypeKind,
expected: TypeKind,
actual: ReflectKind,
expected: ReflectKind,
access: &'static str,
) -> StaticError {
ReflectPathError::InvalidAccess(AccessError {
@ -733,7 +733,7 @@ mod tests {
assert_eq!(
a.reflect_path("x.notreal").err().unwrap(),
ReflectPathError::InvalidAccess(AccessError {
kind: AccessErrorKind::MissingField(TypeKind::Struct),
kind: AccessErrorKind::MissingField(ReflectKind::Struct),
access: access_field("notreal"),
offset: Some(2),
})
@ -754,11 +754,11 @@ mod tests {
);
assert_eq!(
a.reflect_path("x[0]").err().unwrap(),
invalid_access(2, TypeKind::Struct, TypeKind::List, "x[0]")
invalid_access(2, ReflectKind::Struct, ReflectKind::List, "x[0]")
);
assert_eq!(
a.reflect_path("y.x").err().unwrap(),
invalid_access(2, TypeKind::List, TypeKind::Struct, "y.x")
invalid_access(2, ReflectKind::List, ReflectKind::Struct, "y.x")
);
}

View File

@ -10,12 +10,47 @@ use std::{
use crate::utility::NonGenericTypeInfoCell;
/// An immutable enumeration of "kinds" of reflected type.
macro_rules! impl_reflect_enum {
($name:ident$(<$lifetime:lifetime>)?) => {
impl $name$(<$lifetime>)? {
/// Returns the "kind" of this reflected type without any information.
pub fn kind(&self) -> ReflectKind {
match self {
Self::Struct(_) => ReflectKind::Struct,
Self::TupleStruct(_) => ReflectKind::TupleStruct,
Self::Tuple(_) => ReflectKind::Tuple,
Self::List(_) => ReflectKind::List,
Self::Array(_) => ReflectKind::Array,
Self::Map(_) => ReflectKind::Map,
Self::Enum(_) => ReflectKind::Enum,
Self::Value(_) => ReflectKind::Value,
}
}
}
impl From<$name$(<$lifetime>)?> for ReflectKind {
fn from(value: $name) -> Self {
match value {
$name::Struct(_) => Self::Struct,
$name::TupleStruct(_) => Self::TupleStruct,
$name::Tuple(_) => Self::Tuple,
$name::List(_) => Self::List,
$name::Array(_) => Self::Array,
$name::Map(_) => Self::Map,
$name::Enum(_) => Self::Enum,
$name::Value(_) => Self::Value,
}
}
}
};
}
/// An immutable enumeration of "kinds" of a reflected type.
///
/// Each variant contains a trait object with methods specific to a kind of
/// type.
///
/// A `ReflectRef` is obtained via [`Reflect::reflect_ref`].
/// A [`ReflectRef`] is obtained via [`Reflect::reflect_ref`].
pub enum ReflectRef<'a> {
Struct(&'a dyn Struct),
TupleStruct(&'a dyn TupleStruct),
@ -26,13 +61,14 @@ pub enum ReflectRef<'a> {
Enum(&'a dyn Enum),
Value(&'a dyn Reflect),
}
impl_reflect_enum!(ReflectRef<'_>);
/// A mutable enumeration of "kinds" of reflected type.
/// A mutable enumeration of "kinds" of a reflected type.
///
/// Each variant contains a trait object with methods specific to a kind of
/// type.
///
/// A `ReflectMut` is obtained via [`Reflect::reflect_mut`].
/// A [`ReflectMut`] is obtained via [`Reflect::reflect_mut`].
pub enum ReflectMut<'a> {
Struct(&'a mut dyn Struct),
TupleStruct(&'a mut dyn TupleStruct),
@ -43,13 +79,14 @@ pub enum ReflectMut<'a> {
Enum(&'a mut dyn Enum),
Value(&'a mut dyn Reflect),
}
impl_reflect_enum!(ReflectMut<'_>);
/// An owned enumeration of "kinds" of reflected type.
/// An owned enumeration of "kinds" of a reflected type.
///
/// Each variant contains a trait object with methods specific to a kind of
/// type.
///
/// A `ReflectOwned` is obtained via [`Reflect::reflect_owned`].
/// A [`ReflectOwned`] is obtained via [`Reflect::reflect_owned`].
pub enum ReflectOwned {
Struct(Box<dyn Struct>),
TupleStruct(Box<dyn TupleStruct>),
@ -60,6 +97,38 @@ pub enum ReflectOwned {
Enum(Box<dyn Enum>),
Value(Box<dyn Reflect>),
}
impl_reflect_enum!(ReflectOwned);
/// A zero-sized enumuration of the "kinds" of a reflected type.
///
/// A [`ReflectKind`] is obtained via [`Reflect::reflect_kind`],
/// or via [`ReflectRef::kind`],[`ReflectMut::kind`] or [`ReflectOwned::kind`].
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum ReflectKind {
Struct,
TupleStruct,
Tuple,
List,
Array,
Map,
Enum,
Value,
}
impl std::fmt::Display for ReflectKind {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
ReflectKind::Struct => f.pad("struct"),
ReflectKind::TupleStruct => f.pad("tuple struct"),
ReflectKind::Tuple => f.pad("tuple"),
ReflectKind::List => f.pad("list"),
ReflectKind::Array => f.pad("array"),
ReflectKind::Map => f.pad("map"),
ReflectKind::Enum => f.pad("enum"),
ReflectKind::Value => f.pad("value"),
}
}
}
/// The core trait of [`bevy_reflect`], used for accessing and modifying data dynamically.
///
@ -156,7 +225,14 @@ pub trait Reflect: DynamicTypePath + Any + Send + Sync {
/// containing the trait object.
fn set(&mut self, value: Box<dyn Reflect>) -> Result<(), Box<dyn Reflect>>;
/// Returns an enumeration of "kinds" of type.
/// Returns a zero-sized enumeration of "kinds" of type.
///
/// See [`ReflectKind`].
fn reflect_kind(&self) -> ReflectKind {
self.reflect_ref().kind()
}
/// Returns an immutable enumeration of "kinds" of type.
///
/// See [`ReflectRef`].
fn reflect_ref(&self) -> ReflectRef;

View File

@ -1,6 +1,6 @@
use crate::{
self as bevy_reflect, NamedField, Reflect, ReflectMut, ReflectOwned, ReflectRef, TypeInfo,
TypePath, TypePathTable,
self as bevy_reflect, NamedField, Reflect, ReflectKind, ReflectMut, ReflectOwned, ReflectRef,
TypeInfo, TypePath, TypePathTable,
};
use bevy_reflect_derive::impl_type_path;
use bevy_utils::HashMap;
@ -438,6 +438,11 @@ impl Reflect for DynamicStruct {
Ok(())
}
#[inline]
fn reflect_kind(&self) -> ReflectKind {
ReflectKind::Struct
}
#[inline]
fn reflect_ref(&self) -> ReflectRef {
ReflectRef::Struct(self)

View File

@ -1,12 +1,12 @@
use bevy_reflect_derive::impl_type_path;
use bevy_utils::all_tuples;
use crate::TypePathTable;
use crate::{
self as bevy_reflect, utility::GenericTypePathCell, FromReflect, GetTypeRegistration, Reflect,
ReflectMut, ReflectOwned, ReflectRef, TypeInfo, TypePath, TypeRegistration, Typed,
UnnamedField,
};
use crate::{ReflectKind, TypePathTable};
use std::any::{Any, TypeId};
use std::fmt::{Debug, Formatter};
use std::slice::Iter;
@ -344,6 +344,11 @@ impl Reflect for DynamicTuple {
Ok(())
}
#[inline]
fn reflect_kind(&self) -> ReflectKind {
ReflectKind::Tuple
}
#[inline]
fn reflect_ref(&self) -> ReflectRef {
ReflectRef::Tuple(self)
@ -545,6 +550,10 @@ macro_rules! impl_reflect_tuple {
Ok(())
}
fn reflect_kind(&self) -> ReflectKind {
ReflectKind::Tuple
}
fn reflect_ref(&self) -> ReflectRef {
ReflectRef::Tuple(self)
}

View File

@ -1,8 +1,8 @@
use bevy_reflect_derive::impl_type_path;
use crate::{
self as bevy_reflect, DynamicTuple, Reflect, ReflectMut, ReflectOwned, ReflectRef, Tuple,
TypeInfo, TypePath, TypePathTable, UnnamedField,
self as bevy_reflect, DynamicTuple, Reflect, ReflectKind, ReflectMut, ReflectOwned, ReflectRef,
Tuple, TypeInfo, TypePath, TypePathTable, UnnamedField,
};
use std::any::{Any, TypeId};
use std::fmt::{Debug, Formatter};
@ -346,6 +346,11 @@ impl Reflect for DynamicTupleStruct {
Ok(())
}
#[inline]
fn reflect_kind(&self) -> ReflectKind {
ReflectKind::TupleStruct
}
#[inline]
fn reflect_ref(&self) -> ReflectRef {
ReflectRef::TupleStruct(self)

View File

@ -9,8 +9,8 @@ use bevy_ecs::{
};
use bevy_reflect::{
utility::{reflect_hasher, NonGenericTypeInfoCell},
FromReflect, Reflect, ReflectMut, ReflectOwned, ReflectRef, TypeInfo, TypePath, Typed,
ValueInfo,
FromReflect, Reflect, ReflectKind, ReflectMut, ReflectOwned, ReflectRef, TypeInfo, TypePath,
Typed, ValueInfo,
};
use bevy_utils::{thiserror::Error, HashMap, HashSet};
use serde::{Deserialize, Serialize};
@ -122,6 +122,9 @@ impl Reflect for RenderAssetUsages {
*self = value.take()?;
Ok(())
}
fn reflect_kind(&self) -> bevy_reflect::ReflectKind {
ReflectKind::Value
}
fn reflect_ref(&self) -> bevy_reflect::ReflectRef {
ReflectRef::Value(self)
}