Skip to content

Commit

Permalink
Replace Handle<M: UiMaterial> component with UiMaterialHandle wra…
Browse files Browse the repository at this point in the history
…pper (#15740)

# Objective

- Closes #15720

## Solution

Wrap the handle in a new wrapper component: `UiMaterialHandle`
It's not possible to match the naming convention of `MeshMaterial3d/2d`
here with the trait already being called `UiMaterial`

Should we consider renaming to `Material3d/2dHandle` and `Mesh3d/2d` to
`Mesh3d/2dHandle`?

- This shouldn't have any merge conflicts with #15591

## Testing

Tested the `ui_material` example

## Migration Guide

Let's defer the migration guide to the required component port. I just
want to yeet the `Component` impl on `Handle` in the meantime :)
  • Loading branch information
tim-blackbird authored Oct 8, 2024
1 parent aa626e4 commit 9aef71b
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 13 deletions.
2 changes: 1 addition & 1 deletion crates/bevy_ui/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ pub mod prelude {
pub use {
crate::{
geometry::*, node_bundles::*, ui_material::*, ui_node::*, widget::Button,
widget::Label, Interaction, UiMaterialPlugin, UiScale,
widget::Label, Interaction, UiMaterialHandle, UiMaterialPlugin, UiScale,
},
// `bevy_sprite` re-exports for texture slicing
bevy_sprite::{BorderRect, ImageScaleMode, SliceScaleMode, TextureSlicer},
Expand Down
5 changes: 2 additions & 3 deletions crates/bevy_ui/src/node_bundles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@
use crate::{
widget::{Button, UiImageSize},
BackgroundColor, BorderColor, BorderRadius, ContentSize, FocusPolicy, Interaction, Node,
ScrollPosition, Style, UiImage, UiMaterial, ZIndex,
ScrollPosition, Style, UiImage, UiMaterial, UiMaterialHandle, ZIndex,
};
use bevy_asset::Handle;
use bevy_ecs::bundle::Bundle;
use bevy_render::view::{InheritedVisibility, ViewVisibility, Visibility};
use bevy_transform::prelude::{GlobalTransform, Transform};
Expand Down Expand Up @@ -294,7 +293,7 @@ pub struct MaterialNodeBundle<M: UiMaterial> {
/// In some cases these styles also affect how the node drawn/painted.
pub style: Style,
/// The [`UiMaterial`] used to render the node.
pub material: Handle<M>,
pub material: UiMaterialHandle<M>,
/// Whether this node should block interaction with lower nodes
pub focus_policy: FocusPolicy,
/// The transform of the node
Expand Down
4 changes: 2 additions & 2 deletions crates/bevy_ui/src/render/ui_material_pipeline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ where
Shader::from_wgsl
);
app.init_asset::<M>().add_plugins((
ExtractComponentPlugin::<Handle<M>>::extract_visible(),
ExtractComponentPlugin::<UiMaterialHandle<M>>::extract_visible(),
RenderAssetPlugin::<PreparedUiMaterial<M>>::default(),
));

Expand Down Expand Up @@ -364,7 +364,7 @@ pub fn extract_ui_material_nodes<M: UiMaterial>(
(
&Node,
&GlobalTransform,
&Handle<M>,
&UiMaterialHandle<M>,
&ViewVisibility,
Option<&CalculatedClip>,
Option<&TargetCamera>,
Expand Down
42 changes: 38 additions & 4 deletions crates/bevy_ui/src/ui_material.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
use core::hash::Hash;

use bevy_asset::Asset;
use bevy_render::render_resource::{AsBindGroup, RenderPipelineDescriptor, ShaderRef};
use bevy_asset::{Asset, AssetId, Handle};
use bevy_derive::{Deref, DerefMut};
use bevy_ecs::{component::Component, reflect::ReflectComponent};
use bevy_reflect::{prelude::ReflectDefault, Reflect};
use bevy_render::{
extract_component::ExtractComponent,
render_resource::{AsBindGroup, RenderPipelineDescriptor, ShaderRef},
};

/// Materials are used alongside [`UiMaterialPlugin`](crate::UiMaterialPlugin) and [`MaterialNodeBundle`](crate::prelude::MaterialNodeBundle)
/// to spawn entities that are rendered with a specific [`UiMaterial`] type. They serve as an easy to use high level
Expand Down Expand Up @@ -56,10 +62,10 @@ use bevy_render::render_resource::{AsBindGroup, RenderPipelineDescriptor, Shader
/// width: Val::Percent(100.0),
/// ..Default::default()
/// },
/// material: materials.add(CustomMaterial {
/// material: UiMaterialHandle(materials.add(CustomMaterial {
/// color: LinearRgba::RED,
/// color_texture: asset_server.load("some_image.png"),
/// }),
/// })),
/// ..Default::default()
/// });
/// }
Expand Down Expand Up @@ -145,3 +151,31 @@ where
self.bind_group_data.hash(state);
}
}

#[derive(Component, Clone, Debug, Deref, DerefMut, Reflect, PartialEq, Eq, ExtractComponent)]
#[reflect(Component, Default)]
pub struct UiMaterialHandle<M: UiMaterial>(pub Handle<M>);

impl<M: UiMaterial> Default for UiMaterialHandle<M> {
fn default() -> Self {
Self(Handle::default())
}
}

impl<M: UiMaterial> From<Handle<M>> for UiMaterialHandle<M> {
fn from(handle: Handle<M>) -> Self {
Self(handle)
}
}

impl<M: UiMaterial> From<UiMaterialHandle<M>> for AssetId<M> {
fn from(material: UiMaterialHandle<M>) -> Self {
material.id()
}
}

impl<M: UiMaterial> From<&UiMaterialHandle<M>> for AssetId<M> {
fn from(material: &UiMaterialHandle<M>) -> Self {
material.id()
}
}
6 changes: 3 additions & 3 deletions examples/ui/ui_material.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,12 @@ fn setup(
border: UiRect::all(Val::Px(10.)),
..default()
},
material: ui_materials.add(CustomUiMaterial {
material: UiMaterialHandle(ui_materials.add(CustomUiMaterial {
color: LinearRgba::WHITE.to_f32_array().into(),
slider: 0.5,
color_texture: asset_server.load("branding/banner.png"),
border_color: LinearRgba::WHITE.to_f32_array().into(),
}),
})),
..default()
});
});
Expand Down Expand Up @@ -82,7 +82,7 @@ impl UiMaterial for CustomUiMaterial {
// Also updates the color of the image to a rainbow color
fn animate(
mut materials: ResMut<Assets<CustomUiMaterial>>,
q: Query<&Handle<CustomUiMaterial>>,
q: Query<&UiMaterialHandle<CustomUiMaterial>>,
time: Res<Time>,
) {
let duration = 2.0;
Expand Down

0 comments on commit 9aef71b

Please sign in to comment.