diff options
| author | HampusM <hampus@hampusmat.com> | 2026-03-17 13:18:56 +0100 |
|---|---|---|
| committer | HampusM <hampus@hampusmat.com> | 2026-03-17 13:19:14 +0100 |
| commit | 21aafa3b070425e1fa84d2c6bb322e75cb52dfd5 (patch) | |
| tree | f90303f4761136e5885b8ceda4ec2c92dfd00f55 /engine/src | |
| parent | d0cac9159e6ddfe5dbb9b32036e7258f6e51d47e (diff) | |
feat(engine): add macro for reflection
Diffstat (limited to 'engine/src')
| -rw-r--r-- | engine/src/lib.rs | 1 | ||||
| -rw-r--r-- | engine/src/reflection.rs | 147 |
2 files changed, 148 insertions, 0 deletions
diff --git a/engine/src/lib.rs b/engine/src/lib.rs index 75bc921..b470cdc 100644 --- a/engine/src/lib.rs +++ b/engine/src/lib.rs @@ -33,6 +33,7 @@ pub mod math; pub mod mesh; pub mod model; pub mod projection; +pub mod reflection; pub mod renderer; pub mod texture; pub mod transform; 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 + } +} |
