Skip to content

Automatically register types for Reflect #3936

Open
@alice-i-cecile

Description

@alice-i-cecile

What problem does this solve or what need does it fill?

As seen in the examples, each type that we wish to reflect must be manually registered.

This is a serious frustration when using type reflection, and severely limits the ability to implement richer features using it (like trait queries), as we have no guarantee that resources / components are reflectable.

What solution would you like?

  1. Expand the functionality of the Reflect trait to fully support all reasonable data types. Add reflection for enum types #1347 is particularly critical.
  2. Make Resource opt-in, using a derive macro.
  3. Change the bounds on the various non-send resource tools to Resource, and make Res<T>: Resource + Send + Sync.
  4. Remove the blanket impl on Resource and force users to use #[derive(Resource)].
  5. Whenever a schedule is initialized (see Order independence of App construction #1255 for related thoughts on how we need a distinct initialization step), register the relevant traits (such as Reflect) all of the types used in it to the App that contains it. See the prior art on trait queries for an idea of how this might be done.

Open questions

We may need to force an explicit Event trait / derive that handles reflection as well in order to ensure that Res<Events<T>> is reflectable.

What alternative(s) have you considered?

Reducing this boilerplate is quite essential: currently, using scenes is very tedious due to this error-prone boilerplate.

However, there are several reasonable changes to consider:

  1. Make Reflect a required subtrait of Component and Resource . This does not play nice when external types are embedded in components and resources.
  2. Do not automatically implement Reflect in the Component / Resource derive. This is technically clearer, but introduces advanced concepts right away and adds to boilerplate.
  3. Fully remove the existing manual registration API. This will probably still be needed for dynamic component types.
  4. Register the component / resource types the first time that a system that needs it is run. This doesn't work well with e.g. trait queries as we need a complete list at the start, and forces users to reason about whether or not all of the required types are registered. It also spreads work out in unpredictable ways, rather than increasing boot-up costs.

Additional context

This is an old idea, and certainly not entirely my own. It was previously discussed in #1843 / #2254 / bevyengine/rfcs#27.

This strategy is also useful for including other information in the appropriate traits, such as the size of assets / components / resources (seen in https://github.com/BGR360/bevy_datasize).

The same technology used above for trait registration would be very useful for #1515.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-ECSEntities, components, systems, and eventsA-ReflectionRuntime information about typesA-ScenesSerialized ECS data stored on the diskC-FeatureA new feature, making something new possibleC-UsabilityA targeted quality-of-life change that makes Bevy easier to useD-ModestA "normal" level of difficulty; suitable for simple features or challenging fixesS-Ready-For-ImplementationThis issue is ready for an implementation PR. Go for it!

    Type

    No type

    Projects

    Status

    Open

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions