Skip to content

Commit b840db9

Browse files
committed
Alter Reflect::*_any methods to return remote type
1 parent a3195c0 commit b840db9

File tree

7 files changed

+73
-52
lines changed

7 files changed

+73
-52
lines changed
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
use quote::quote;
2+
3+
/// A helper function for quickly implementing the `Reflect::*_any` methods while taking remote types into account.
4+
///
5+
/// Specifically, this handles `Reflect::into_any`, `Reflect::as_any`, and `Reflect::as_any_mut`.
6+
pub(crate) fn impl_reflect_any_methods(is_remote_wrapper: bool) -> proc_macro2::TokenStream {
7+
if is_remote_wrapper {
8+
quote! {
9+
#[inline]
10+
fn into_any(self: Box<Self>) -> Box<dyn ::std::any::Any> {
11+
Box::new(self.0)
12+
}
13+
14+
#[inline]
15+
fn as_any(&self) -> &dyn ::std::any::Any {
16+
&self.0
17+
}
18+
19+
#[inline]
20+
fn as_any_mut(&mut self) -> &mut dyn ::std::any::Any {
21+
&mut self.0
22+
}
23+
}
24+
} else {
25+
quote! {
26+
#[inline]
27+
fn into_any(self: Box<Self>) -> Box<dyn ::std::any::Any> {
28+
self
29+
}
30+
31+
#[inline]
32+
fn as_any(&self) -> &dyn ::std::any::Any {
33+
self
34+
}
35+
36+
#[inline]
37+
fn as_any_mut(&mut self) -> &mut dyn ::std::any::Any {
38+
self
39+
}
40+
}
41+
}
42+
}

crates/bevy_reflect/bevy_reflect_derive/src/impls/enums.rs

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::derive_data::{EnumVariantFields, ReflectEnum, StructField};
22
use crate::enum_utility::{get_variant_constructors, EnumVariantConstructors};
3+
use crate::impls::any::impl_reflect_any_methods;
34
use crate::impls::impl_typed;
45
use proc_macro::TokenStream;
56
use proc_macro2::{Ident, Span};
@@ -88,6 +89,8 @@ pub(crate) fn impl_enum(reflect_enum: &ReflectEnum) -> TokenStream {
8889
bevy_reflect_path,
8990
);
9091

92+
let any_impls = impl_reflect_any_methods(reflect_enum.is_remote_wrapper());
93+
9194
let get_type_registration_impl = reflect_enum.meta().get_type_registration();
9295
let (impl_generics, ty_generics, where_clause) =
9396
reflect_enum.meta().generics().split_for_impl();
@@ -192,20 +195,7 @@ pub(crate) fn impl_enum(reflect_enum: &ReflectEnum) -> TokenStream {
192195
<Self as #bevy_reflect_path::Typed>::type_info()
193196
}
194197

195-
#[inline]
196-
fn into_any(self: Box<Self>) -> Box<dyn std::any::Any> {
197-
self
198-
}
199-
200-
#[inline]
201-
fn as_any(&self) -> &dyn std::any::Any {
202-
self
203-
}
204-
205-
#[inline]
206-
fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
207-
self
208-
}
198+
#any_impls
209199

210200
#[inline]
211201
fn as_reflect(&self) -> &dyn #bevy_reflect_path::Reflect {

crates/bevy_reflect/bevy_reflect_derive/src/impls/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
mod any;
12
mod enums;
23
mod structs;
34
mod tuple_structs;

crates/bevy_reflect/bevy_reflect_derive/src/impls/structs.rs

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use crate::impls::any::impl_reflect_any_methods;
12
use crate::impls::impl_typed;
23
use crate::struct_utility::FieldAccessors;
34
use crate::ReflectStruct;
@@ -25,7 +26,7 @@ pub(crate) fn impl_struct(reflect_struct: &ReflectStruct) -> TokenStream {
2526
fields_ref,
2627
fields_mut,
2728
field_indices,
28-
field_count
29+
field_count,
2930
} = FieldAccessors::new(reflect_struct);
3031
let field_types = reflect_struct.active_types();
3132

@@ -59,6 +60,8 @@ pub(crate) fn impl_struct(reflect_struct: &ReflectStruct) -> TokenStream {
5960
bevy_reflect_path,
6061
);
6162

63+
let any_impls = impl_reflect_any_methods(reflect_struct.is_remote_wrapper());
64+
6265
let get_type_registration_impl = reflect_struct.get_type_registration();
6366
let (impl_generics, ty_generics, where_clause) =
6467
reflect_struct.meta().generics().split_for_impl();
@@ -131,20 +134,7 @@ pub(crate) fn impl_struct(reflect_struct: &ReflectStruct) -> TokenStream {
131134
<Self as #bevy_reflect_path::Typed>::type_info()
132135
}
133136

134-
#[inline]
135-
fn into_any(self: Box<Self>) -> Box<dyn std::any::Any> {
136-
self
137-
}
138-
139-
#[inline]
140-
fn as_any(&self) -> &dyn std::any::Any {
141-
self
142-
}
143-
144-
#[inline]
145-
fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
146-
self
147-
}
137+
#any_impls
148138

149139
#[inline]
150140
fn as_reflect(&self) -> &dyn #bevy_reflect_path::Reflect {

crates/bevy_reflect/bevy_reflect_derive/src/impls/tuple_structs.rs

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use crate::impls::any::impl_reflect_any_methods;
12
use crate::impls::impl_typed;
23
use crate::struct_utility::FieldAccessors;
34
use crate::ReflectStruct;
@@ -50,6 +51,8 @@ pub(crate) fn impl_tuple_struct(reflect_struct: &ReflectStruct) -> TokenStream {
5051
bevy_reflect_path,
5152
);
5253

