From 9f09de55142e8e4c619a3ff229f0a37ab9f30443 Mon Sep 17 00:00:00 2001 From: Jonah Henriksson <33059163+JonahPlusPlus@users.noreply.github.com> Date: Fri, 16 Dec 2022 01:40:15 +0000 Subject: [PATCH] Make `AsBindGroup` unsized (#6937) # Objective `AsBindGroup` can't be used as a trait object because of the constraint `Sized` and because of the associated function. This is a problem for [`bevy_atmosphere`](https://github.com/JonahPlusPlus/bevy_atmosphere) because it needs to use a trait that depends on `AsBindGroup` as a trait object, for switching out different shaders at runtime. The current solution it employs is reimplementing the trait and derive macro into that trait, instead of constraining to `AsBindGroup`. ## Solution Remove the `Sized` constraint from `AsBindGroup` and add the constraint `where Self: Sized` to the associated function `bind_group_layout`. Also change `PreparedBindGroup` to `PreparedBindGroup` and use it as `PreparedBindGroup` instead of `PreparedBindGroup`. This weakens the constraints, but increases the flexibility of `AsBindGroup`. I'm not entirely sure why the `Sized` constraint was there, because it worked fine without it (maybe @cart wasn't aware of use cases for `AsBindGroup` as a trait object or this was just leftover from legacy code?). --- ## Changelog - `AsBindGroup` can be used as a trait object. --- crates/bevy_render/macros/src/as_bind_group.rs | 2 +- crates/bevy_render/src/render_resource/bind_group.rs | 12 +++++++----- examples/3d/skybox.rs | 2 +- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/crates/bevy_render/macros/src/as_bind_group.rs b/crates/bevy_render/macros/src/as_bind_group.rs index 4c8a2b14b2ac9..bbc3c3850cf0b 100644 --- a/crates/bevy_render/macros/src/as_bind_group.rs +++ b/crates/bevy_render/macros/src/as_bind_group.rs @@ -371,7 +371,7 @@ pub fn derive_as_bind_group(ast: syn::DeriveInput) -> Result { render_device: &#render_path::renderer::RenderDevice, images: &#render_path::render_asset::RenderAssets<#render_path::texture::Image>, fallback_image: &#render_path::texture::FallbackImage, - ) -> Result<#render_path::render_resource::PreparedBindGroup, #render_path::render_resource::AsBindGroupError> { + ) -> Result<#render_path::render_resource::PreparedBindGroup, #render_path::render_resource::AsBindGroupError> { let bindings = vec![#(#binding_impls,)*]; let bind_group = { diff --git a/crates/bevy_render/src/render_resource/bind_group.rs b/crates/bevy_render/src/render_resource/bind_group.rs index c19f07605320f..88d3c6cc927e1 100644 --- a/crates/bevy_render/src/render_resource/bind_group.rs +++ b/crates/bevy_render/src/render_resource/bind_group.rs @@ -253,7 +253,7 @@ impl Deref for BindGroup { /// } /// } /// ``` -pub trait AsBindGroup: Sized { +pub trait AsBindGroup { /// Data that will be stored alongside the "prepared" bind group. type Data: Send + Sync; @@ -264,10 +264,12 @@ pub trait AsBindGroup: Sized { render_device: &RenderDevice, images: &RenderAssets, fallback_image: &FallbackImage, - ) -> Result, AsBindGroupError>; + ) -> Result, AsBindGroupError>; /// Creates the bind group layout matching all bind groups returned by [`AsBindGroup::as_bind_group`] - fn bind_group_layout(render_device: &RenderDevice) -> BindGroupLayout; + fn bind_group_layout(render_device: &RenderDevice) -> BindGroupLayout + where + Self: Sized; } /// An error that occurs during [`AsBindGroup::as_bind_group`] calls. @@ -277,10 +279,10 @@ pub enum AsBindGroupError { } /// A prepared bind group returned as a result of [`AsBindGroup::as_bind_group`]. -pub struct PreparedBindGroup { +pub struct PreparedBindGroup { pub bindings: Vec, pub bind_group: BindGroup, - pub data: T::Data, + pub data: T, } /// An owned binding resource of any type (ex: a [`Buffer`], [`TextureView`], etc). diff --git a/examples/3d/skybox.rs b/examples/3d/skybox.rs index 460c79d1d1191..c9dadafd5b8f1 100644 --- a/examples/3d/skybox.rs +++ b/examples/3d/skybox.rs @@ -227,7 +227,7 @@ impl AsBindGroup for CubemapMaterial { render_device: &RenderDevice, images: &RenderAssets, _fallback_image: &FallbackImage, - ) -> Result, AsBindGroupError> { + ) -> Result, AsBindGroupError> { let base_color_texture = self .base_color_texture .as_ref()