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:
parent
4c86ad6aed
commit
054134fba2
@ -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)
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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.
|
||||
//!
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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(),
|
||||
}),
|
||||
}
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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")
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user