diff options
Diffstat (limited to 'engine/src/reflection.rs')
| -rw-r--r-- | engine/src/reflection.rs | 111 |
1 files changed, 57 insertions, 54 deletions
diff --git a/engine/src/reflection.rs b/engine/src/reflection.rs index 3ce424e..83bc636 100644 --- a/engine/src/reflection.rs +++ b/engine/src/reflection.rs @@ -1,22 +1,35 @@ use std::alloc::Layout; use std::any::{TypeId, type_name}; +use std::fmt::Debug; pub use engine_macros::Reflection; -pub trait With: 'static +/// Trait implemented by types that support runtime reflection on them. +/// +/// # Safety +/// Implementors of this trait must provide accurate reflection information in the +/// `TYPE_REFLECTION` associated constant and the `type_reflection` and +/// `get_type_reflection` methods. +pub unsafe trait Reflection: 'static { - const REFLECTION: &Reflection; + const TYPE_REFLECTION: &Type; - fn reflection() -> &'static Reflection + fn type_reflection() -> &'static Type where - Self: Sized; + Self: Sized, + { + Self::TYPE_REFLECTION + } - fn get_reflection(&self) -> &'static Reflection; + fn get_type_reflection(&self) -> &'static Type + { + Self::TYPE_REFLECTION + } } #[derive(Debug)] #[non_exhaustive] -pub enum Reflection +pub enum Type { Struct(Struct), Array(Array), @@ -24,7 +37,7 @@ pub enum Reflection Literal(Literal), } -impl Reflection +impl Type { pub const fn as_struct(&self) -> Option<&Struct> { @@ -50,20 +63,28 @@ pub struct StructField pub byte_offset: usize, pub type_id: TypeId, pub type_name: &'static str, - pub reflection: &'static Reflection, + pub get_type: FnWithDebug<Option<&'static Type>>, +} + +impl StructField +{ + pub fn type_reflection(&self) -> Option<&'static Type> + { + self.get_type.get() + } } #[derive(Debug, Clone)] pub struct Array { - pub item_reflection: &'static Reflection, + pub item_reflection: &'static Type, pub length: usize, } #[derive(Debug, Clone)] pub struct Slice { - pub item_reflection: &'static Reflection, + pub item_reflection: &'static Type, } #[derive(Debug)] @@ -77,25 +98,13 @@ pub struct Literal macro_rules! impl_with_for_literals { ($($literal: ty),*) => { $( - impl With for $literal + unsafe impl Reflection for $literal { - const REFLECTION: &Reflection = &Reflection::Literal(Literal { + const TYPE_REFLECTION: &Type = &Type::Literal(Literal { layout: Layout::new::<$literal>(), type_id: TypeId::of::<$literal>(), type_name: || type_name::<$literal>() }); - - fn reflection() -> &'static Reflection - where - Self: Sized - { - Self::REFLECTION - } - - fn get_reflection(&self) -> &'static Reflection - { - Self::reflection() - } } )* }; @@ -119,52 +128,46 @@ impl_with_for_literals!( &'static str ); -impl<T: With, const LEN: usize> With for [T; LEN] +unsafe impl<T: Reflection, const LEN: usize> Reflection for [T; LEN] { - const REFLECTION: &Reflection = &Reflection::Array(Array { - item_reflection: T::REFLECTION, + const TYPE_REFLECTION: &Type = &Type::Array(Array { + item_reflection: T::TYPE_REFLECTION, length: LEN, }); +} - fn reflection() -> &'static Reflection - where - Self: Sized, - { - Self::REFLECTION - } - - fn get_reflection(&self) -> &'static Reflection - { - Self::reflection() - } +unsafe impl<T: Reflection> Reflection for &'static [T] +{ + const TYPE_REFLECTION: &Type = + &Type::Slice(Slice { item_reflection: T::TYPE_REFLECTION }); } -impl<T: With> With for &'static [T] +#[derive(Clone)] +pub struct FnWithDebug<Value> { - const REFLECTION: &Reflection = - &Reflection::Slice(Slice { item_reflection: T::REFLECTION }); + func: fn() -> Value, +} - fn reflection() -> &'static Reflection - where - Self: Sized, +impl<Value> FnWithDebug<Value> +{ + pub const fn new(func: fn() -> Value) -> Self { - Self::REFLECTION + Self { func } } - fn get_reflection(&self) -> &'static Reflection + pub fn get(&self) -> Value { - Self::reflection() + (self.func)() } } -// Used by the Reflection derive macro -#[doc(hidden)] -pub mod __private +impl<Value: Debug> Debug for FnWithDebug<Value> { - pub const fn get_type_reflection<T>() -> &'static super::Reflection - where - T: super::With, + fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - T::REFLECTION + formatter + .debug_tuple("FnWithDebug") + .field(&self.get()) + .finish() } } |
