Skip to content

Commit

Permalink
Add ReflectKind (#11664)
Browse files Browse the repository at this point in the history
# Objective

Fix #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`
  • Loading branch information
doonv committed Feb 7, 2024
1 parent 4c86ad6 commit 054134f
Show file tree
Hide file tree
Showing 20 changed files with 224 additions and 129 deletions.
7 changes: 5 additions & 2 deletions crates/bevy_asset/src/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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)
}
Expand Down
4 changes: 4 additions & 0 deletions crates/bevy_reflect/bevy_reflect_derive/src/impls/enums.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down
4 changes: 4 additions & 0 deletions crates/bevy_reflect/bevy_reflect_derive/src/impls/structs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down
4 changes: 4 additions & 0 deletions crates/bevy_reflect/bevy_reflect_derive/src/impls/values.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down
9 changes: 7 additions & 2 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, 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::{
Expand Down Expand Up @@ -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)
Expand Down
9 changes: 7 additions & 2 deletions crates/bevy_reflect/src/enums/dynamic_enum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand Down
6 changes: 5 additions & 1 deletion crates/bevy_reflect/src/impls/smallvec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};

Expand Down Expand Up @@ -119,6 +119,10 @@ where
Ok(())
}

fn reflect_kind(&self) -> ReflectKind {
ReflectKind::List
}

fn reflect_ref(&self) -> ReflectRef {
ReflectRef::List(self)
}
Expand Down
37 changes: 35 additions & 2 deletions crates/bevy_reflect/src/impls/std.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};

Expand Down Expand Up @@ -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)
}
Expand Down Expand Up @@ -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)
}
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
}
Expand Down Expand Up @@ -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)
}
Expand Down Expand Up @@ -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)
}
Expand Down Expand Up @@ -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)
}
Expand Down Expand Up @@ -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)
}
Expand Down
4 changes: 2 additions & 2 deletions crates/bevy_reflect/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
//!
Expand Down
9 changes: 7 additions & 2 deletions crates/bevy_reflect/src/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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].
Expand Down Expand Up @@ -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)
Expand Down
8 changes: 6 additions & 2 deletions crates/bevy_reflect/src/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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].
Expand Down Expand Up @@ -354,6 +354,10 @@ impl Reflect for DynamicMap {
Ok(())
}

fn reflect_kind(&self) -> ReflectKind {
ReflectKind::Map
}

fn reflect_ref(&self) -> ReflectRef {
ReflectRef::Map(self)
}
Expand Down
20 changes: 10 additions & 10 deletions crates/bevy_reflect/src/path/access.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>;

Expand Down Expand Up @@ -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))
}

Expand All @@ -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(),
})
}
Expand All @@ -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(),
}),
}
Expand All @@ -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)))
Expand Down Expand Up @@ -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(),
})
}
Expand All @@ -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(),
}),
}
Expand Down
Loading

0 comments on commit 054134f

Please sign in to comment.