diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/impls/enums.rs b/crates/bevy_reflect/bevy_reflect_derive/src/impls/enums.rs index 83e8e18ff3728..d3399c4f50460 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/impls/enums.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/impls/enums.rs @@ -264,6 +264,10 @@ pub(crate) fn impl_enum(reflect_enum: &ReflectEnum) -> TokenStream { #bevy_reflect_path::ReflectMut::Enum(self) } + fn reflect_owned(self: Box) -> #bevy_reflect_path::ReflectOwned { + #bevy_reflect_path::ReflectOwned::Enum(self) + } + #hash_fn #partial_eq_fn diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/impls/structs.rs b/crates/bevy_reflect/bevy_reflect_derive/src/impls/structs.rs index 2c35930703ec5..923457f2b19f9 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/impls/structs.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/impls/structs.rs @@ -223,6 +223,10 @@ pub(crate) fn impl_struct(reflect_struct: &ReflectStruct) -> TokenStream { #bevy_reflect_path::ReflectMut::Struct(self) } + fn reflect_owned(self: Box) -> #bevy_reflect_path::ReflectOwned { + #bevy_reflect_path::ReflectOwned::Struct(self) + } + #hash_fn #partial_eq_fn diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/impls/tuple_structs.rs b/crates/bevy_reflect/bevy_reflect_derive/src/impls/tuple_structs.rs index df2e8661f7498..30bcaf3c9c143 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/impls/tuple_structs.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/impls/tuple_structs.rs @@ -184,6 +184,10 @@ pub(crate) fn impl_tuple_struct(reflect_struct: &ReflectStruct) -> TokenStream { #bevy_reflect_path::ReflectMut::TupleStruct(self) } + fn reflect_owned(self: Box) -> #bevy_reflect_path::ReflectOwned { + #bevy_reflect_path::ReflectOwned::TupleStruct(self) + } + #hash_fn #partial_eq_fn diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/impls/values.rs b/crates/bevy_reflect/bevy_reflect_derive/src/impls/values.rs index 91f230876d1d6..1c768fbf0b96e 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/impls/values.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/impls/values.rs @@ -103,6 +103,10 @@ pub(crate) fn impl_value(meta: &ReflectMeta) -> TokenStream { #bevy_reflect_path::ReflectMut::Value(self) } + fn reflect_owned(self: Box) -> #bevy_reflect_path::ReflectOwned { + #bevy_reflect_path::ReflectOwned::Value(self) + } + #hash_fn #partial_eq_fn diff --git a/crates/bevy_reflect/src/array.rs b/crates/bevy_reflect/src/array.rs index 6571fdf33792b..206eda8006ae6 100644 --- a/crates/bevy_reflect/src/array.rs +++ b/crates/bevy_reflect/src/array.rs @@ -1,5 +1,6 @@ use crate::{ - utility::NonGenericTypeInfoCell, DynamicInfo, Reflect, ReflectMut, ReflectRef, TypeInfo, Typed, + utility::NonGenericTypeInfoCell, DynamicInfo, Reflect, ReflectMut, ReflectOwned, ReflectRef, + TypeInfo, Typed, }; use std::{ any::{Any, TypeId}, @@ -226,6 +227,11 @@ impl Reflect for DynamicArray { ReflectMut::Array(self) } + #[inline] + fn reflect_owned(self: Box) -> ReflectOwned { + ReflectOwned::Array(self) + } + #[inline] fn clone_value(&self) -> Box { Box::new(self.clone_dynamic()) diff --git a/crates/bevy_reflect/src/enums/dynamic_enum.rs b/crates/bevy_reflect/src/enums/dynamic_enum.rs index e0ad08a689406..a3424c66263d3 100644 --- a/crates/bevy_reflect/src/enums/dynamic_enum.rs +++ b/crates/bevy_reflect/src/enums/dynamic_enum.rs @@ -1,7 +1,8 @@ use crate::utility::NonGenericTypeInfoCell; use crate::{ enum_debug, enum_hash, enum_partial_eq, DynamicInfo, DynamicStruct, DynamicTuple, Enum, - Reflect, ReflectMut, ReflectRef, Struct, Tuple, TypeInfo, Typed, VariantFieldIter, VariantType, + Reflect, ReflectMut, ReflectOwned, ReflectRef, Struct, Tuple, TypeInfo, Typed, + VariantFieldIter, VariantType, }; use std::any::Any; use std::fmt::Formatter; @@ -390,6 +391,11 @@ impl Reflect for DynamicEnum { ReflectMut::Enum(self) } + #[inline] + fn reflect_owned(self: Box) -> ReflectOwned { + ReflectOwned::Enum(self) + } + #[inline] fn clone_value(&self) -> Box { Box::new(self.clone_dynamic()) diff --git a/crates/bevy_reflect/src/impls/smallvec.rs b/crates/bevy_reflect/src/impls/smallvec.rs index ef855e9426379..dfff11e6de65f 100644 --- a/crates/bevy_reflect/src/impls/smallvec.rs +++ b/crates/bevy_reflect/src/impls/smallvec.rs @@ -4,7 +4,7 @@ use std::any::Any; use crate::utility::GenericTypeInfoCell; use crate::{ Array, ArrayIter, FromReflect, FromType, GetTypeRegistration, List, ListInfo, Reflect, - ReflectFromPtr, ReflectMut, ReflectRef, TypeInfo, TypeRegistration, Typed, + ReflectFromPtr, ReflectMut, ReflectOwned, ReflectRef, TypeInfo, TypeRegistration, Typed, }; impl Array for SmallVec @@ -115,6 +115,10 @@ where ReflectMut::List(self) } + fn reflect_owned(self: Box) -> ReflectOwned { + ReflectOwned::List(self) + } + fn clone_value(&self) -> Box { Box::new(List::clone_dynamic(self)) } diff --git a/crates/bevy_reflect/src/impls/std.rs b/crates/bevy_reflect/src/impls/std.rs index 8f7c59bbbf05d..169b35f41f5ca 100644 --- a/crates/bevy_reflect/src/impls/std.rs +++ b/crates/bevy_reflect/src/impls/std.rs @@ -1,5 +1,5 @@ use crate::std_traits::ReflectDefault; -use crate::{self as bevy_reflect, ReflectFromPtr}; +use crate::{self as bevy_reflect, ReflectFromPtr, ReflectOwned}; use crate::{ map_apply, map_partial_eq, Array, ArrayInfo, ArrayIter, DynamicEnum, DynamicMap, Enum, EnumInfo, FromReflect, FromType, GetTypeRegistration, List, ListInfo, Map, MapInfo, MapIter, @@ -270,6 +270,10 @@ impl Reflect for Vec { ReflectMut::List(self) } + fn reflect_owned(self: Box) -> ReflectOwned { + ReflectOwned::List(self) + } + fn clone_value(&self) -> Box { Box::new(List::clone_dynamic(self)) } @@ -434,6 +438,10 @@ impl Reflect for HashMap { ReflectMut::Map(self) } + fn reflect_owned(self: Box) -> ReflectOwned { + ReflectOwned::Map(self) + } + fn clone_value(&self) -> Box { Box::new(self.clone_dynamic()) } @@ -566,6 +574,11 @@ impl Reflect for [T; N] { ReflectMut::Array(self) } + #[inline] + fn reflect_owned(self: Box) -> ReflectOwned { + ReflectOwned::Array(self) + } + #[inline] fn clone_value(&self) -> Box { Box::new(self.clone_dynamic()) @@ -678,6 +691,10 @@ impl Reflect for Cow<'static, str> { ReflectMut::Value(self) } + fn reflect_owned(self: Box) -> ReflectOwned { + ReflectOwned::Value(self) + } + fn clone_value(&self) -> Box { Box::new(self.clone()) } @@ -868,6 +885,10 @@ impl Reflect for Option { ReflectMut::Enum(self) } + fn reflect_owned(self: Box) -> ReflectOwned { + ReflectOwned::Enum(self) + } + #[inline] fn clone_value(&self) -> Box { Box::new(Enum::clone_dynamic(self)) diff --git a/crates/bevy_reflect/src/list.rs b/crates/bevy_reflect/src/list.rs index 965bdcb66396d..b05597a5f2a79 100644 --- a/crates/bevy_reflect/src/list.rs +++ b/crates/bevy_reflect/src/list.rs @@ -3,8 +3,8 @@ use std::fmt::{Debug, Formatter}; use crate::utility::NonGenericTypeInfoCell; use crate::{ - Array, ArrayIter, DynamicArray, DynamicInfo, FromReflect, Reflect, ReflectMut, ReflectRef, - TypeInfo, Typed, + Array, ArrayIter, DynamicArray, DynamicInfo, FromReflect, Reflect, ReflectMut, ReflectOwned, + ReflectRef, TypeInfo, Typed, }; /// An ordered, mutable list of [Reflect] items. This corresponds to types like [`std::vec::Vec`]. @@ -246,6 +246,11 @@ impl Reflect for DynamicList { ReflectMut::List(self) } + #[inline] + fn reflect_owned(self: Box) -> ReflectOwned { + ReflectOwned::List(self) + } + #[inline] fn clone_value(&self) -> Box { Box::new(List::clone_dynamic(self)) diff --git a/crates/bevy_reflect/src/map.rs b/crates/bevy_reflect/src/map.rs index bbccdb73acc6a..f6f2d0efaa941 100644 --- a/crates/bevy_reflect/src/map.rs +++ b/crates/bevy_reflect/src/map.rs @@ -5,7 +5,7 @@ use std::hash::Hash; use bevy_utils::{Entry, HashMap}; use crate::utility::NonGenericTypeInfoCell; -use crate::{DynamicInfo, Reflect, ReflectMut, ReflectRef, TypeInfo, Typed}; +use crate::{DynamicInfo, Reflect, ReflectMut, ReflectOwned, ReflectRef, TypeInfo, Typed}; /// An ordered mapping between [`Reflect`] values. /// @@ -300,6 +300,10 @@ impl Reflect for DynamicMap { ReflectMut::Map(self) } + fn reflect_owned(self: Box) -> ReflectOwned { + ReflectOwned::Map(self) + } + fn clone_value(&self) -> Box { Box::new(self.clone_dynamic()) } diff --git a/crates/bevy_reflect/src/reflect.rs b/crates/bevy_reflect/src/reflect.rs index fb8285fd9de0c..a700ba4f993bb 100644 --- a/crates/bevy_reflect/src/reflect.rs +++ b/crates/bevy_reflect/src/reflect.rs @@ -45,6 +45,23 @@ pub enum ReflectMut<'a> { Value(&'a mut dyn Reflect), } +/// An owned enumeration of "kinds" of reflected type. +/// +/// Each variant contains a trait object with methods specific to a kind of +/// type. +/// +/// A `ReflectOwned` is obtained via [`Reflect::reflect_owned`]. +pub enum ReflectOwned { + Struct(Box), + TupleStruct(Box), + Tuple(Box), + List(Box), + Array(Box), + Map(Box), + Enum(Box), + Value(Box), +} + /// A reflected Rust type. /// /// Methods for working with particular kinds of Rust type are available using the [`Array`], [`List`], @@ -139,6 +156,11 @@ pub trait Reflect: Any + Send + Sync { /// See [`ReflectMut`]. fn reflect_mut(&mut self) -> ReflectMut; + /// Returns an owned enumeration of "kinds" of type. + /// + /// See [`ReflectOwned`]. + fn reflect_owned(self: Box) -> ReflectOwned; + /// Clones the value as a `Reflect` trait object. /// /// When deriving `Reflect` for a struct, tuple struct or enum, the value is diff --git a/crates/bevy_reflect/src/struct_trait.rs b/crates/bevy_reflect/src/struct_trait.rs index e4dfdf72d4f54..b4c897efd73a6 100644 --- a/crates/bevy_reflect/src/struct_trait.rs +++ b/crates/bevy_reflect/src/struct_trait.rs @@ -1,5 +1,7 @@ use crate::utility::NonGenericTypeInfoCell; -use crate::{DynamicInfo, NamedField, Reflect, ReflectMut, ReflectRef, TypeInfo, Typed}; +use crate::{ + DynamicInfo, NamedField, Reflect, ReflectMut, ReflectOwned, ReflectRef, TypeInfo, Typed, +}; use bevy_utils::{Entry, HashMap}; use std::fmt::{Debug, Formatter}; use std::{ @@ -427,6 +429,11 @@ impl Reflect for DynamicStruct { ReflectMut::Struct(self) } + #[inline] + fn reflect_owned(self: Box) -> ReflectOwned { + ReflectOwned::Struct(self) + } + fn apply(&mut self, value: &dyn Reflect) { if let ReflectRef::Struct(struct_value) = value.reflect_ref() { for (i, value) in struct_value.iter_fields().enumerate() { diff --git a/crates/bevy_reflect/src/tuple.rs b/crates/bevy_reflect/src/tuple.rs index f3b1968df580f..527982b029539 100644 --- a/crates/bevy_reflect/src/tuple.rs +++ b/crates/bevy_reflect/src/tuple.rs @@ -1,7 +1,7 @@ use crate::utility::NonGenericTypeInfoCell; use crate::{ - DynamicInfo, FromReflect, GetTypeRegistration, Reflect, ReflectMut, ReflectRef, TypeInfo, - TypeRegistration, Typed, UnnamedField, + DynamicInfo, FromReflect, GetTypeRegistration, Reflect, ReflectMut, ReflectOwned, ReflectRef, + TypeInfo, TypeRegistration, Typed, UnnamedField, }; use std::any::{Any, TypeId}; use std::fmt::{Debug, Formatter}; @@ -341,6 +341,11 @@ impl Reflect for DynamicTuple { ReflectMut::Tuple(self) } + #[inline] + fn reflect_owned(self: Box) -> ReflectOwned { + ReflectOwned::Tuple(self) + } + fn apply(&mut self, value: &dyn Reflect) { tuple_apply(self, value); } @@ -540,6 +545,10 @@ macro_rules! impl_reflect_tuple { ReflectMut::Tuple(self) } + fn reflect_owned(self: Box) -> ReflectOwned { + ReflectOwned::Tuple(self) + } + fn clone_value(&self) -> Box { Box::new(self.clone_dynamic()) } diff --git a/crates/bevy_reflect/src/tuple_struct.rs b/crates/bevy_reflect/src/tuple_struct.rs index 3069cb5ea0718..d6549521bc34f 100644 --- a/crates/bevy_reflect/src/tuple_struct.rs +++ b/crates/bevy_reflect/src/tuple_struct.rs @@ -1,5 +1,7 @@ use crate::utility::NonGenericTypeInfoCell; -use crate::{DynamicInfo, Reflect, ReflectMut, ReflectRef, TypeInfo, Typed, UnnamedField}; +use crate::{ + DynamicInfo, Reflect, ReflectMut, ReflectOwned, ReflectRef, TypeInfo, Typed, UnnamedField, +}; use std::any::{Any, TypeId}; use std::fmt::{Debug, Formatter}; use std::slice::Iter; @@ -330,6 +332,11 @@ impl Reflect for DynamicTupleStruct { ReflectMut::TupleStruct(self) } + #[inline] + fn reflect_owned(self: Box) -> ReflectOwned { + ReflectOwned::TupleStruct(self) + } + fn apply(&mut self, value: &dyn Reflect) { if let ReflectRef::TupleStruct(tuple_struct) = value.reflect_ref() { for (i, value) in tuple_struct.iter_fields().enumerate() { diff --git a/crates/bevy_reflect/src/type_info.rs b/crates/bevy_reflect/src/type_info.rs index 37fe9f9cbef3d..f309d6daa5bff 100644 --- a/crates/bevy_reflect/src/type_info.rs +++ b/crates/bevy_reflect/src/type_info.rs @@ -23,7 +23,7 @@ use std::any::{Any, TypeId}; /// /// ``` /// # use std::any::Any; -/// # use bevy_reflect::{NamedField, Reflect, ReflectMut, ReflectRef, StructInfo, TypeInfo, ValueInfo}; +/// # use bevy_reflect::{NamedField, Reflect, ReflectMut, ReflectOwned, ReflectRef, StructInfo, TypeInfo, ValueInfo}; /// # use bevy_reflect::utility::NonGenericTypeInfoCell; /// use bevy_reflect::Typed; /// @@ -59,6 +59,7 @@ use std::any::{Any, TypeId}; /// # fn set(&mut self, value: Box) -> Result<(), Box> { todo!() } /// # fn reflect_ref(&self) -> ReflectRef { todo!() } /// # fn reflect_mut(&mut self) -> ReflectMut { todo!() } +/// # fn reflect_owned(self: Box) -> ReflectOwned { todo!() } /// # fn clone_value(&self) -> Box { todo!() } /// # } /// ``` diff --git a/crates/bevy_reflect/src/utility.rs b/crates/bevy_reflect/src/utility.rs index 84973cea15b90..773360312cea1 100644 --- a/crates/bevy_reflect/src/utility.rs +++ b/crates/bevy_reflect/src/utility.rs @@ -16,7 +16,7 @@ use std::any::{Any, TypeId}; /// /// ``` /// # use std::any::Any; -/// # use bevy_reflect::{NamedField, Reflect, ReflectMut, ReflectRef, StructInfo, Typed, TypeInfo}; +/// # use bevy_reflect::{NamedField, Reflect, ReflectMut, ReflectOwned, ReflectRef, StructInfo, Typed, TypeInfo}; /// use bevy_reflect::utility::NonGenericTypeInfoCell; /// /// struct Foo { @@ -46,6 +46,7 @@ use std::any::{Any, TypeId}; /// # fn set(&mut self, value: Box) -> Result<(), Box> { todo!() } /// # fn reflect_ref(&self) -> ReflectRef { todo!() } /// # fn reflect_mut(&mut self) -> ReflectMut { todo!() } +/// # fn reflect_owned(self: Box) -> ReflectOwned { todo!() } /// # fn clone_value(&self) -> Box { todo!() } /// # } /// ``` @@ -79,7 +80,7 @@ impl NonGenericTypeInfoCell { /// /// ``` /// # use std::any::Any; -/// # use bevy_reflect::{Reflect, ReflectMut, ReflectRef, TupleStructInfo, Typed, TypeInfo, UnnamedField}; +/// # use bevy_reflect::{Reflect, ReflectMut, ReflectOwned, ReflectRef, TupleStructInfo, Typed, TypeInfo, UnnamedField}; /// use bevy_reflect::utility::GenericTypeInfoCell; /// /// struct Foo(T); @@ -107,6 +108,7 @@ impl NonGenericTypeInfoCell { /// # fn set(&mut self, value: Box) -> Result<(), Box> { todo!() } /// # fn reflect_ref(&self) -> ReflectRef { todo!() } /// # fn reflect_mut(&mut self) -> ReflectMut { todo!() } +/// # fn reflect_owned(self: Box) -> ReflectOwned { todo!() } /// # fn clone_value(&self) -> Box { todo!() } /// # } /// ```