summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engine-macros/src/lib.rs94
-rw-r--r--engine/src/reflection.rs43
-rw-r--r--engine/src/renderer/opengl/graphics_mesh.rs6
3 files changed, 71 insertions, 72 deletions
diff --git a/engine-macros/src/lib.rs b/engine-macros/src/lib.rs
index ad6c15f..b87acf8 100644
--- a/engine-macros/src/lib.rs
+++ b/engine-macros/src/lib.rs
@@ -2,19 +2,7 @@
use proc_macro::TokenStream;
use quote::{ToTokens, format_ident, quote};
-use syn::punctuated::Punctuated;
-use syn::{
- Item,
- LitStr,
- Path as SynPath,
- PredicateType,
- Token,
- TraitBound,
- TypeParamBound,
- WhereClause,
- WherePredicate,
- parse,
-};
+use syn::{Item, LitStr, Path as SynPath, parse};
macro_rules! syn_path {
($first_segment: ident $(::$segment: ident)*) => {
@@ -57,29 +45,6 @@ pub fn reflection_derive(input: TokenStream) -> TokenStream
let (impl_generics, type_generics, where_clause) = input.generics.split_for_impl();
- let mut where_clause = where_clause.cloned().unwrap_or_else(|| WhereClause {
- where_token: <Token![where]>::default(),
- predicates: Punctuated::new(),
- });
-
- where_clause
- .predicates
- .extend(input.fields.iter().map(|field| {
- WherePredicate::Type(PredicateType {
- lifetimes: None,
- bounded_ty: field.ty.clone(),
- colon_token: <Token![:]>::default(),
- bounds: [TypeParamBound::Trait(TraitBound {
- paren_token: None,
- modifier: syn::TraitBoundModifier::None,
- lifetimes: None,
- path: engine_crate_path.join(syn_path!(reflection::With)),
- })]
- .into_iter()
- .collect(),
- })
- }));
-
let fields = input.fields.into_iter().enumerate().map(|(index, field)| {
let field_ident = field.ident.unwrap_or_else(|| format_ident!("{index}"));
@@ -98,10 +63,38 @@ pub fn reflection_derive(input: TokenStream) -> TokenStream
byte_offset: std::mem::offset_of!(Self, #field_ident),
type_id: std::any::TypeId::of::<#field_type>(),
type_name: #field_type_name,
- reflection:
- #engine_crate_path::reflection::__private::get_type_reflection::<
- #field_type
- >()
+ get_reflection: #engine_crate_path::reflection::FnWithDebug::new(|| {
+ struct SpecializationTarget<Field>(std::marker::PhantomData<Field>);
+
+ trait FieldHasReflection
+ {
+ fn field_reflection(&self) -> Option<&'static #engine_crate_path::reflection::Reflection>;
+ }
+
+ trait FieldDoesNotHaveReflection
+ {
+ fn field_reflection(&self) -> Option<&'static #engine_crate_path::reflection::Reflection>;
+ }
+
+ impl<Field> FieldDoesNotHaveReflection for &SpecializationTarget<Field>
+ {
+ fn field_reflection(&self) -> Option<&'static #engine_crate_path::reflection::Reflection>
+ {
+ None
+ }
+ }
+
+ impl<Field: #engine_crate_path::reflection::With> FieldHasReflection for SpecializationTarget<Field>
+ {
+ fn field_reflection(&self) -> Option<&'static #engine_crate_path::reflection::Reflection>
+ {
+ Some(Field::reflection())
+ }
+ }
+
+ (&SpecializationTarget::<#field_type>(std::marker::PhantomData))
+ .field_reflection()
+ })
}
}
});
@@ -151,24 +144,3 @@ fn find_engine_crate_path() -> Option<SynPath>
Some(syn_path!(engine))
}
-
-trait SynPathExt
-{
- fn join(&self, other: Self) -> Self;
-}
-
-impl SynPathExt for SynPath
-{
- fn join(&self, other: Self) -> Self
- {
- Self {
- leading_colon: self.leading_colon.clone(),
- segments: self
- .segments
- .iter()
- .chain(&other.segments)
- .cloned()
- .collect(),
- }
- }
-}
diff --git a/engine/src/reflection.rs b/engine/src/reflection.rs
index 3ce424e..7c5ee5c 100644
--- a/engine/src/reflection.rs
+++ b/engine/src/reflection.rs
@@ -1,5 +1,6 @@
use std::alloc::Layout;
use std::any::{TypeId, type_name};
+use std::fmt::Debug;
pub use engine_macros::Reflection;
@@ -50,7 +51,15 @@ pub struct StructField
pub byte_offset: usize,
pub type_id: TypeId,
pub type_name: &'static str,
- pub reflection: &'static Reflection,
+ pub get_reflection: FnWithDebug<Option<&'static Reflection>>,
+}
+
+impl StructField
+{
+ pub fn reflection(&self) -> Option<&'static Reflection>
+ {
+ self.get_reflection.get()
+ }
}
#[derive(Debug, Clone)]
@@ -157,14 +166,32 @@ impl<T: With> With for &'static [T]
}
}
-// Used by the Reflection derive macro
-#[doc(hidden)]
-pub mod __private
+#[derive(Clone)]
+pub struct FnWithDebug<Value>
{
- pub const fn get_type_reflection<T>() -> &'static super::Reflection
- where
- T: super::With,
+ func: fn() -> Value,
+}
+
+impl<Value> FnWithDebug<Value>
+{
+ pub const fn new(func: fn() -> Value) -> Self
+ {
+ Self { func }
+ }
+
+ pub fn get(&self) -> Value
+ {
+ (self.func)()
+ }
+}
+
+impl<Value: Debug> Debug for FnWithDebug<Value>
+{
+ fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result
{
- T::REFLECTION
+ formatter
+ .debug_tuple("FnWithDebug")
+ .field(&self.get())
+ .finish()
}
}
diff --git a/engine/src/renderer/opengl/graphics_mesh.rs b/engine/src/renderer/opengl/graphics_mesh.rs
index 5d081c7..d62cd3e 100644
--- a/engine/src/renderer/opengl/graphics_mesh.rs
+++ b/engine/src/renderer/opengl/graphics_mesh.rs
@@ -105,8 +105,8 @@ impl GraphicsMesh
vertex_arr.set_attrib_format(
current_context,
attrib_index,
- match vertex_subset_field.reflection.reflection {
- Reflection::Literal(_) => {
+ match vertex_subset_field.reflection.reflection() {
+ Some(Reflection::Literal(_)) => {
if vertex_subset_field.reflection.type_id != TypeId::of::<f32>() {
panic!("Unsupported vertex field data type");
}
@@ -118,7 +118,7 @@ impl GraphicsMesh
offset: vertex_subset_field.offset.try_into().unwrap(),
}
}
- Reflection::Array(array_vertex_field) => {
+ Some(Reflection::Array(array_vertex_field)) => {
let Reflection::Literal(array_vertex_field_item) =
array_vertex_field.item_reflection
else {