diff options
Diffstat (limited to 'engine/src/reflection.rs')
| -rw-r--r-- | engine/src/reflection.rs | 147 |
1 files changed, 147 insertions, 0 deletions
diff --git a/engine/src/reflection.rs b/engine/src/reflection.rs new file mode 100644 index 0000000..5bd2aef --- /dev/null +++ b/engine/src/reflection.rs @@ -0,0 +1,147 @@ +use std::alloc::Layout; +use std::any::TypeId; + +pub use engine_macros::Reflection; + +pub trait With: 'static +{ + const REFLECTION: &Reflection; + + fn reflection() -> &'static Reflection + where + Self: Sized; + + fn get_reflection(&self) -> &'static Reflection; +} + +#[derive(Debug, Clone)] +#[non_exhaustive] +pub enum Reflection +{ + Struct(Struct), + Array(Array), + Slice(Slice), + Literal, +} + +#[derive(Debug, Clone)] +pub struct Struct +{ + pub fields: &'static [StructField], +} + +#[derive(Debug, Clone)] +pub struct StructField +{ + pub name: &'static str, + pub index: usize, + pub layout: Layout, + pub byte_offset: usize, + pub type_id: TypeId, + pub type_name: &'static str, + pub reflection: &'static Reflection, +} + +#[derive(Debug, Clone)] +pub struct Array +{ + pub item_reflection: &'static Reflection, + pub length: usize, +} + +#[derive(Debug, Clone)] +pub struct Slice +{ + pub item_reflection: &'static Reflection, +} + +macro_rules! impl_with_for_literals { + ($($literal: ty),*) => { + $( + impl With for $literal + { + const REFLECTION: &Reflection = &Reflection::Literal; + + fn reflection() -> &'static Reflection + where + Self: Sized + { + Self::REFLECTION + } + + fn get_reflection(&self) -> &'static Reflection + { + Self::reflection() + } + } + )* + }; +} + +impl_with_for_literals!( + u8, + i8, + u16, + i16, + u32, + i32, + u64, + i64, + u128, + i128, + f32, + f64, + usize, + isize, + &'static str +); + +impl<T: With, const LEN: usize> With for [T; LEN] +{ + const REFLECTION: &Reflection = &Reflection::Array(Array { + item_reflection: T::REFLECTION, + length: LEN, + }); + + fn reflection() -> &'static Reflection + where + Self: Sized, + { + Self::REFLECTION + } + + fn get_reflection(&self) -> &'static Reflection + { + Self::reflection() + } +} + +impl<T: With> With for &'static [T] +{ + const REFLECTION: &Reflection = + &Reflection::Slice(Slice { item_reflection: T::REFLECTION }); + + fn reflection() -> &'static Reflection + where + Self: Sized, + { + Self::REFLECTION + } + + fn get_reflection(&self) -> &'static Reflection + { + Self::reflection() + } +} + +// Used by the Reflection derive macro +#[doc(hidden)] +pub mod __private +{ + pub const fn get_type_reflection<T>() -> &'static super::Reflection + where + T: super::With, + { + T::REFLECTION + } +} |
