From 9f104551ddace34d1762286251fac02c5825b103 Mon Sep 17 00:00:00 2001 From: radiish Date: Sun, 5 Feb 2023 16:03:30 +0000 Subject: [PATCH] use `Reflect` in more places --- crates/bevy_app/src/app.rs | 2 +- crates/bevy_asset/src/reflect.rs | 83 +++++++++++----------- crates/bevy_core_pipeline/src/bloom/mod.rs | 2 +- crates/bevy_pbr/src/bundle.rs | 2 +- crates/bevy_reflect/src/serde/de.rs | 2 +- crates/bevy_reflect/src/serde/ser.rs | 10 ++- crates/bevy_reflect/src/type_registry.rs | 48 +++++++------ crates/bevy_ui/src/focus.rs | 2 +- 8 files changed, 82 insertions(+), 69 deletions(-) diff --git a/crates/bevy_app/src/app.rs b/crates/bevy_app/src/app.rs index 7d5f356cbe44e7..7864a87997d8a0 100644 --- a/crates/bevy_app/src/app.rs +++ b/crates/bevy_app/src/app.rs @@ -1082,7 +1082,7 @@ impl App { /// See [`bevy_reflect::TypeRegistry::register_type_data`]. #[cfg(feature = "bevy_reflect")] pub fn register_type_data< - T: bevy_reflect::PartialReflect + 'static, + T: bevy_reflect::Reflect + 'static, D: bevy_reflect::TypeData + bevy_reflect::FromType, >( &mut self, diff --git a/crates/bevy_asset/src/reflect.rs b/crates/bevy_asset/src/reflect.rs index 61857e4e524a0d..3b8c4255cfea84 100644 --- a/crates/bevy_asset/src/reflect.rs +++ b/crates/bevy_asset/src/reflect.rs @@ -1,7 +1,7 @@ use std::any::{Any, TypeId}; use bevy_ecs::world::{unsafe_world_cell::UnsafeWorldCell, World}; -use bevy_reflect::{FromReflect, FromType, PartialReflect, Uuid}; +use bevy_reflect::{FromReflect, FromType, Reflect, Uuid}; use crate::{Asset, Assets, Handle, HandleId, HandleUntyped}; @@ -17,17 +17,16 @@ pub struct ReflectAsset { handle_type_id: TypeId, assets_resource_type_id: TypeId, - get: fn(&World, HandleUntyped) -> Option<&dyn PartialReflect>, + get: fn(&World, HandleUntyped) -> Option<&dyn Reflect>, // SAFETY: // - may only be called with a [`IteriorMutableWorld`] which can be used to access the corresponding `Assets` resource mutably // - may only be used to access **at most one** access at once - get_unchecked_mut: - unsafe fn(UnsafeWorldCell<'_>, HandleUntyped) -> Option<&mut dyn PartialReflect>, - add: fn(&mut World, &dyn PartialReflect) -> HandleUntyped, - set: fn(&mut World, HandleUntyped, &dyn PartialReflect) -> HandleUntyped, + get_unchecked_mut: unsafe fn(UnsafeWorldCell<'_>, HandleUntyped) -> Option<&mut dyn Reflect>, + add: fn(&mut World, Box) -> HandleUntyped, + set: fn(&mut World, HandleUntyped, Box) -> HandleUntyped, len: fn(&World) -> usize, ids: for<'w> fn(&'w World) -> Box + 'w>, - remove: fn(&mut World, HandleUntyped) -> Option>, + remove: fn(&mut World, HandleUntyped) -> Option>, } impl ReflectAsset { @@ -47,11 +46,7 @@ impl ReflectAsset { } /// Equivalent of [`Assets::get`] - pub fn get<'w>( - &self, - world: &'w World, - handle: HandleUntyped, - ) -> Option<&'w dyn PartialReflect> { + pub fn get<'w>(&self, world: &'w World, handle: HandleUntyped) -> Option<&'w dyn Reflect> { (self.get)(world, handle) } @@ -60,7 +55,7 @@ impl ReflectAsset { &self, world: &'w mut World, handle: HandleUntyped, - ) -> Option<&'w mut dyn PartialReflect> { + ) -> Option<&'w mut dyn Reflect> { // SAFETY: unique world access unsafe { (self.get_unchecked_mut)(world.as_unsafe_world_cell(), handle) } } @@ -96,13 +91,13 @@ impl ReflectAsset { &self, world: UnsafeWorldCell<'w>, handle: HandleUntyped, - ) -> Option<&'w mut dyn PartialReflect> { + ) -> Option<&'w mut dyn Reflect> { // SAFETY: requirements are deferred to the caller (self.get_unchecked_mut)(world, handle) } /// Equivalent of [`Assets::add`] - pub fn add(&self, world: &mut World, value: &dyn PartialReflect) -> HandleUntyped { + pub fn add(&self, world: &mut World, value: Box) -> HandleUntyped { (self.add)(world, value) } /// Equivalent of [`Assets::set`] @@ -110,17 +105,13 @@ impl ReflectAsset { &self, world: &mut World, handle: HandleUntyped, - value: &dyn PartialReflect, + value: Box, ) -> HandleUntyped { (self.set)(world, handle, value) } /// Equivalent of [`Assets::remove`] - pub fn remove( - &self, - world: &mut World, - handle: HandleUntyped, - ) -> Option> { + pub fn remove(&self, world: &mut World, handle: HandleUntyped) -> Option> { (self.remove)(world, handle) } @@ -150,26 +141,41 @@ impl FromType for ReflectAsset { get: |world, handle| { let assets = world.resource::>(); let asset = assets.get(&handle.typed()); - asset.map(|asset| asset as &dyn PartialReflect) + asset.map(|asset| asset as &dyn Reflect) }, get_unchecked_mut: |world, handle| { // SAFETY: `get_unchecked_mut` must be callied with `UnsafeWorldCell` having access to `Assets`, // and must ensure to only have at most one reference to it live at all times. let assets = unsafe { world.get_resource_mut::>().unwrap().into_inner() }; let asset = assets.get_mut(&handle.typed()); - asset.map(|asset| asset as &mut dyn PartialReflect) + asset.map(|asset| asset as &mut dyn Reflect) }, add: |world, value| { let mut assets = world.resource_mut::>(); - let value: A = FromReflect::from_reflect(value) - .expect("could not call `FromReflect::from_reflect` in `ReflectAsset::add`"); - assets.add(value).into() + assets + .add(value.take::().unwrap_or_else(|value| { + panic!( + "ReflectAsset::add called with type `{}`, even though it was created for `{}`", + value.type_name(), + std::any::type_name::() + ) + })) + .into() }, set: |world, handle, value| { let mut assets = world.resource_mut::>(); - let value: A = FromReflect::from_reflect(value) - .expect("could not call `FromReflect::from_reflect` in `ReflectAsset::set`"); - assets.set(handle, value).into() + assets + .set( + handle, + value.take::().unwrap_or_else(|value| { + panic!( + "ReflectAsset::set called with type `{}`, even though it was created for `{}`", + value.type_name(), + std::any::type_name::() + ) + }), + ) + .into() }, len: |world| { let assets = world.resource::>(); @@ -182,7 +188,7 @@ impl FromType for ReflectAsset { remove: |world, handle| { let mut assets = world.resource_mut::>(); let value = assets.remove(handle); - value.map(|value| Box::new(value) as Box) + value.map(|value| Box::new(value) as Box) }, } } @@ -190,7 +196,7 @@ impl FromType for ReflectAsset { /// Reflect type data struct relating a [`Handle`] back to the `T` asset type. /// -/// Say you want to look up the asset values of a list of handles when you have access to their `&dyn PartialReflect` form. +/// Say you want to look up the asset values of a list of handles when you have access to their `&dyn Reflect` form. /// Assets can be looked up in the world using [`ReflectAsset`], but how do you determine which [`ReflectAsset`] to use when /// only looking at the handle? [`ReflectHandle`] is stored in the type registry on each `Handle` type, so you can use [`ReflectHandle::asset_type_id`] to look up /// the [`ReflectAsset`] type data on the corresponding `T` asset type: @@ -203,7 +209,7 @@ impl FromType for ReflectAsset { /// /// # let world: &World = unimplemented!(); /// # let type_registry: TypeRegistry = unimplemented!(); -/// let handles: Vec<&dyn PartialReflect> = unimplemented!(); +/// let handles: Vec<&dyn Reflect> = unimplemented!(); /// for handle in handles { /// let reflect_handle = type_registry.get_type_data::(handle.type_id()).unwrap(); /// let reflect_asset = type_registry.get_type_data::(reflect_handle.asset_type_id()).unwrap(); @@ -218,7 +224,7 @@ pub struct ReflectHandle { type_uuid: Uuid, asset_type_id: TypeId, downcast_handle_untyped: fn(&dyn Any) -> Option, - typed: fn(HandleUntyped) -> Box, + typed: fn(HandleUntyped) -> Box, } impl ReflectHandle { /// The [`bevy_reflect::TypeUuid`] of the asset @@ -235,9 +241,9 @@ impl ReflectHandle { (self.downcast_handle_untyped)(handle) } - /// A way to go from a [`HandleUntyped`] to a [`Handle`] in a `Box`. + /// A way to go from a [`HandleUntyped`] to a [`Handle`] in a `Box`. /// Equivalent of [`HandleUntyped::typed`]. - pub fn typed(&self, handle: HandleUntyped) -> Box { + pub fn typed(&self, handle: HandleUntyped) -> Box { (self.typed)(handle) } } @@ -293,7 +299,7 @@ mod tests { field: "test".into(), }; - let handle = reflect_asset.add(&mut app.world, &value); + let handle = reflect_asset.add(&mut app.world, Box::new(value)); let strukt = match reflect_asset .get_mut(&mut app.world, handle) .unwrap() @@ -315,10 +321,7 @@ mod tests { let asset = reflect_asset .get(&app.world, fetched_handle.clone_weak()) .unwrap(); - assert_eq!( - asset.try_downcast_ref::().unwrap().field, - "edited" - ); + assert_eq!(asset.downcast_ref::().unwrap().field, "edited"); reflect_asset .remove(&mut app.world, fetched_handle) diff --git a/crates/bevy_core_pipeline/src/bloom/mod.rs b/crates/bevy_core_pipeline/src/bloom/mod.rs index 589dd241f3bb19..ad438b2a25dcf3 100644 --- a/crates/bevy_core_pipeline/src/bloom/mod.rs +++ b/crates/bevy_core_pipeline/src/bloom/mod.rs @@ -8,7 +8,7 @@ use bevy_ecs::{ world::{FromWorld, World}, }; use bevy_math::{UVec2, UVec4, Vec4}; -use bevy_reflect::{PartialReflect, Reflect, TypeUuid}; +use bevy_reflect::{Reflect, TypeUuid}; use bevy_render::{ camera::ExtractedCamera, extract_component::{ diff --git a/crates/bevy_pbr/src/bundle.rs b/crates/bevy_pbr/src/bundle.rs index 94b41c61a42471..0590dba4abdb6b 100644 --- a/crates/bevy_pbr/src/bundle.rs +++ b/crates/bevy_pbr/src/bundle.rs @@ -4,7 +4,7 @@ use crate::{ }; use bevy_asset::Handle; use bevy_ecs::{bundle::Bundle, component::Component, prelude::Entity, reflect::ReflectComponent}; -use bevy_reflect::{PartialReflect, Reflect}; +use bevy_reflect::Reflect; use bevy_render::{ mesh::Mesh, primitives::{CascadesFrusta, CubemapFrusta, Frustum}, diff --git a/crates/bevy_reflect/src/serde/de.rs b/crates/bevy_reflect/src/serde/de.rs index ff6e23251f7e28..7c91dd7e1619b5 100644 --- a/crates/bevy_reflect/src/serde/de.rs +++ b/crates/bevy_reflect/src/serde/de.rs @@ -375,7 +375,7 @@ impl<'a, 'de> DeserializeSeed<'de> for TypedReflectDeserializer<'a> { // Handle both Value case and types that have a custom `ReflectDeserialize` if let Some(deserialize_reflect) = self.registration.data::() { let value = deserialize_reflect.deserialize(deserializer)?; - return Ok(value); + return Ok(value.into_partial()); } match self.registration.type_info() { diff --git a/crates/bevy_reflect/src/serde/ser.rs b/crates/bevy_reflect/src/serde/ser.rs index 5f859e73b792b3..d00a0b9cb3f158 100644 --- a/crates/bevy_reflect/src/serde/ser.rs +++ b/crates/bevy_reflect/src/serde/ser.rs @@ -32,15 +32,21 @@ fn get_serializable<'a, E: serde::ser::Error>( reflect_value: &'a dyn PartialReflect, type_registry: &TypeRegistry, ) -> Result, E> { + let full_reflect = reflect_value.as_full().ok_or_else(|| { + serde::ser::Error::custom(format_args!( + "Type '{}' does not implement Reflect", + reflect_value.type_name(), + )) + })?; let reflect_serialize = type_registry - .get_type_data::(reflect_value.type_id()) + .get_type_data::(full_reflect.type_id()) .ok_or_else(|| { serde::ser::Error::custom(format_args!( "Type '{}' did not register ReflectSerialize", reflect_value.type_name() )) })?; - Ok(reflect_serialize.get_serializable(reflect_value)) + Ok(reflect_serialize.get_serializable(full_reflect)) } /// Get the underlying [`TypeInfo`] of a given type. diff --git a/crates/bevy_reflect/src/type_registry.rs b/crates/bevy_reflect/src/type_registry.rs index 0569ebb659f3a1..52f5df9115ee83 100644 --- a/crates/bevy_reflect/src/type_registry.rs +++ b/crates/bevy_reflect/src/type_registry.rs @@ -1,4 +1,4 @@ -use crate::{serde::Serializable, PartialReflect, Reflect, TypeInfo, Typed}; +use crate::{serde::Serializable, Reflect, TypeInfo}; use bevy_ptr::{Ptr, PtrMut}; use bevy_utils::{HashMap, HashSet}; use downcast_rs::{impl_downcast, Downcast}; @@ -124,7 +124,7 @@ impl TypeRegistry { /// type_registry.register_type_data::, ReflectSerialize>(); /// type_registry.register_type_data::, ReflectDeserialize>(); /// ``` - pub fn register_type_data>(&mut self) { + pub fn register_type_data>(&mut self) { let data = self.get_mut(TypeId::of::()).unwrap_or_else(|| { panic!( "attempted to call `TypeRegistry::register_type_data` for type `{T}` with data `{D}` without registering `{T}` first", @@ -268,8 +268,8 @@ impl TypeRegistryArc { /// /// [short name]: bevy_utils::get_short_name /// [`TypeInfo`]: crate::TypeInfo -/// [0]: crate::PartialReflect -/// [1]: crate::PartialReflect +/// [0]: crate::Reflect +/// [1]: crate::Reflect pub struct TypeRegistration { short_name: String, data: HashMap>, @@ -327,7 +327,7 @@ impl TypeRegistration { } /// Creates type registration information for `T`. - pub fn of() -> Self { + pub fn of() -> Self { let type_name = std::any::type_name::(); Self { data: HashMap::default(), @@ -396,15 +396,19 @@ pub trait FromType { /// [`FromType::from_type`]. #[derive(Clone)] pub struct ReflectSerialize { - get_serializable: for<'a> fn(value: &'a dyn PartialReflect) -> Serializable, + get_serializable: for<'a> fn(value: &'a dyn Reflect) -> Serializable, } impl FromType for ReflectSerialize { fn from_type() -> Self { ReflectSerialize { get_serializable: |value| { - let value = value.try_downcast_ref::().unwrap_or_else(|| { - panic!("ReflectSerialize::get_serialize called with type `{}`, even though it was created for `{}`", value.type_name(), std::any::type_name::()) + let value = value.downcast_ref::().unwrap_or_else(|| { + panic!( + "ReflectSerialize::get_serialize called with type `{}`, even though it was created for `{}`", + value.type_name(), + std::any::type_name::() + ) }); Serializable::Borrowed(value) }, @@ -414,7 +418,7 @@ impl FromType for ReflectSerialize { impl ReflectSerialize { /// Turn the value into a serializable representation - pub fn get_serializable<'a>(&self, value: &'a dyn PartialReflect) -> Serializable<'a> { + pub fn get_serializable<'a>(&self, value: &'a dyn Reflect) -> Serializable<'a> { (self.get_serializable)(value) } } @@ -427,7 +431,7 @@ impl ReflectSerialize { pub struct ReflectDeserialize { pub func: fn( deserializer: &mut dyn erased_serde::Deserializer, - ) -> Result, erased_serde::Error>, + ) -> Result, erased_serde::Error>, } impl ReflectDeserialize { @@ -436,7 +440,7 @@ impl ReflectDeserialize { /// The underlying type of the reflected value, and thus the expected /// structure of the serialized data, is determined by the type used to /// construct this `ReflectDeserialize` value. - pub fn deserialize<'de, D>(&self, deserializer: D) -> Result, D::Error> + pub fn deserialize<'de, D>(&self, deserializer: D) -> Result, D::Error> where D: serde::Deserializer<'de>, { @@ -446,7 +450,7 @@ impl ReflectDeserialize { } } -impl Deserialize<'a> + PartialReflect> FromType for ReflectDeserialize { +impl Deserialize<'a> + Reflect> FromType for ReflectDeserialize { fn from_type() -> Self { ReflectDeserialize { func: |deserializer| Ok(Box::new(T::deserialize(deserializer)?)), @@ -456,10 +460,10 @@ impl Deserialize<'a> + PartialReflect> FromType for ReflectDeseria /// [`Reflect`] values are commonly used in situations where the actual types of values /// are not known at runtime. In such situations you might have access to a `*const ()` pointer -/// that you know implements [`Reflect`], but have no way of turning it into a `&dyn PartialReflect`. +/// that you know implements [`Reflect`], but have no way of turning it into a `&dyn Reflect`. /// /// This is where [`ReflectFromPtr`] comes in, when creating a [`ReflectFromPtr`] for a given type `T: Reflect`. -/// Internally, this saves a concrete function `*const T -> const dyn PartialReflect` which lets you create a trait object of [`Reflect`] +/// Internally, this saves a concrete function `*const T -> const dyn Reflect` which lets you create a trait object of [`Reflect`] /// from a pointer. /// /// # Example @@ -482,13 +486,13 @@ impl Deserialize<'a> + PartialReflect> FromType for ReflectDeseria /// // SAFE: `value` is of type `Reflected`, which the `ReflectFromPtr` was created for /// let value = unsafe { reflect_from_ptr.as_reflect_ptr(value) }; /// -/// assert_eq!(value.try_downcast_ref::().unwrap().0, "Hello world!"); +/// assert_eq!(value.downcast_ref::().unwrap().0, "Hello world!"); /// ``` #[derive(Clone)] pub struct ReflectFromPtr { type_id: TypeId, - to_reflect: for<'a> unsafe fn(Ptr<'a>) -> &'a dyn PartialReflect, - to_reflect_mut: for<'a> unsafe fn(PtrMut<'a>) -> &'a mut dyn PartialReflect, + to_reflect: for<'a> unsafe fn(Ptr<'a>) -> &'a dyn Reflect, + to_reflect_mut: for<'a> unsafe fn(PtrMut<'a>) -> &'a mut dyn Reflect, } impl ReflectFromPtr { @@ -501,7 +505,7 @@ impl ReflectFromPtr { /// /// `val` must be a pointer to value of the type that the [`ReflectFromPtr`] was constructed for. /// This can be verified by checking that the type id returned by [`ReflectFromPtr::type_id`] is the expected one. - pub unsafe fn as_reflect_ptr<'a>(&self, val: Ptr<'a>) -> &'a dyn PartialReflect { + pub unsafe fn as_reflect_ptr<'a>(&self, val: Ptr<'a>) -> &'a dyn Reflect { (self.to_reflect)(val) } @@ -509,24 +513,24 @@ impl ReflectFromPtr { /// /// `val` must be a pointer to a value of the type that the [`ReflectFromPtr`] was constructed for /// This can be verified by checking that the type id returned by [`ReflectFromPtr::type_id`] is the expected one. - pub unsafe fn as_reflect_ptr_mut<'a>(&self, val: PtrMut<'a>) -> &'a mut dyn PartialReflect { + pub unsafe fn as_reflect_ptr_mut<'a>(&self, val: PtrMut<'a>) -> &'a mut dyn Reflect { (self.to_reflect_mut)(val) } } -impl FromType for ReflectFromPtr { +impl FromType for ReflectFromPtr { fn from_type() -> Self { ReflectFromPtr { type_id: std::any::TypeId::of::(), to_reflect: |ptr| { // SAFE: only called from `as_reflect`, where the `ptr` is guaranteed to be of type `T`, // and `as_reflect_ptr`, where the caller promises to call it with type `T` - unsafe { ptr.deref::() as &dyn PartialReflect } + unsafe { ptr.deref::() as &dyn Reflect } }, to_reflect_mut: |ptr| { // SAFE: only called from `as_reflect_mut`, where the `ptr` is guaranteed to be of type `T`, // and `as_reflect_ptr_mut`, where the caller promises to call it with type `T` - unsafe { ptr.deref_mut::() as &mut dyn PartialReflect } + unsafe { ptr.deref_mut::() as &mut dyn Reflect } }, } } diff --git a/crates/bevy_ui/src/focus.rs b/crates/bevy_ui/src/focus.rs index 5044dcc0a9936e..b30062818dac18 100644 --- a/crates/bevy_ui/src/focus.rs +++ b/crates/bevy_ui/src/focus.rs @@ -10,7 +10,7 @@ use bevy_ecs::{ }; use bevy_input::{mouse::MouseButton, touch::Touches, Input}; use bevy_math::Vec2; -use bevy_reflect::{PartialReflect, Reflect, ReflectDeserialize, ReflectSerialize}; +use bevy_reflect::{Reflect, ReflectDeserialize, ReflectSerialize}; use bevy_render::{camera::NormalizedRenderTarget, prelude::Camera, view::ComputedVisibility}; use bevy_transform::components::GlobalTransform;