diff options
| author | HampusM <hampus@hampusmat.com> | 2026-06-23 00:19:05 +0200 |
|---|---|---|
| committer | HampusM <hampus@hampusmat.com> | 2026-06-23 00:25:40 +0200 |
| commit | 172bf5b905c6ab82e96f5ef8a14ff3bc9193f7ad (patch) | |
| tree | 54a23f599a0d55336d0a4b121da3e27963ea75e7 /engine-reflection | |
| parent | e12391a0861d61a19516f212edd49ad78b65104e (diff) | |
feat(engine): add type reflection fn for casting to dyn Any
Diffstat (limited to 'engine-reflection')
| -rw-r--r-- | engine-reflection/src/lib.rs | 30 |
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>; |
