Smart-forward `reflect` attributes
MrGVSV opened this issue · comments
The Problem
Currently, reflect
attributes are forwarded 1:1 from fields on a schematic to fields on a generated input type.
This may not always be desired. For example:
#[derive(Component, Reflect, Schematic)]
struct MyStruct {
#[reflect(default)]
#[schematic(from = MyInteger)]
foo: i32,
}
#[derive(Reflect)]
struct MyInteger(i32);
impl From<MyInteger> for i32 {/* ... */}
The above code ends up generating the following input type:
// GENERATED
#[derive(::bevy::reflect::Reflect)]
struct MyStructInput {
#[reflect(default)]
foo: MyInteger,
}
But this results in a compile error due to MyInteger
not implementing Default
.
The Solution
While it would make things a bit more verbose, we could add a new attribute, #[schematic(reflect(...))]
, that makes forwarding reflection attributes explicit. This could also be used to pass certain reflection attributes to the generated input container rather than just its fields.
One way to assuage this added verbosity would be to only require this attribute on fields that define some custom schematic functionality. Fields that don't use any #[schematic]
attribute are meant to map 1:1 with the input field type. For example:
#[derive(Component, Reflect, Schematic)]
struct MyStruct {
#[reflect(default)]
#[schematic(from = MyInteger)]
#[schematic(reflect(default))] // <-- Needed
foo: i32,
#[reflect(default)] // <-- Not needed
bar: i32,
}
The issue with doing this is that it feels a little implicit and confusing, so it might not even be worth it.
It might be good just to start with the more verbose approach so we can get this working properly, and then reassess how/if we make it better.