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