MrGVSV / bevy_proto

Create config files for entities in Bevy

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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.