summaryrefslogtreecommitdiff
path: root/engine/src
diff options
context:
space:
mode:
Diffstat (limited to 'engine/src')
-rw-r--r--engine/src/lib.rs1
-rw-r--r--engine/src/reflection.rs147
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
+ }
+}