mirror of
https://github.com/bevyengine/bevy
synced 2024-11-10 07:04:33 +00:00
remove unsafe Clone implementation on Res/ResMut in favor of UnsafeClone
This commit is contained in:
parent
df17d166cf
commit
17f3860d12
12 changed files with 96 additions and 54 deletions
|
@ -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::<Option<ignore>>()? {
|
||||
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::<Option<ignore>>()? {
|
||||
vertex_attributes.ignore = true;
|
||||
return Ok(());
|
||||
}
|
||||
Ok(())
|
||||
})
|
||||
.expect("invalid 'vertex' attribute format");
|
||||
|
||||
vertex_attributes
|
||||
}),
|
||||
vertex_attributes
|
||||
},
|
||||
),
|
||||
)
|
||||
})
|
||||
.collect::<Vec<(&Field, VertexAttributes)>>();
|
||||
|
|
|
@ -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<dyn System> {
|
||||
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<dyn System> {
|
||||
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,)*) }
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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<TypeId, Archetype>);
|
||||
fn release(resource_archetypes: &HashMap<TypeId, Archetype>);
|
||||
|
@ -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(),)*)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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::<Option<ignore>>()? {
|
||||
attribute_args.ignore = Some(true);
|
||||
return Ok(());
|
||||
}
|
||||
Ok(())
|
||||
}).expect("invalid 'property' attribute format");
|
||||
})
|
||||
.expect("invalid 'property' attribute format");
|
||||
|
||||
attribute_args
|
||||
}),
|
||||
|
|
|
@ -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<PipelineDescriptor>>,
|
||||
pub shaders: ResMut<'a, Assets<Shader>>,
|
||||
|
@ -126,6 +128,20 @@ pub struct DrawContext<'a> {
|
|||
pub current_pipeline: Option<Handle<PipelineDescriptor>>,
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
},
|
||||
|
|
|
@ -599,7 +599,9 @@ fn asset_render_resources_node_system<T: RenderResources>(
|
|||
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);
|
||||
|
|
|
@ -24,14 +24,8 @@ pub trait RenderResourceContext: Downcast + Send + Sync + 'static {
|
|||
range: Range<u64>,
|
||||
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<Shader>, shaders: &Assets<Shader>);
|
||||
fn create_shader_module_from_source(&self, shader_handle: Handle<Shader>, shader: &Shader);
|
||||
|
|
|
@ -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()),
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue