Skip to content

Commit 5affe80

Browse files
committed
Unhide ToPartialReflect and ToReflect
Also moved these traits to a new `cast` module
1 parent fe6e822 commit 5affe80

File tree

3 files changed

+186
-108
lines changed

3 files changed

+186
-108
lines changed

crates/bevy_reflect/src/boxed.rs

Lines changed: 6 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -2,121 +2,14 @@ use core::fmt::Formatter;
22
use std::any::Any;
33

44
use crate::__macro_exports::RegisterForReflection;
5+
use crate::cast::{ToPartialReflect, ToReflect};
56
use crate::serde::Serializable;
67
use crate::utility::GenericTypePathCell;
78
use crate::{
89
ApplyError, MaybeTyped, PartialReflect, Reflect, ReflectKind, ReflectMut, ReflectOwned,
910
ReflectRef, ReflectRemote, TypeInfo, TypePath,
1011
};
1112

12-
/// A trait used to access `Self` as a [`dyn PartialReflect`].
13-
///
14-
/// This is used to provide by [`ReflectBox<T>`] in order to remotely reflect
15-
/// the inner type, `T`.
16-
///
17-
/// This trait can be implemented on custom trait objects to allow them to be remotely reflected
18-
/// by [`ReflectBox`].
19-
///
20-
/// [`dyn PartialReflect`]: PartialReflect
21-
#[doc(hidden)]
22-
pub trait ToPartialReflect: Send + Sync + 'static {
23-
/// Get a reference to `Self` as a [`&dyn PartialReflect`](PartialReflect).
24-
fn to_partial_reflect_ref(&self) -> &dyn PartialReflect;
25-
/// Get a mutable reference to `Self` as a [`&mut dyn PartialReflect`](PartialReflect).
26-
fn to_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect;
27-
/// Take `Self` as a [`Box<dyn PartialReflect>`](PartialReflect).
28-
fn to_partial_reflect_box(self: Box<Self>) -> Box<dyn PartialReflect>;
29-
}
30-
31-
impl<T: PartialReflect> ToPartialReflect for T {
32-
fn to_partial_reflect_ref(&self) -> &dyn PartialReflect {
33-
self
34-
}
35-
36-
fn to_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect {
37-
self
38-
}
39-
40-
fn to_partial_reflect_box(self: Box<Self>) -> Box<dyn PartialReflect> {
41-
self
42-
}
43-
}
44-
45-
impl ToPartialReflect for dyn PartialReflect {
46-
fn to_partial_reflect_ref(&self) -> &dyn PartialReflect {
47-
self
48-
}
49-
50-
fn to_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect {
51-
self
52-
}
53-
54-
fn to_partial_reflect_box(self: Box<Self>) -> Box<dyn PartialReflect> {
55-
self
56-
}
57-
}
58-
59-
/// A trait used to access `Self` as a [`dyn Reflect`].
60-
///
61-
/// This is used to provide by [`ReflectBox<T>`] in order to remotely reflect
62-
/// the inner type, `T`.
63-
///
64-
/// This trait can be implemented on custom trait objects to allow them to be remotely reflected
65-
/// by [`ReflectBox`].
66-
///
67-
/// [`dyn Reflect`]: Reflect
68-
#[doc(hidden)]
69-
pub trait ToReflect: ToPartialReflect {
70-
/// Get a reference to `Self` as a [`&dyn Reflect`](Reflect).
71-
fn to_reflect_ref(&self) -> &dyn Reflect;
72-
/// Get a mutable reference to `Self` as a [`&mut dyn Reflect`](Reflect).
73-
fn to_reflect_mut(&mut self) -> &mut dyn Reflect;
74-
/// Take `Self` as a [`Box<dyn Reflect>`](Reflect).
75-
fn to_reflect_box(self: Box<Self>) -> Box<dyn Reflect>;
76-
}
77-
78-
impl<T: Reflect> ToReflect for T {
79-
fn to_reflect_ref(&self) -> &dyn Reflect {
80-
self
81-
}
82-
83-
fn to_reflect_mut(&mut self) -> &mut dyn Reflect {
84-
self
85-
}
86-
87-
fn to_reflect_box(self: Box<Self>) -> Box<dyn Reflect> {
88-
self
89-
}
90-
}
91-
92-
impl ToPartialReflect for dyn Reflect {
93-
fn to_partial_reflect_ref(&self) -> &dyn PartialReflect {
94-
self.as_partial_reflect()
95-
}
96-
97-
fn to_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect {
98-
self.as_partial_reflect_mut()
99-
}
100-
101-
fn to_partial_reflect_box(self: Box<Self>) -> Box<dyn PartialReflect> {
102-
self.into_partial_reflect()
103-
}
104-
}
105-
106-
impl ToReflect for dyn Reflect {
107-
fn to_reflect_ref(&self) -> &dyn Reflect {
108-
self
109-
}
110-
111-
fn to_reflect_mut(&mut self) -> &mut dyn Reflect {
112-
self
113-
}
114-
115-
fn to_reflect_box(self: Box<Self>) -> Box<dyn Reflect> {
116-
self
117-
}
118-
}
119-
12013
/// A [remote wrapper] type around [`Box<T>`] where `T` is either a type that implements [`PartialReflect`]/[`Reflect`]
12114
/// or a [`dyn PartialReflect`]/[`dyn Reflect`] trait object.
12215
///
@@ -126,6 +19,10 @@ impl ToReflect for dyn Reflect {
12619
/// [`ReflectBox`] should never be created or used directly outside remote reflection,
12720
/// in order to avoid double-boxing.
12821
///
22+
/// Along with supporting reflection for `Box<dyn Reflect>`, `Box<dyn PartialReflect>`, and `Box<T: PartialReflect>`,
23+
/// [`ReflectBox`] can also be used to reflect any boxed trait object that is compatible with reflection.
24+
/// This can be achieved by implementing [`ToPartialReflect`] and [`ToReflect`] for the custom trait object type.
25+
///
12926
/// # Examples
13027
///
13128
/// ```
@@ -164,6 +61,7 @@ impl ToReflect for dyn Reflect {
16461
/// [remote wrapper]: ReflectRemote
16562
/// [`dyn PartialReflect`]: PartialReflect
16663
/// [`dyn Reflect`]: Reflect
64+
/// [`cast`]: crate::cast
16765
#[repr(transparent)]
16866
pub struct ReflectBox<T: ?Sized + ToPartialReflect + TypePath>(Box<T>);
16967

crates/bevy_reflect/src/cast.rs

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
//! Traits for casting types to [`dyn PartialReflect`] and [`dyn Reflect`] trait objects.
2+
//!
3+
//! These traits are primarily used by [`ReflectBox`] to cast the inner type to
4+
//! the corresponding reflection trait object.
5+
//!
6+
//! # Example
7+
//!
8+
//! ```
9+
//! # use bevy_reflect::cast::{ToPartialReflect, ToReflect};
10+
//! # use bevy_reflect::{PartialReflect, Reflect, TypePath};
11+
//!
12+
//! // A custom trait used to represent equippable items
13+
//! trait Equippable: Reflect {}
14+
//!
15+
//! impl TypePath for dyn Equippable {
16+
//! fn type_path() -> &'static str {
17+
//! "dyn my_crate::equipment::Equippable"
18+
//! }
19+
//!
20+
//! fn short_type_path() -> &'static str {
21+
//! "dyn Equippable"
22+
//! }
23+
//! }
24+
//!
25+
//! impl ToPartialReflect for dyn Equippable {
26+
//! fn to_partial_reflect_ref(&self) -> &dyn PartialReflect {
27+
//! self.as_partial_reflect()
28+
//! }
29+
//!
30+
//! fn to_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect {
31+
//! self.as_partial_reflect_mut()
32+
//! }
33+
//!
34+
//! fn to_partial_reflect_box(self: Box<Self>) -> Box<dyn PartialReflect> {
35+
//! self.into_partial_reflect()
36+
//! }
37+
//! }
38+
//!
39+
//! impl ToReflect for dyn Equippable {
40+
//! fn to_reflect_ref(&self) -> &dyn Reflect {
41+
//! self.as_reflect()
42+
//! }
43+
//!
44+
//! fn to_reflect_mut(&mut self) -> &mut dyn Reflect {
45+
//! self.as_reflect_mut()
46+
//! }
47+
//!
48+
//! fn to_reflect_box(self: Box<Self>) -> Box<dyn Reflect> {
49+
//! self.into_reflect()
50+
//! }
51+
//! }
52+
//!
53+
//! #[derive(Reflect)]
54+
//! #[reflect(from_reflect = false)]
55+
//! struct Player {
56+
//! // Now `dyn Equippable` can be used with `ReflectBox`:
57+
//! #[reflect(remote = ReflectBox<dyn Equippable>)]
58+
//! weapon: Box<dyn Equippable>,
59+
//! }
60+
//! ```
61+
//!
62+
//! [`dyn PartialReflect`]: PartialReflect
63+
//! [`dyn Reflect`]: Reflect
64+
65+
use crate::{PartialReflect, Reflect};
66+
67+
/// A trait used to access `Self` as a [`dyn PartialReflect`].
68+
///
69+
/// This is used by [`ReflectBox<T>`] in order to remotely reflect the inner type, `T`.
70+
/// In most cases, [`PartialReflect`] should be used instead of this trait.
71+
///
72+
/// This trait can be implemented on custom trait objects to allow them to be remotely reflected
73+
/// by [`ReflectBox`].
74+
///
75+
/// See the [module-level documentation] for details.
76+
///
77+
/// [`dyn PartialReflect`]: PartialReflect
78+
/// [`ReflectBox<T>`]: crate::boxed::ReflectBox
79+
/// [module-level documentation]: crate::cast
80+
pub trait ToPartialReflect: Send + Sync + 'static {
81+
/// Get a reference to `Self` as a [`&dyn PartialReflect`](PartialReflect).
82+
fn to_partial_reflect_ref(&self) -> &dyn PartialReflect;
83+
/// Get a mutable reference to `Self` as a [`&mut dyn PartialReflect`](PartialReflect).
84+
fn to_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect;
85+
/// Take `Self` as a [`Box<dyn PartialReflect>`](PartialReflect).
86+
fn to_partial_reflect_box(self: Box<Self>) -> Box<dyn PartialReflect>;
87+
}
88+
89+
impl<T: PartialReflect> ToPartialReflect for T {
90+
fn to_partial_reflect_ref(&self) -> &dyn PartialReflect {
91+
self
92+
}
93+
94+
fn to_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect {
95+
self
96+
}
97+
98+
fn to_partial_reflect_box(self: Box<Self>) -> Box<dyn PartialReflect> {
99+
self
100+
}
101+
}
102+
103+
impl ToPartialReflect for dyn PartialReflect {
104+
fn to_partial_reflect_ref(&self) -> &dyn PartialReflect {
105+
self
106+
}
107+
108+
fn to_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect {
109+
self
110+
}
111+
112+
fn to_partial_reflect_box(self: Box<Self>) -> Box<dyn PartialReflect> {
113+
self
114+
}
115+
}
116+
117+
/// A trait used to access `Self` as a [`dyn Reflect`].
118+
///
119+
/// This is used by [`ReflectBox<T>`] in order to remotely reflect the inner type, `T`.
120+
/// In most cases, [`Reflect`] should be used instead of this trait.
121+
///
122+
/// This trait can be implemented on custom trait objects to allow them to be remotely reflected
123+
/// by [`ReflectBox`].
124+
///
125+
/// See the [module-level documentation] for details.
126+
///
127+
/// [`dyn Reflect`]: Reflect
128+
/// [`ReflectBox<T>`]: crate::boxed::ReflectBox
129+
/// [module-level documentation]: crate::cast
130+
pub trait ToReflect: ToPartialReflect {
131+
/// Get a reference to `Self` as a [`&dyn Reflect`](Reflect).
132+
fn to_reflect_ref(&self) -> &dyn Reflect;
133+
/// Get a mutable reference to `Self` as a [`&mut dyn Reflect`](Reflect).
134+
fn to_reflect_mut(&mut self) -> &mut dyn Reflect;
135+
/// Take `Self` as a [`Box<dyn Reflect>`](Reflect).
136+
fn to_reflect_box(self: Box<Self>) -> Box<dyn Reflect>;
137+
}
138+
139+
impl<T: Reflect> ToReflect for T {
140+
fn to_reflect_ref(&self) -> &dyn Reflect {
141+
self
142+
}
143+
144+
fn to_reflect_mut(&mut self) -> &mut dyn Reflect {
145+
self
146+
}
147+
148+
fn to_reflect_box(self: Box<Self>) -> Box<dyn Reflect> {
149+
self
150+
}
151+
}
152+
153+
impl ToPartialReflect for dyn Reflect {
154+
fn to_partial_reflect_ref(&self) -> &dyn PartialReflect {
155+
self.as_partial_reflect()
156+
}
157+
158+
fn to_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect {
159+
self.as_partial_reflect_mut()
160+
}
161+
162+
fn to_partial_reflect_box(self: Box<Self>) -> Box<dyn PartialReflect> {
163+
self.into_partial_reflect()
164+
}
165+
}
166+
167+
impl ToReflect for dyn Reflect {
168+
fn to_reflect_ref(&self) -> &dyn Reflect {
169+
self
170+
}
171+
172+
fn to_reflect_mut(&mut self) -> &mut dyn Reflect {
173+
self
174+
}
175+
176+
fn to_reflect_box(self: Box<Self>) -> Box<dyn Reflect> {
177+
self
178+
}
179+
}

crates/bevy_reflect/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -527,6 +527,7 @@
527527
528528
mod array;
529529
pub mod boxed;
530+
pub mod cast;
530531
mod fields;
531532
mod from_reflect;
532533
#[cfg(feature = "functions")]

0 commit comments

Comments
 (0)