API inconsistency with `Handle` as component or field of component
Question
Should components with associated assets (e.g. Sprite + Handle<Image>) include their Handle as a field, or as a separate component on the same entity, or something else?
Handle-as-field: May make generic systems impossible (see theasset_decompressionexample).Handle-as-component: May create ambiguity (seeEnvironmentMapLight).
From the Discord discussion, this is blocked on Bevy scenes before a design decision can be made.
Status quo
Bevy's answer to this question is inconsistent (as of March 6th, 2024):
Component with a wrapped
Handlefield:
UiImage::texture: Handle<Image>TextureAtlas::layout: Handle<TextureAtlasLayout>Skybox::image: Handle<Image>Mesh2dHandle::0: Handle<Mesh>SkinnedMesh::inverse_bindposes: Handle<SkinnedMeshInverseBindposes>Lightmap::image: Handle<Image>IrradianceVolume::voxels: Handle<Image>EnvironmentMapLight::diffuse_map: Handle<Image>EnvironmentMapLight::specular_map: Handle<Image>Component with an associated
Handle-as-component:
Sprite+Handle<Image>- more? hard to ripgrep for this
Bundle with a
Handle-as-component field:
SpriteBundle::texture: Handle<Image>SceneBundle::scene: Handle<Scene>DynamicSceneBundle::scene: Handle<DynamicScene>MaterialMesh2dBundle<M>::material: Handle<M>MaterialMeshBundle<M>::material: Handle<M>MaterialMeshBundle<M>::mesh: Handle<Mesh>MaterialNodeBundle<M>::material: Handle<M>AudioSourceBundle<Source>::source: Handle<Source>
I agree; this design has annoyed me since the Component trait was implemented. I think these should all be newtyped personally.
This seems to be unblocked now, with required components landed and the scene overhaul generally being underway.
This was discussed informally today, with both @cart and I being broadly on board with moving to wrapper components: https://discordapp.com/channels/691052431525675048/1264881140007702558/1278098028536008827
Resolved in #15796. Handle should now be used as a field in a Component.