54+
let any_impls = impl_reflect_any_methods(reflect_struct.is_remote_wrapper());
55+
5356
let (impl_generics, ty_generics, where_clause) =
5457
reflect_struct.meta().generics().split_for_impl();
5558

@@ -100,20 +103,7 @@ pub(crate) fn impl_tuple_struct(reflect_struct: &ReflectStruct) -> TokenStream {
100103
<Self as #bevy_reflect_path::Typed>::type_info()
101104
}
102105

103-
#[inline]
104-
fn into_any(self: Box<Self>) -> Box<dyn std::any::Any> {
105-
self
106-
}
107-
108-
#[inline]
109-
fn as_any(&self) -> &dyn std::any::Any {
110-
self
111-
}
112-
113-
#[inline]
114-
fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
115-
self
116-
}
106+
#any_impls
117107

118108
#[inline]
119109
fn as_reflect(&self) -> &dyn #bevy_reflect_path::Reflect {

crates/bevy_reflect/src/lib.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1141,12 +1141,14 @@ bevy_reflect::tests::should_reflect_debug::Test {
11411141
value: "Hello".to_string(),
11421142
}));
11431143

1144-
let output: MyType = input.take().expect("data should be of type `MyType`");
1144+
let output: external_crate::TheirType = input
1145+
.take()
1146+
.expect("should downcast to `external_crate::TheirType`");
11451147
assert_eq!(
11461148
external_crate::TheirType {
11471149
value: "Hello".to_string(),
11481150
},
1149-
output.0
1151+
output
11501152
);
11511153
}
11521154

crates/bevy_reflect/src/reflect.rs

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -67,12 +67,18 @@ pub trait Reflect: Any + Send + Sync {
6767
fn get_type_info(&self) -> &'static TypeInfo;
6868

6969
/// Returns the value as a [`Box<dyn Any>`][std::any::Any].
70+
///
71+
/// For remote wrapper types, this will return the remote type instead.
7072
fn into_any(self: Box<Self>) -> Box<dyn Any>;
7173

7274
/// Returns the value as a [`&dyn Any`][std::any::Any].
75+
///
76+
/// For remote wrapper types, this will return the remote type instead.
7377
fn as_any(&self) -> &dyn Any;
7478

7579
/// Returns the value as a [`&mut dyn Any`][std::any::Any].
80+
///
81+
/// For remote wrapper types, this will return the remote type instead.
7682
fn as_any_mut(&mut self) -> &mut dyn Any;
7783

7884
/// Casts this type to a reflected value
@@ -223,7 +229,7 @@ impl dyn Reflect {
223229
/// Downcasts the value to type `T`, consuming the trait object.
224230
///
225231
/// If the underlying value is not of type `T`, returns `Err(self)`.
226-
pub fn downcast<T: Reflect>(self: Box<dyn Reflect>) -> Result<Box<T>, Box<dyn Reflect>> {
232+
pub fn downcast<T: Any>(self: Box<dyn Reflect>) -> Result<Box<T>, Box<dyn Reflect>> {
227233
if self.is::<T>() {
228234
Ok(self.into_any().downcast().unwrap())
229235
} else {
@@ -234,7 +240,7 @@ impl dyn Reflect {
234240
/// Downcasts the value to type `T`, unboxing and consuming the trait object.
235241
///
236242
/// If the underlying value is not of type `T`, returns `Err(self)`.
237-
pub fn take<T: Reflect>(self: Box<dyn Reflect>) -> Result<T, Box<dyn Reflect>> {
243+
pub fn take<T: Any>(self: Box<dyn Reflect>) -> Result<T, Box<dyn Reflect>> {
238244
self.downcast::<T>().map(|value| *value)
239245
}
240246

@@ -243,7 +249,7 @@ impl dyn Reflect {
243249
///
244250
/// Read `is` for more information on underlying values and represented types.
245251
#[inline]
246-
pub fn represents<T: Reflect>(&self) -> bool {
252+
pub fn represents<T: Any>(&self) -> bool {
247253
self.type_name() == any::type_name::<T>()
248254
}
249255

@@ -256,23 +262,23 @@ impl dyn Reflect {
256262
/// to determine what type they represent. Represented types cannot be downcasted
257263
/// to, but you can use [`FromReflect`] to create a value of the represented type from them.
258264
#[inline]
259-
pub fn is<T: Reflect>(&self) -> bool {
260-
self.type_id() == TypeId::of::<T>()
265+
pub fn is<T: Any>(&self) -> bool {
266+
self.as_any().type_id() == TypeId::of::<T>()
261267
}
262268

263269
/// Downcasts the value to type `T` by reference.
264270
///
265271
/// If the underlying value is not of type `T`, returns `None`.
266272
#[inline]
267-
pub fn downcast_ref<T: Reflect>(&self) -> Option<&T> {
273+
pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
268274
self.as_any().downcast_ref::<T>()
269275
}
270276

271277
/// Downcasts the value to type `T` by mutable reference.
272278
///
273279
/// If the underlying value is not of type `T`, returns `None`.
274280
#[inline]
275-
pub fn downcast_mut<T: Reflect>(&mut self) -> Option<&mut T> {
281+
pub fn downcast_mut<T: Any>(&mut self) -> Option<&mut T> {
276282
self.as_any_mut().downcast_mut::<T>()
277283
}
278284
}

0 commit comments

Comments
 (0)