summaryrefslogtreecommitdiff
path: root/engine-macros/src/reflection
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2026-06-12 20:41:38 +0200
committerHampusM <hampus@hampusmat.com>2026-06-12 20:50:28 +0200
commit52e42bfdb3d56644da03e60969b1a2bedac8efc2 (patch)
treec0f4e4d7994a5f44fe28e7d603796b7b28142dad /engine-macros/src/reflection
parentbf82dbc8c377453ccb97c7d66f1ef4b8f8ebd6b0 (diff)
fix(engine): no field type refs for generic types deriving Reflection
Diffstat (limited to 'engine-macros/src/reflection')
-rw-r--r--engine-macros/src/reflection/enum_impl.rs8
-rw-r--r--engine-macros/src/reflection/field.rs105
-rw-r--r--engine-macros/src/reflection/struct_impl.rs1
3 files changed, 78 insertions, 36 deletions
diff --git a/engine-macros/src/reflection/enum_impl.rs b/engine-macros/src/reflection/enum_impl.rs
index b2e01e8..1760f40 100644
--- a/engine-macros/src/reflection/enum_impl.rs
+++ b/engine-macros/src/reflection/enum_impl.rs
@@ -288,6 +288,10 @@ fn generate_variants<'a>(
unreachable!();
}
},
+ type_reflection_optional: input
+ .generics
+ .params
+ .is_empty(),
},
)
},
@@ -333,6 +337,10 @@ fn generate_variants<'a>(
}
}
},
+ type_reflection_optional: input
+ .generics
+ .params
+ .is_empty(),
},
)
},
diff --git a/engine-macros/src/reflection/field.rs b/engine-macros/src/reflection/field.rs
index 7d4e301..95671c3 100644
--- a/engine-macros/src/reflection/field.rs
+++ b/engine-macros/src/reflection/field.rs
@@ -6,6 +6,7 @@ pub struct ReflectionFieldGenOptions<'a>
{
pub field_vis_override: Option<syn::Visibility>,
pub gen_get_byte_offset: &'a dyn Fn(&syn::Field) -> proc_macro2::TokenStream,
+ pub type_reflection_optional: bool,
}
pub fn generate(
@@ -33,6 +34,12 @@ pub fn generate(
let field_reflection_vis = generate_visibility(field_vis, &engine_crate_path);
+ let get_type_fn_body = if options.type_reflection_optional {
+ gen_get_optional_type_reflection(field_type, engine_crate_path)
+ } else {
+ gen_get_mandatory_type_reflection(field_type, engine_crate_path)
+ };
+
quote! {
#engine_crate_path::reflection::Field {
name: #field_name,
@@ -44,44 +51,70 @@ pub fn generate(
std::any::type_name::<#field_type>()
}),
get_type: #engine_crate_path::reflection::FnWithDebug::new(|| {
- struct SpecializationTarget<Field>(std::marker::PhantomData<Field>);
-
- trait FieldHasReflection
- {
- fn field_type_reflection(&self)
- -> Option<&'static #engine_crate_path::reflection::Type>;
- }
-
- trait FieldDoesNotHaveReflection
- {
- fn field_type_reflection(&self)
- -> Option<&'static #engine_crate_path::reflection::Type>;
- }
-
- impl<Field> FieldDoesNotHaveReflection for &SpecializationTarget<Field>
- {
- fn field_type_reflection(&self)
- -> Option<&'static #engine_crate_path::reflection::Type>
- {
- None
- }
- }
-
- impl<Field> FieldHasReflection for SpecializationTarget<Field>
- where
- Field: #engine_crate_path::reflection::Reflection
- {
- fn field_type_reflection(&self)
- -> Option<&'static #engine_crate_path::reflection::Type>
- {
- Some(Field::type_reflection())
- }
- }
-
- (&SpecializationTarget::<#field_type>(std::marker::PhantomData))
- .field_type_reflection()
+ #get_type_fn_body
}),
visibility: #field_reflection_vis
}
}
}
+
+fn gen_get_optional_type_reflection(
+ field_type: &syn::Type,
+ engine_crate_path: &syn::Path,
+) -> proc_macro2::TokenStream
+{
+ quote! {
+ struct SpecializationTarget<Field>(std::marker::PhantomData<Field>);
+
+ trait FieldHasReflection
+ {
+ fn field_type_reflection(&self)
+ -> Option<&'static #engine_crate_path::reflection::Type>;
+ }
+
+ trait FieldDoesNotHaveReflection
+ {
+ fn field_type_reflection(&self)
+ -> Option<&'static #engine_crate_path::reflection::Type>;
+ }
+
+ impl<Field> FieldDoesNotHaveReflection for &SpecializationTarget<Field>
+ {
+ fn field_type_reflection(&self)
+ -> Option<&'static #engine_crate_path::reflection::Type>
+ {
+ None
+ }
+ }
+
+ impl<Field> FieldHasReflection for SpecializationTarget<Field>
+ where
+ Field: #engine_crate_path::reflection::Reflection
+ {
+ fn field_type_reflection(&self)
+ -> Option<&'static #engine_crate_path::reflection::Type>
+ {
+ Some(Field::type_reflection())
+ }
+ }
+
+ (&SpecializationTarget::<#field_type>(std::marker::PhantomData))
+ .field_type_reflection()
+ }
+}
+
+fn gen_get_mandatory_type_reflection(
+ field_type: &syn::Type,
+ engine_crate_path: &syn::Path,
+) -> proc_macro2::TokenStream
+{
+ quote! {
+ fn field_type_reflection<T: #engine_crate_path::reflection::Reflection>()
+ -> &'static #engine_crate_path::reflection::Type
+ {
+ T::type_reflection()
+ }
+
+ Some(field_type_reflection::<#field_type>())
+ }
+}
diff --git a/engine-macros/src/reflection/struct_impl.rs b/engine-macros/src/reflection/struct_impl.rs
index 92cf00b..2a271e0 100644
--- a/engine-macros/src/reflection/struct_impl.rs
+++ b/engine-macros/src/reflection/struct_impl.rs
@@ -29,6 +29,7 @@ pub fn generate(input: syn::ItemStruct) -> proc_macro2::TokenStream
quote! { std::mem::offset_of!(Self, #field_index) }
}
},
+ type_reflection_optional: input.generics.params.is_empty(),
},
)
});