From c81ca57ba32ecc3287a5d4ff345a02526ef2dc29 Mon Sep 17 00:00:00 2001 From: Gino Valente Date: Thu, 11 Aug 2022 15:23:46 -0700 Subject: [PATCH 1/4] Bound Option reflection by FromReflect --- crates/bevy_reflect/src/impls/std.rs | 29 ++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/crates/bevy_reflect/src/impls/std.rs b/crates/bevy_reflect/src/impls/std.rs index 7b66aba360249..7937c42ebfff4 100644 --- a/crates/bevy_reflect/src/impls/std.rs +++ b/crates/bevy_reflect/src/impls/std.rs @@ -585,13 +585,13 @@ impl Reflect for Cow<'static, str> { } } -impl GetTypeRegistration for Option { +impl GetTypeRegistration for Option { fn get_type_registration() -> TypeRegistration { TypeRegistration::of::>() } } -impl Enum for Option { +impl Enum for Option { fn field(&self, _name: &str) -> Option<&dyn Reflect> { None } @@ -655,7 +655,7 @@ impl Enum for Option { } } -impl Reflect for Option { +impl Reflect for Option { #[inline] fn type_name(&self) -> &str { std::any::type_name::() @@ -741,7 +741,7 @@ impl Reflect for Option { #[inline] fn clone_value(&self) -> Box { - Box::new(self.clone()) + Box::new(Enum::clone_dynamic(self)) } fn reflect_hash(&self) -> Option { @@ -753,7 +753,7 @@ impl Reflect for Option { } } -impl FromReflect for Option { +impl FromReflect for Option { fn from_reflect(reflect: &dyn Reflect) -> Option { if let ReflectRef::Enum(dyn_enum) = reflect.reflect_ref() { match dyn_enum.variant_name() { @@ -762,7 +762,7 @@ impl FromReflect for Option { .field_at(0) .expect("Field at index 0 should exist") .clone_value(); - let field = field.take::().unwrap_or_else(|_| { + let field = T::from_reflect(field.as_ref()).unwrap_or_else(|| { panic!( "Field at index 0 should be of type {}", std::any::type_name::() @@ -783,7 +783,7 @@ impl FromReflect for Option { } } -impl Typed for Option { +impl Typed for Option { fn type_info() -> &'static TypeInfo { static CELL: GenericTypeInfoCell = GenericTypeInfoCell::new(); CELL.get_or_insert::(|| { @@ -827,8 +827,10 @@ impl FromReflect for Cow<'static, str> { #[cfg(test)] mod tests { + use crate as bevy_reflect; use crate::{ - Enum, Reflect, ReflectSerialize, TypeInfo, TypeRegistry, Typed, VariantInfo, VariantType, + Enum, FromReflect, Reflect, ReflectSerialize, TypeInfo, TypeRegistry, Typed, VariantInfo, + VariantType, }; use bevy_utils::HashMap; use std::f32::consts::{PI, TAU}; @@ -939,6 +941,17 @@ mod tests { assert_eq!(Some(321), value); } + #[test] + fn option_should_from_reflect() { + #[derive(Reflect, FromReflect, PartialEq, Debug)] + struct Foo(usize); + + let expected = Some(Foo(123)); + let output = as FromReflect>::from_reflect(&expected).unwrap(); + + assert_eq!(expected, output); + } + #[test] fn option_should_impl_typed() { type MyOption = Option; From 50a2588ea916810141322b86eaf605124382db1a Mon Sep 17 00:00:00 2001 From: Gino Valente Date: Thu, 11 Aug 2022 15:44:54 -0700 Subject: [PATCH 2/4] Add FromReflect impl for Instant --- crates/bevy_reflect/src/impls/std.rs | 10 +++++++++- crates/bevy_time/src/time.rs | 4 ++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/crates/bevy_reflect/src/impls/std.rs b/crates/bevy_reflect/src/impls/std.rs index 7937c42ebfff4..90fa58dc372ec 100644 --- a/crates/bevy_reflect/src/impls/std.rs +++ b/crates/bevy_reflect/src/impls/std.rs @@ -76,6 +76,7 @@ impl_from_reflect_value!(String); impl_from_reflect_value!(HashSet); impl_from_reflect_value!(Range); impl_from_reflect_value!(Duration); +impl_from_reflect_value!(Instant); impl_from_reflect_value!(NonZeroI128); impl_from_reflect_value!(NonZeroU128); impl_from_reflect_value!(NonZeroIsize); @@ -832,7 +833,7 @@ mod tests { Enum, FromReflect, Reflect, ReflectSerialize, TypeInfo, TypeRegistry, Typed, VariantInfo, VariantType, }; - use bevy_utils::HashMap; + use bevy_utils::{HashMap, Instant}; use std::f32::consts::{PI, TAU}; #[test] @@ -992,4 +993,11 @@ mod tests { let forty_two: std::num::NonZeroUsize = crate::FromReflect::from_reflect(a).unwrap(); assert_eq!(forty_two, std::num::NonZeroUsize::new(42).unwrap()); } + + #[test] + fn instant_should_from_reflect() { + let expected = Instant::now(); + let output = ::from_reflect(&expected).unwrap(); + assert_eq!(expected, output); + } } diff --git a/crates/bevy_time/src/time.rs b/crates/bevy_time/src/time.rs index 8cb864882f25e..1835f841c93a7 100644 --- a/crates/bevy_time/src/time.rs +++ b/crates/bevy_time/src/time.rs @@ -1,9 +1,9 @@ use bevy_ecs::{reflect::ReflectResource, system::Resource}; -use bevy_reflect::Reflect; +use bevy_reflect::{FromReflect, Reflect}; use bevy_utils::{Duration, Instant}; /// Tracks elapsed time since the last update and since the App has started -#[derive(Resource, Reflect, Debug, Clone)] +#[derive(Resource, Reflect, FromReflect, Debug, Clone)] #[reflect(Resource)] pub struct Time { delta: Duration, From c24a85a6c85137ac4351c3eea489e6c6f41e8479 Mon Sep 17 00:00:00 2001 From: Gino Valente Date: Thu, 11 Aug 2022 15:48:28 -0700 Subject: [PATCH 3/4] Update derives with FromReflect --- crates/bevy_render/src/camera/camera.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/bevy_render/src/camera/camera.rs b/crates/bevy_render/src/camera/camera.rs index f81c5b6ad1aed..bbfac5b1f28b8 100644 --- a/crates/bevy_render/src/camera/camera.rs +++ b/crates/bevy_render/src/camera/camera.rs @@ -32,7 +32,7 @@ use wgpu::Extent3d; /// You can overlay multiple cameras in a single window using viewports to create effects like /// split screen, minimaps, and character viewers. // TODO: remove reflect_value when possible -#[derive(Reflect, Debug, Clone, Serialize, Deserialize)] +#[derive(Reflect, FromReflect, Debug, Clone, Serialize, Deserialize)] #[reflect_value(Default, Serialize, Deserialize)] pub struct Viewport { /// The physical position to render this viewport to within the [`RenderTarget`] of this [`Camera`]. @@ -71,7 +71,7 @@ pub struct ComputedCameraValues { target_info: Option, } -#[derive(Component, Debug, Reflect, Clone)] +#[derive(Component, Debug, Reflect, FromReflect, Clone)] #[reflect(Component)] pub struct Camera { /// If set, this camera will render to the given [`Viewport`] rectangle within the configured [`RenderTarget`]. From 50f7a5edebd96ee6134742250bddd5609c80a827 Mon Sep 17 00:00:00 2001 From: Gino Valente Date: Tue, 16 Aug 2022 17:09:11 -0700 Subject: [PATCH 4/4] Import FromReflect --- crates/bevy_render/src/camera/camera.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/bevy_render/src/camera/camera.rs b/crates/bevy_render/src/camera/camera.rs index bbfac5b1f28b8..0bfd3c5a7de03 100644 --- a/crates/bevy_render/src/camera/camera.rs +++ b/crates/bevy_render/src/camera/camera.rs @@ -19,6 +19,7 @@ use bevy_ecs::{ }; use bevy_math::{Mat4, UVec2, Vec2, Vec3}; use bevy_reflect::prelude::*; +use bevy_reflect::FromReflect; use bevy_transform::components::GlobalTransform; use bevy_utils::HashSet; use bevy_window::{WindowCreated, WindowId, WindowResized, Windows};