diff --git a/crates/bevy_animation/src/graph.rs b/crates/bevy_animation/src/graph.rs index 45144aa4cd1cd..0a3965dc451e0 100644 --- a/crates/bevy_animation/src/graph.rs +++ b/crates/bevy_animation/src/graph.rs @@ -15,7 +15,7 @@ use bevy_ecs::{ system::{Res, ResMut, Resource}, }; use bevy_reflect::{prelude::ReflectDefault, Reflect, ReflectSerialize}; -use bevy_utils::HashMap; +use bevy_utils::{impl_handle_wrapper, HashMap}; use derive_more::derive::{Display, Error, From}; use petgraph::{ graph::{DiGraph, NodeIndex}, @@ -130,17 +130,7 @@ pub struct AnimationGraph { #[reflect(Component, Default)] pub struct AnimationGraphHandle(pub Handle); -impl From for AssetId { - fn from(handle: AnimationGraphHandle) -> Self { - handle.id() - } -} - -impl From<&AnimationGraphHandle> for AssetId { - fn from(handle: &AnimationGraphHandle) -> Self { - handle.id() - } -} +impl_handle_wrapper!(AnimationGraphHandle, AnimationGraph); /// A type alias for the `petgraph` data structure that defines the animation /// graph. diff --git a/crates/bevy_pbr/src/mesh_material.rs b/crates/bevy_pbr/src/mesh_material.rs index c737c991b808b..6aa7a9d959cf6 100644 --- a/crates/bevy_pbr/src/mesh_material.rs +++ b/crates/bevy_pbr/src/mesh_material.rs @@ -3,6 +3,7 @@ use bevy_asset::{AssetId, Handle}; use bevy_derive::{Deref, DerefMut}; use bevy_ecs::{component::Component, reflect::ReflectComponent}; use bevy_reflect::{std_traits::ReflectDefault, Reflect}; +use bevy_utils::impl_generic_handle_wrapper; use derive_more::derive::From; /// A [material](Material) for a [`Mesh3d`]. @@ -73,23 +74,7 @@ use derive_more::derive::From; #[require(HasMaterial3d)] pub struct MeshMaterial3d(pub Handle); -impl Default for MeshMaterial3d { - fn default() -> Self { - Self(Handle::default()) - } -} - -impl From> for AssetId { - fn from(material: MeshMaterial3d) -> Self { - material.id() - } -} - -impl From<&MeshMaterial3d> for AssetId { - fn from(material: &MeshMaterial3d) -> Self { - material.id() - } -} +impl_generic_handle_wrapper!(MeshMaterial3d, Handle, M, Material); /// A component that marks an entity as having a [`MeshMaterial3d`]. /// [`Mesh3d`] entities without this component are rendered with a [default material]. diff --git a/crates/bevy_pbr/src/meshlet/mod.rs b/crates/bevy_pbr/src/meshlet/mod.rs index 80d5f7aa59bfc..dc7053a2dd11b 100644 --- a/crates/bevy_pbr/src/meshlet/mod.rs +++ b/crates/bevy_pbr/src/meshlet/mod.rs @@ -87,7 +87,7 @@ use bevy_render::{ ExtractSchedule, Render, RenderApp, RenderSet, }; use bevy_transform::components::{GlobalTransform, Transform}; -use bevy_utils::tracing::error; +use bevy_utils::{impl_handle_wrapper, tracing::error}; use derive_more::From; const MESHLET_BINDINGS_SHADER_HANDLE: Handle = Handle::weak_from_u128(1325134235233421); @@ -295,17 +295,7 @@ impl Plugin for MeshletPlugin { #[require(Transform, Visibility)] pub struct MeshletMesh3d(pub Handle); -impl From for AssetId { - fn from(mesh: MeshletMesh3d) -> Self { - mesh.id() - } -} - -impl From<&MeshletMesh3d> for AssetId { - fn from(mesh: &MeshletMesh3d) -> Self { - mesh.id() - } -} +impl_handle_wrapper!(MeshletMesh3d, MeshletMesh); /// A component bundle for entities with a [`MeshletMesh`] and a [`Material`]. #[derive(Bundle, Clone)] diff --git a/crates/bevy_render/src/mesh/components.rs b/crates/bevy_render/src/mesh/components.rs index cb3d46afa4e6b..bfb93c57a0fe2 100644 --- a/crates/bevy_render/src/mesh/components.rs +++ b/crates/bevy_render/src/mesh/components.rs @@ -4,6 +4,7 @@ use bevy_derive::{Deref, DerefMut}; use bevy_ecs::{component::Component, reflect::ReflectComponent}; use bevy_reflect::{std_traits::ReflectDefault, Reflect}; use bevy_transform::components::Transform; +use bevy_utils::impl_handle_wrapper; use derive_more::derive::From; /// A component for rendering 2D meshes, typically with a [`MeshMaterial2d`] using a [`ColorMaterial`]. @@ -41,17 +42,7 @@ use derive_more::derive::From; #[require(Transform, Visibility)] pub struct Mesh2d(pub Handle); -impl From for AssetId { - fn from(mesh: Mesh2d) -> Self { - mesh.id() - } -} - -impl From<&Mesh2d> for AssetId { - fn from(mesh: &Mesh2d) -> Self { - mesh.id() - } -} +impl_handle_wrapper!(Mesh2d, Mesh); /// A component for rendering 3D meshes, typically with a [`MeshMaterial3d`] using a [`StandardMaterial`]. /// @@ -91,14 +82,4 @@ impl From<&Mesh2d> for AssetId { #[require(Transform, Visibility)] pub struct Mesh3d(pub Handle); -impl From for AssetId { - fn from(mesh: Mesh3d) -> Self { - mesh.id() - } -} - -impl From<&Mesh3d> for AssetId { - fn from(mesh: &Mesh3d) -> Self { - mesh.id() - } -} +impl_handle_wrapper!(Mesh3d, Mesh); diff --git a/crates/bevy_sprite/src/mesh2d/material.rs b/crates/bevy_sprite/src/mesh2d/material.rs index 847a3104fcf90..37895c569c193 100644 --- a/crates/bevy_sprite/src/mesh2d/material.rs +++ b/crates/bevy_sprite/src/mesh2d/material.rs @@ -34,7 +34,7 @@ use bevy_render::{ Extract, ExtractSchedule, Render, RenderApp, RenderSet, }; use bevy_transform::components::{GlobalTransform, Transform}; -use bevy_utils::tracing::error; +use bevy_utils::{impl_generic_handle_wrapper, tracing::error}; use core::{hash::Hash, marker::PhantomData}; use derive_more::derive::From; @@ -215,23 +215,7 @@ pub trait Material2d: AsBindGroup + Asset + Clone + Sized { #[require(HasMaterial2d)] pub struct MeshMaterial2d(pub Handle); -impl Default for MeshMaterial2d { - fn default() -> Self { - Self(Handle::default()) - } -} - -impl From> for AssetId { - fn from(material: MeshMaterial2d) -> Self { - material.id() - } -} - -impl From<&MeshMaterial2d> for AssetId { - fn from(material: &MeshMaterial2d) -> Self { - material.id() - } -} +impl_generic_handle_wrapper!(MeshMaterial2d, Handle, M, Material2d); /// A component that marks an entity as having a [`MeshMaterial2d`]. /// [`Mesh2d`] entities without this component are rendered with a [default material]. diff --git a/crates/bevy_ui/src/ui_material.rs b/crates/bevy_ui/src/ui_material.rs index b57e65865e54e..b877e536848c0 100644 --- a/crates/bevy_ui/src/ui_material.rs +++ b/crates/bevy_ui/src/ui_material.rs @@ -8,6 +8,7 @@ use bevy_render::{ extract_component::ExtractComponent, render_resource::{AsBindGroup, RenderPipelineDescriptor, ShaderRef}, }; +use bevy_utils::impl_generic_handle_wrapper; use derive_more::derive::From; /// Materials are used alongside [`UiMaterialPlugin`](crate::UiMaterialPlugin) and [`MaterialNodeBundle`](crate::prelude::MaterialNodeBundle) @@ -159,20 +160,4 @@ where #[reflect(Component, Default)] pub struct UiMaterialHandle(pub Handle); -impl Default for UiMaterialHandle { - fn default() -> Self { - Self(Handle::default()) - } -} - -impl From> for AssetId { - fn from(material: UiMaterialHandle) -> Self { - material.id() - } -} - -impl From<&UiMaterialHandle> for AssetId { - fn from(material: &UiMaterialHandle) -> Self { - material.id() - } -} +impl_generic_handle_wrapper!(UiMaterialHandle, Handle, M, UiMaterial); diff --git a/crates/bevy_utils/src/lib.rs b/crates/bevy_utils/src/lib.rs index 1f7e1f7e5c32b..65e7329522642 100644 --- a/crates/bevy_utils/src/lib.rs +++ b/crates/bevy_utils/src/lib.rs @@ -407,6 +407,54 @@ pub fn error(result: Result<(), E>) { } } +/// Boilerplate for handle wrapper +#[macro_export] +macro_rules! impl_handle_wrapper { + ($handle_wrapper_type:ident, $asset_type:ty) => { + impl From<$handle_wrapper_type> for AssetId<$asset_type> { + fn from(handle: $handle_wrapper_type) -> Self { + handle.id() + } + } + + impl From<&$handle_wrapper_type> for AssetId<$asset_type> { + fn from(handle: &$handle_wrapper_type) -> Self { + handle.id() + } + } + }; +} + +/// Boilerplate for generic handle wrapper +#[macro_export] +macro_rules! impl_generic_handle_wrapper { + ($handle_type:ident, $asset_type:ty, $asset_type_parameter:ident, $parameter_trait:ident) => { + impl<$asset_type_parameter: $parameter_trait> Default + for $handle_type<$asset_type_parameter> + { + fn default() -> Self { + Self(Handle::default()) + } + } + + impl<$asset_type_parameter: $parameter_trait> From<$handle_type<$asset_type_parameter>> + for AssetId<$asset_type_parameter> + { + fn from(handle: $handle_type<$asset_type_parameter>) -> Self { + handle.id() + } + } + + impl<$asset_type_parameter: $parameter_trait> From<&$handle_type<$asset_type_parameter>> + for AssetId<$asset_type_parameter> + { + fn from(handle: &$handle_type<$asset_type_parameter>) -> Self { + handle.id() + } + } + }; +} + /// Like [`tracing::trace`], but conditional on cargo feature `detailed_trace`. #[macro_export] macro_rules! detailed_trace { diff --git a/crates/bevy_utils/src/once.rs b/crates/bevy_utils/src/once.rs index 68aeb745559da..0e1747b1c3a3d 100644 --- a/crates/bevy_utils/src/once.rs +++ b/crates/bevy_utils/src/once.rs @@ -2,7 +2,7 @@ #[macro_export] macro_rules! once { ($expression:expr) => {{ - use ::core::sync::atomic::{AtomicBool, Ordering}; + use core::sync::atomic::{AtomicBool, Ordering}; static SHOULD_FIRE: AtomicBool = AtomicBool::new(true); if SHOULD_FIRE.swap(false, Ordering::Relaxed) {