Skip to content

Commit cd78fbf

Browse files
committed
downcasting for dyn type
1 parent 40cda8b commit cd78fbf

File tree

2 files changed

+49
-0
lines changed

2 files changed

+49
-0
lines changed

fyrox-core/src/dyntype.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,13 @@ use std::{
2828
use uuid::Uuid;
2929

3030
pub enum DynTypeError {
31+
Empty,
3132
NoConstructorContainerProvided,
3233
NoConstructorForTypeUuid(Uuid),
34+
TypeCast {
35+
actual_type_name: &'static str,
36+
requested_type_name: &'static str,
37+
},
3338
}
3439

3540
impl DynTypeError {
@@ -55,6 +60,19 @@ impl Display for DynTypeError {
5560
there's no constructor provided for the {uuid} type!"
5661
)
5762
}
63+
DynTypeError::Empty => {
64+
write!(f, "The container is empty")
65+
}
66+
DynTypeError::TypeCast {
67+
actual_type_name,
68+
requested_type_name,
69+
} => {
70+
write!(
71+
f,
72+
"The actual type ({actual_type_name}) of the \
73+
dynamic type is different ({requested_type_name})."
74+
)
75+
}
5876
}
5977
}
6078
}
@@ -207,6 +225,27 @@ impl DynTypeContainer {
207225
pub fn value_mut(&mut self) -> Option<&mut dyn DynType> {
208226
self.0.as_mut().map(|v| &mut *v.0)
209227
}
228+
229+
pub fn data_ref<T: DynType>(&self) -> Result<&T, DynTypeError> {
230+
let value = self.value_ref().ok_or(DynTypeError::Empty)?;
231+
(value as &dyn Any)
232+
.downcast_ref()
233+
.ok_or_else(|| DynTypeError::TypeCast {
234+
actual_type_name: Reflect::type_name(value),
235+
requested_type_name: type_name::<T>(),
236+
})
237+
}
238+
239+
pub fn data_mut<T: DynType>(&mut self) -> Result<&mut T, DynTypeError> {
240+
let value = self.value_mut().ok_or(DynTypeError::Empty)?;
241+
let actual_type_name = Reflect::type_name(value);
242+
(value as &mut dyn Any)
243+
.downcast_mut()
244+
.ok_or_else(|| DynTypeError::TypeCast {
245+
actual_type_name,
246+
requested_type_name: type_name::<T>(),
247+
})
248+
}
210249
}
211250

212251
impl Visit for DynTypeContainer {

fyrox-impl/src/plugin/error.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ use crate::{
2525
core::{pool::PoolError, visitor::error::VisitError},
2626
scene::graph::GraphError,
2727
};
28+
use fyrox_core::dyntype::DynTypeError;
2829
use std::fmt::{Debug, Display, Formatter};
2930

3031
/// All possible errors that may occur during script or plugin methods execution.
@@ -39,6 +40,8 @@ pub enum GameError {
3940
VisitError(VisitError),
4041
/// A [`LoadError`] has occurred.
4142
ResourceLoadError(LoadError),
43+
/// A [`DynTypeError`] has occurred.
44+
DynTypeError(DynTypeError),
4245
}
4346

4447
impl From<GraphError> for GameError {
@@ -71,6 +74,12 @@ impl From<VisitError> for GameError {
7174
}
7275
}
7376

77+
impl From<DynTypeError> for GameError {
78+
fn from(value: DynTypeError) -> Self {
79+
Self::DynTypeError(value)
80+
}
81+
}
82+
7483
impl std::error::Error for GameError {}
7584

7685
impl Display for GameError {
@@ -81,6 +90,7 @@ impl Display for GameError {
8190
GameError::AnyError(err) => Display::fmt(&err, f),
8291
GameError::ResourceLoadError(err) => Display::fmt(&err, f),
8392
GameError::VisitError(err) => Display::fmt(&err, f),
93+
GameError::DynTypeError(err) => Display::fmt(&err, f),
8494
}
8595
}
8696
}

0 commit comments

Comments
 (0)