summaryrefslogtreecommitdiff
path: root/engine-reflection
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2026-06-23 00:19:05 +0200
committerHampusM <hampus@hampusmat.com>2026-06-23 00:25:40 +0200
commit172bf5b905c6ab82e96f5ef8a14ff3bc9193f7ad (patch)
tree54a23f599a0d55336d0a4b121da3e27963ea75e7 /engine-reflection
parente12391a0861d61a19516f212edd49ad78b65104e (diff)
feat(engine): add type reflection fn for casting to dyn Any
Diffstat (limited to 'engine-reflection')
-rw-r--r--engine-reflection/src/lib.rs30
1 files changed, 28 insertions, 2 deletions
diff --git a/engine-reflection/src/lib.rs b/engine-reflection/src/lib.rs
index 289989c..600c511 100644
--- a/engine-reflection/src/lib.rs
+++ b/engine-reflection/src/lib.rs
@@ -1,7 +1,9 @@
use std::alloc::Layout;
use std::any::{type_name, Any, TypeId};
use std::borrow::Cow;
+use std::ffi::c_void;
use std::fmt::Debug;
+use std::ptr::NonNull;
/// Trait implemented by types that support runtime reflection on them.
///
@@ -87,6 +89,18 @@ impl Type
Self::Array(_) | Self::Slice(_) | Self::Reference(_) => false,
}
}
+
+ #[inline]
+ pub fn cast_dyn_any(&self, ptr: NonNull<c_void>) -> Option<NonNull<dyn Any>> {
+ match self {
+ Self::Struct(struct_type) => Some((struct_type.cast_dyn_any)(ptr)),
+ Self::Enum(enum_type) => Some((enum_type.cast_dyn_any)(ptr)),
+ Self::Literal(literal_type) => Some((literal_type.cast_dyn_any)(ptr)),
+ Self::Array(array_type) => Some((array_type.cast_dyn_any)(ptr)),
+ Self::Reference(ref_type) => Some((ref_type.cast_dyn_any)(ptr)),
+ Self::Slice(_) => None
+ }
+ }
}
#[derive(Debug, Clone)]
@@ -94,6 +108,7 @@ pub struct Struct
{
pub fields: &'static [Field],
pub get_default_value: fn() -> Option<DefaultValueFn>,
+ pub cast_dyn_any: CastDynAnyFn
}
impl Struct
@@ -125,6 +140,7 @@ pub struct Enum
pub tagged_union: Option<EnumTaggedUnion>,
pub get_default_value: fn() -> Option<DefaultValueFn>,
+ pub cast_dyn_any: CastDynAnyFn
}
impl Enum
@@ -232,6 +248,7 @@ pub struct Array
pub item_layout: Layout,
pub get_item_type_name: FnWithDebug<&'static str>,
pub length: usize,
+ pub cast_dyn_any: CastDynAnyFn
}
impl Array
@@ -267,6 +284,7 @@ pub struct Literal
pub ty: LiteralType,
pub type_name: fn() -> &'static str,
pub get_default_value: fn() -> Option<DefaultValueFn>,
+ pub cast_dyn_any: CastDynAnyFn
}
impl Literal
@@ -288,6 +306,7 @@ impl Literal
pub struct Reference
{
pub ty: &'static Type,
+ pub cast_dyn_any: CastDynAnyFn
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
@@ -339,7 +358,8 @@ macro_rules! impl_reflection_for_literals {
type_id: TypeId::of::<$literal>(),
ty: LiteralType::$literal_type,
type_name: || type_name::<$literal>(),
- get_default_value: || Some(|| Box::new(Self::default()))
+ get_default_value: || Some(|| Box::new(Self::default())),
+ cast_dyn_any: |ptr| ptr.cast::<Self>()
});
}
)*
@@ -372,6 +392,7 @@ unsafe impl<T: Reflection, const LEN: usize> Reflection for [T; LEN]
item_layout: Layout::new::<T>(),
get_item_type_name: FnWithDebug::new(|| type_name::<T>()),
length: LEN,
+ cast_dyn_any: |ptr| ptr.cast::<Self>()
});
}
@@ -386,7 +407,10 @@ unsafe impl<T: Reflection> Reflection for &'static [T]
unsafe impl<T: Reflection> Reflection for &'static T
{
- const TYPE_REFLECTION: &Type = &Type::Reference(Reference { ty: T::TYPE_REFLECTION });
+ const TYPE_REFLECTION: &Type = &Type::Reference(Reference {
+ ty: T::TYPE_REFLECTION,
+ cast_dyn_any: |ptr| ptr.cast::<Self>()
+ });
}
#[derive(Clone)]
@@ -420,3 +444,5 @@ impl<Value: Debug> Debug for FnWithDebug<Value>
}
type DefaultValueFn = fn() -> Box<dyn Any>;
+
+type CastDynAnyFn = fn(NonNull<c_void>) -> NonNull<dyn Any>;