From 21aafa3b070425e1fa84d2c6bb322e75cb52dfd5 Mon Sep 17 00:00:00 2001 From: HampusM Date: Tue, 17 Mar 2026 13:18:56 +0100 Subject: feat(engine): add macro for reflection --- engine/Cargo.toml | 1 + engine/src/lib.rs | 1 + engine/src/reflection.rs | 147 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 149 insertions(+) create mode 100644 engine/src/reflection.rs (limited to 'engine') diff --git a/engine/Cargo.toml b/engine/Cargo.toml index 8e46bef..4e4600d 100644 --- a/engine/Cargo.toml +++ b/engine/Cargo.toml @@ -18,6 +18,7 @@ nu-ansi-term = "0.46.0" ecs = { path = "../ecs" } util-macros = { path = "../util-macros" } opengl-bindings = { path = "../opengl-bindings" } +engine-macros = { path = "../engine-macros" } [dependencies.winit] version = "0.30.11" 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 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 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() -> &'static super::Reflection + where + T: super::With, + { + T::REFLECTION + } +} -- cgit v1.2.3-18-g5258