diff --git a/crates/bevy_derive/src/as_vertex_buffer_descriptor.rs b/crates/bevy_derive/src/as_vertex_buffer_descriptor.rs index 58fb1ef168..3b782afaa5 100644 --- a/crates/bevy_derive/src/as_vertex_buffer_descriptor.rs +++ b/crates/bevy_derive/src/as_vertex_buffer_descriptor.rs @@ -1,10 +1,10 @@ -use crate::{ - modules::{get_modules, get_path}, -}; +use crate::modules::{get_modules, get_path}; use inflector::Inflector; use proc_macro::TokenStream; use quote::{format_ident, quote}; -use syn::{parse_macro_input, DeriveInput, Path, Data, DataStruct, Fields, Field, parse::ParseStream}; +use syn::{ + parse::ParseStream, parse_macro_input, Data, DataStruct, DeriveInput, Field, Fields, Path, +}; #[derive(Default)] struct VertexAttributes { @@ -31,22 +31,29 @@ pub fn derive_as_vertex_buffer_descriptor(input: TokenStream) -> TokenStream { .map(|field| { ( field, - field.attrs + field + .attrs .iter() - .find(|a| a.path.get_ident().as_ref().unwrap().to_string() == VERTEX_ATTRIBUTE_NAME) - .map_or_else(|| VertexAttributes::default() ,|a| { - syn::custom_keyword!(ignore); - let mut vertex_attributes = VertexAttributes::default(); - a.parse_args_with(|input: ParseStream| { - if let Some(_) = input.parse::>()? { - vertex_attributes.ignore = true; - return Ok(()); - } - Ok(()) - }).expect("invalid 'vertex' attribute format"); + .find(|a| { + a.path.get_ident().as_ref().unwrap().to_string() == VERTEX_ATTRIBUTE_NAME + }) + .map_or_else( + || VertexAttributes::default(), + |a| { + syn::custom_keyword!(ignore); + let mut vertex_attributes = VertexAttributes::default(); + a.parse_args_with(|input: ParseStream| { + if let Some(_) = input.parse::>()? { + vertex_attributes.ignore = true; + return Ok(()); + } + Ok(()) + }) + .expect("invalid 'vertex' attribute format"); - vertex_attributes - }), + vertex_attributes + }, + ), ) }) .collect::>(); diff --git a/crates/bevy_ecs/src/into_system.rs b/crates/bevy_ecs/src/into_system.rs index 1b18e2b81f..9435e26ab2 100644 --- a/crates/bevy_ecs/src/into_system.rs +++ b/crates/bevy_ecs/src/into_system.rs @@ -1,5 +1,5 @@ use crate::{ - resource_query::{FetchResource, ResourceQuery}, + resource_query::{FetchResource, ResourceQuery, UnsafeClone}, system::{System, SystemId, ThreadLocalExecution}, Commands, Resources, }; @@ -74,6 +74,7 @@ macro_rules! impl_into_foreach_system { { #[allow(non_snake_case)] #[allow(unused_variables)] + #[allow(unused_unsafe)] fn system(mut self) -> Box { let id = SystemId::new(); Box::new(SystemFn { @@ -136,6 +137,7 @@ macro_rules! impl_into_query_system { { #[allow(non_snake_case)] #[allow(unused_variables)] + #[allow(unused_unsafe)] fn system(mut self) -> Box { let id = SystemId::new(); Box::new(SystemFn { @@ -163,10 +165,10 @@ macro_rules! impl_into_query_system { macro_rules! fn_call { ($self:ident, ($($commands: ident, $commands_var: ident)*), ($($resource: ident),*), ($($a: ident),*)) => { - $self($($commands_var.clone(),)* $($resource.clone(),)* $($a,)*) + unsafe { $self($($commands_var.clone(),)* $($resource.unsafe_clone(),)* $($a,)*) } }; ($self:ident, (), ($($resource: ident),*), ($($a: ident),*)) => { - $self($($resource.clone(),)* $($a,)*) + unsafe { $self($($resource.unsafe_clone(),)* $($a,)*) } }; } diff --git a/crates/bevy_ecs/src/lib.rs b/crates/bevy_ecs/src/lib.rs index 4d9eeacae5..16c4624501 100644 --- a/crates/bevy_ecs/src/lib.rs +++ b/crates/bevy_ecs/src/lib.rs @@ -4,7 +4,7 @@ mod commands; mod into_system; #[cfg(feature = "profiler")] pub mod profiler; -mod resource_query; +pub mod resource_query; mod resources; mod schedule; mod system; diff --git a/crates/bevy_ecs/src/resource_query.rs b/crates/bevy_ecs/src/resource_query.rs index 451febe259..fd05550570 100644 --- a/crates/bevy_ecs/src/resource_query.rs +++ b/crates/bevy_ecs/src/resource_query.rs @@ -26,9 +26,13 @@ impl<'a, T: Component> Res<'a, T> { } } +pub trait UnsafeClone { + unsafe fn unsafe_clone(&self) -> Self; +} + // TODO: this is unsafe. lets think of a better solution that allows us to clone internally -impl<'a, T: Component> Clone for ResMut<'a, T> { - fn clone(&self) -> Self { +impl<'a, T: Component> UnsafeClone for ResMut<'a, T> { + unsafe fn unsafe_clone(&self) -> Self { Self { archetype: self.archetype, target: self.target, @@ -36,8 +40,8 @@ impl<'a, T: Component> Clone for ResMut<'a, T> { } } -impl<'a, T: Component> Clone for Res<'a, T> { - fn clone(&self) -> Self { +impl<'a, T: Component> UnsafeClone for Res<'a, T> { + unsafe fn unsafe_clone(&self) -> Self { Self { archetype: self.archetype, target: self.target, @@ -110,9 +114,8 @@ impl<'a, T: Component + FromResources> Local<'a, T> { } } -// TODO: this is unsafe. lets think of a better solution that allows us to clone internally -impl<'a, T: Component + FromResources> Clone for Local<'a, T> { - fn clone(&self) -> Self { +impl<'a, T: Component + FromResources> UnsafeClone for Local<'a, T> { + unsafe fn unsafe_clone(&self) -> Self { Self { archetype: self.archetype, target: self.target, @@ -143,7 +146,7 @@ pub trait ResourceQuery { /// Streaming iterators over contiguous homogeneous ranges of components pub trait FetchResource<'a>: Sized { /// Type of value to be fetched - type Item: Clone; + type Item: UnsafeClone; fn borrow(resource_archetypes: &HashMap); fn release(resource_archetypes: &HashMap); @@ -276,6 +279,15 @@ macro_rules! tuple_impl { $($name::initialize(resources, system_id);)* } } + + #[allow(unused_variables)] + #[allow(non_snake_case)] + impl<$($name: UnsafeClone),*> UnsafeClone for ($($name,)*) { + unsafe fn unsafe_clone(&self) -> Self { + let ($($name,)*) = self; + ($($name.unsafe_clone(),)*) + } + } }; } diff --git a/crates/bevy_pbr/src/nodes/lights_node.rs b/crates/bevy_pbr/src/nodes/lights_node.rs index 650fbb5d01..0194cb2f03 100644 --- a/crates/bevy_pbr/src/nodes/lights_node.rs +++ b/crates/bevy_pbr/src/nodes/lights_node.rs @@ -131,8 +131,10 @@ pub fn lights_node_system( data[0..light_count_size].copy_from_slice([light_count as u32, 0, 0, 0].as_bytes()); // light array - for ((light, transform, translation), slot) in - query.iter().iter().zip(data[light_count_size..current_light_uniform_size].chunks_exact_mut(size)) + for ((light, transform, translation), slot) in query + .iter() + .iter() + .zip(data[light_count_size..current_light_uniform_size].chunks_exact_mut(size)) { slot.copy_from_slice( LightRaw::from(&light, &transform.value, &translation).as_bytes(), diff --git a/crates/bevy_property/bevy_property_derive/src/lib.rs b/crates/bevy_property/bevy_property_derive/src/lib.rs index 856dfa9eff..567811040b 100644 --- a/crates/bevy_property/bevy_property_derive/src/lib.rs +++ b/crates/bevy_property/bevy_property_derive/src/lib.rs @@ -3,11 +3,11 @@ extern crate proc_macro; mod modules; use modules::{get_modules, get_path}; -use proc_macro::{TokenStream}; +use proc_macro::TokenStream; use proc_macro_crate::crate_name; use quote::quote; use syn::{ - parse::{ParseStream, Parse}, + parse::{Parse, ParseStream}, parse_macro_input, punctuated::Punctuated, token::{Comma, Where}, @@ -48,19 +48,20 @@ pub fn derive_properties(input: TokenStream) -> TokenStream { f, f.attrs .iter() - .find(|a| a.path.get_ident().as_ref().unwrap().to_string() == PROP_ATTRIBUTE_NAME) + .find(|a| { + a.path.get_ident().as_ref().unwrap().to_string() == PROP_ATTRIBUTE_NAME + }) .map(|a| { syn::custom_keyword!(ignore); - let mut attribute_args = PropAttributeArgs { - ignore: None, - }; + let mut attribute_args = PropAttributeArgs { ignore: None }; a.parse_args_with(|input: ParseStream| { if let Some(_) = input.parse::>()? { attribute_args.ignore = Some(true); return Ok(()); } Ok(()) - }).expect("invalid 'property' attribute format"); + }) + .expect("invalid 'property' attribute format"); attribute_args }), diff --git a/crates/bevy_render/src/draw.rs b/crates/bevy_render/src/draw.rs index ddac811a1c..ef1d585715 100644 --- a/crates/bevy_render/src/draw.rs +++ b/crates/bevy_render/src/draw.rs @@ -11,7 +11,10 @@ use crate::{ shader::Shader, }; use bevy_asset::{Assets, Handle}; -use bevy_ecs::{Archetype, FetchResource, Query, Res, ResMut, ResourceQuery, Resources, SystemId}; +use bevy_ecs::{ + resource_query::UnsafeClone, Archetype, FetchResource, Query, Res, ResMut, ResourceQuery, + Resources, SystemId, +}; use bevy_property::Properties; use std::{any::TypeId, collections::HashMap, ops::Range, sync::Arc}; use thiserror::Error; @@ -115,7 +118,6 @@ pub enum DrawError { BufferAllocationFailure, } -#[derive(Clone)] pub struct DrawContext<'a> { pub pipelines: ResMut<'a, Assets>, pub shaders: ResMut<'a, Assets>, @@ -126,6 +128,20 @@ pub struct DrawContext<'a> { pub current_pipeline: Option>, } +impl<'a> UnsafeClone for DrawContext<'a> { + unsafe fn unsafe_clone(&self) -> Self { + Self { + pipelines: self.pipelines.unsafe_clone(), + shaders: self.shaders.unsafe_clone(), + pipeline_compiler: self.pipeline_compiler.unsafe_clone(), + render_resource_context: self.render_resource_context.unsafe_clone(), + vertex_buffer_descriptors: self.vertex_buffer_descriptors.unsafe_clone(), + shared_buffers: self.shared_buffers.unsafe_clone(), + current_pipeline: self.current_pipeline.clone(), + } + } +} + impl<'a> ResourceQuery for DrawContext<'a> { type Fetch = FetchDrawContext; } diff --git a/crates/bevy_render/src/pass/ops.rs b/crates/bevy_render/src/pass/ops.rs index 4a54e02e8d..68a698541d 100644 --- a/crates/bevy_render/src/pass/ops.rs +++ b/crates/bevy_render/src/pass/ops.rs @@ -14,4 +14,4 @@ pub struct Operations { pub load: LoadOp, /// Whether data will be written to through this attachment. pub store: bool, -} \ No newline at end of file +} diff --git a/crates/bevy_render/src/render_graph/nodes/pass_node.rs b/crates/bevy_render/src/render_graph/nodes/pass_node.rs index f5ac02aa11..4ac3247cc7 100644 --- a/crates/bevy_render/src/render_graph/nodes/pass_node.rs +++ b/crates/bevy_render/src/render_graph/nodes/pass_node.rs @@ -1,6 +1,6 @@ use crate::{ draw::{Draw, RenderCommand}, - pass::{ClearColor, PassDescriptor, TextureAttachment, LoadOp}, + pass::{ClearColor, LoadOp, PassDescriptor, TextureAttachment}, pipeline::{ BindGroupDescriptor, BindType, BindingDescriptor, PipelineDescriptor, UniformProperty, }, diff --git a/crates/bevy_render/src/render_graph/nodes/render_resources_node.rs b/crates/bevy_render/src/render_graph/nodes/render_resources_node.rs index 4326bf2da3..5190b2c43b 100644 --- a/crates/bevy_render/src/render_graph/nodes/render_resources_node.rs +++ b/crates/bevy_render/src/render_graph/nodes/render_resources_node.rs @@ -599,7 +599,9 @@ fn asset_render_resources_node_system( state .uniform_buffer_arrays .setup_buffer_arrays(render_resource_context, state.dynamic_uniforms); - state.uniform_buffer_arrays.update_staging_buffer(render_resource_context); + state + .uniform_buffer_arrays + .update_staging_buffer(render_resource_context); for asset_handle in modified_assets.iter() { let asset = assets.get(&asset_handle).expect(EXPECT_ASSET_MESSAGE); diff --git a/crates/bevy_render/src/renderer/render_resource_context.rs b/crates/bevy_render/src/renderer/render_resource_context.rs index 2286ad35be..fb3e85ee43 100644 --- a/crates/bevy_render/src/renderer/render_resource_context.rs +++ b/crates/bevy_render/src/renderer/render_resource_context.rs @@ -24,14 +24,8 @@ pub trait RenderResourceContext: Downcast + Send + Sync + 'static { range: Range, write: &mut dyn FnMut(&mut [u8], &dyn RenderResourceContext), ); - fn map_buffer( - &self, - id: BufferId, - ); - fn unmap_buffer( - &self, - id: BufferId, - ); + fn map_buffer(&self, id: BufferId); + fn unmap_buffer(&self, id: BufferId); fn create_buffer_with_data(&self, buffer_info: BufferInfo, data: &[u8]) -> BufferId; fn create_shader_module(&self, shader_handle: Handle, shaders: &Assets); fn create_shader_module_from_source(&self, shader_handle: Handle, shader: &Shader); diff --git a/crates/bevy_wgpu/src/renderer/wgpu_render_context.rs b/crates/bevy_wgpu/src/renderer/wgpu_render_context.rs index b88f971fa6..ea1a1c4a4f 100644 --- a/crates/bevy_wgpu/src/renderer/wgpu_render_context.rs +++ b/crates/bevy_wgpu/src/renderer/wgpu_render_context.rs @@ -228,7 +228,13 @@ fn create_wgpu_depth_stencil_attachment_descriptor<'a>( wgpu::RenderPassDepthStencilAttachmentDescriptor { attachment, - depth_ops: depth_stencil_attachment_descriptor.depth_ops.as_ref().map(|ops| ops.wgpu_into()), - stencil_ops: depth_stencil_attachment_descriptor.stencil_ops.as_ref().map(|ops| ops.wgpu_into()), + depth_ops: depth_stencil_attachment_descriptor + .depth_ops + .as_ref() + .map(|ops| ops.wgpu_into()), + stencil_ops: depth_stencil_attachment_descriptor + .stencil_ops + .as_ref() + .map(|ops| ops.wgpu_into()), } }