Description
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?
- Expand the functionality of the
Reflect
trait to fully support all reasonable data types. Add reflection for enum types #1347 is particularly critical. - Make
Resource
opt-in, using a derive macro. - Change the bounds on the various non-send resource tools to
Resource
, and makeRes<T>: Resource + Send + Sync
. - Remove the blanket impl on
Resource
and force users to use#[derive(Resource)]
. - 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 theApp
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:
- Make
Reflect
a required subtrait ofComponent
andResource
. This does not play nice when external types are embedded in components and resources. - Do not automatically implement
Reflect
in theComponent
/Resource
derive. This is technically clearer, but introduces advanced concepts right away and adds to boilerplate. - Fully remove the existing manual registration API. This will probably still be needed for dynamic component types.
- 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
Labels
Type
Projects
Status