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::{
|
use crate::modules::{get_modules, get_path};
|
||||||
modules::{get_modules, get_path},
|
|
||||||
};
|
|
||||||
use inflector::Inflector;
|
use inflector::Inflector;
|
||||||
use proc_macro::TokenStream;
|
use proc_macro::TokenStream;
|
||||||
use quote::{format_ident, quote};
|
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)]
|
#[derive(Default)]
|
||||||
struct VertexAttributes {
|
struct VertexAttributes {
|
||||||
|
@ -31,22 +31,29 @@ pub fn derive_as_vertex_buffer_descriptor(input: TokenStream) -> TokenStream {
|
||||||
.map(|field| {
|
.map(|field| {
|
||||||
(
|
(
|
||||||
field,
|
field,
|
||||||
field.attrs
|
field
|
||||||
|
.attrs
|
||||||
.iter()
|
.iter()
|
||||||
.find(|a| a.path.get_ident().as_ref().unwrap().to_string() == VERTEX_ATTRIBUTE_NAME)
|
.find(|a| {
|
||||||
.map_or_else(|| VertexAttributes::default() ,|a| {
|
a.path.get_ident().as_ref().unwrap().to_string() == VERTEX_ATTRIBUTE_NAME
|
||||||
syn::custom_keyword!(ignore);
|
})
|
||||||
let mut vertex_attributes = VertexAttributes::default();
|
.map_or_else(
|
||||||
a.parse_args_with(|input: ParseStream| {
|
|| VertexAttributes::default(),
|
||||||
if let Some(_) = input.parse::<Option<ignore>>()? {
|
|a| {
|
||||||
vertex_attributes.ignore = true;
|
syn::custom_keyword!(ignore);
|
||||||
return Ok(());
|
let mut vertex_attributes = VertexAttributes::default();
|
||||||
}
|
a.parse_args_with(|input: ParseStream| {
|
||||||
Ok(())
|
if let Some(_) = input.parse::<Option<ignore>>()? {
|
||||||
}).expect("invalid 'vertex' attribute format");
|
vertex_attributes.ignore = true;
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
})
|
||||||
|
.expect("invalid 'vertex' attribute format");
|
||||||
|
|
||||||
vertex_attributes
|
vertex_attributes
|
||||||
}),
|
},
|
||||||
|
),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.collect::<Vec<(&Field, VertexAttributes)>>();
|
.collect::<Vec<(&Field, VertexAttributes)>>();
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
resource_query::{FetchResource, ResourceQuery},
|
resource_query::{FetchResource, ResourceQuery, UnsafeClone},
|
||||||
system::{System, SystemId, ThreadLocalExecution},
|
system::{System, SystemId, ThreadLocalExecution},
|
||||||
Commands, Resources,
|
Commands, Resources,
|
||||||
};
|
};
|
||||||
|
@ -74,6 +74,7 @@ macro_rules! impl_into_foreach_system {
|
||||||
{
|
{
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
|
#[allow(unused_unsafe)]
|
||||||
fn system(mut self) -> Box<dyn System> {
|
fn system(mut self) -> Box<dyn System> {
|
||||||
let id = SystemId::new();
|
let id = SystemId::new();
|
||||||
Box::new(SystemFn {
|
Box::new(SystemFn {
|
||||||
|
@ -136,6 +137,7 @@ macro_rules! impl_into_query_system {
|
||||||
{
|
{
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
|
#[allow(unused_unsafe)]
|
||||||
fn system(mut self) -> Box<dyn System> {
|
fn system(mut self) -> Box<dyn System> {
|
||||||
let id = SystemId::new();
|
let id = SystemId::new();
|
||||||
Box::new(SystemFn {
|
Box::new(SystemFn {
|
||||||
|
@ -163,10 +165,10 @@ macro_rules! impl_into_query_system {
|
||||||
|
|
||||||
macro_rules! fn_call {
|
macro_rules! fn_call {
|
||||||
($self:ident, ($($commands: ident, $commands_var: ident)*), ($($resource: ident),*), ($($a: ident),*)) => {
|
($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:ident, (), ($($resource: ident),*), ($($a: ident),*)) => {
|
||||||
$self($($resource.clone(),)* $($a,)*)
|
unsafe { $self($($resource.unsafe_clone(),)* $($a,)*) }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ mod commands;
|
||||||
mod into_system;
|
mod into_system;
|
||||||
#[cfg(feature = "profiler")]
|
#[cfg(feature = "profiler")]
|
||||||
pub mod profiler;
|
pub mod profiler;
|
||||||
mod resource_query;
|
pub mod resource_query;
|
||||||
mod resources;
|
mod resources;
|
||||||
mod schedule;
|
mod schedule;
|
||||||
mod system;
|
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
|
// 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> {
|
impl<'a, T: Component> UnsafeClone for ResMut<'a, T> {
|
||||||
fn clone(&self) -> Self {
|
unsafe fn unsafe_clone(&self) -> Self {
|
||||||
Self {
|
Self {
|
||||||
archetype: self.archetype,
|
archetype: self.archetype,
|
||||||
target: self.target,
|
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> {
|
impl<'a, T: Component> UnsafeClone for Res<'a, T> {
|
||||||
fn clone(&self) -> Self {
|
unsafe fn unsafe_clone(&self) -> Self {
|
||||||
Self {
|
Self {
|
||||||
archetype: self.archetype,
|
archetype: self.archetype,
|
||||||
target: self.target,
|
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> UnsafeClone for Local<'a, T> {
|
||||||
impl<'a, T: Component + FromResources> Clone for Local<'a, T> {
|
unsafe fn unsafe_clone(&self) -> Self {
|
||||||
fn clone(&self) -> Self {
|
|
||||||
Self {
|
Self {
|
||||||
archetype: self.archetype,
|
archetype: self.archetype,
|
||||||
target: self.target,
|
target: self.target,
|
||||||
|
@ -143,7 +146,7 @@ pub trait ResourceQuery {
|
||||||
/// Streaming iterators over contiguous homogeneous ranges of components
|
/// Streaming iterators over contiguous homogeneous ranges of components
|
||||||
pub trait FetchResource<'a>: Sized {
|
pub trait FetchResource<'a>: Sized {
|
||||||
/// Type of value to be fetched
|
/// Type of value to be fetched
|
||||||
type Item: Clone;
|
type Item: UnsafeClone;
|
||||||
|
|
||||||
fn borrow(resource_archetypes: &HashMap<TypeId, Archetype>);
|
fn borrow(resource_archetypes: &HashMap<TypeId, Archetype>);
|
||||||
fn release(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);)*
|
$($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());
|
data[0..light_count_size].copy_from_slice([light_count as u32, 0, 0, 0].as_bytes());
|
||||||
|
|
||||||
// light array
|
// light array
|
||||||
for ((light, transform, translation), slot) in
|
for ((light, transform, translation), slot) in query
|
||||||
query.iter().iter().zip(data[light_count_size..current_light_uniform_size].chunks_exact_mut(size))
|
.iter()
|
||||||
|
.iter()
|
||||||
|
.zip(data[light_count_size..current_light_uniform_size].chunks_exact_mut(size))
|
||||||
{
|
{
|
||||||
slot.copy_from_slice(
|
slot.copy_from_slice(
|
||||||
LightRaw::from(&light, &transform.value, &translation).as_bytes(),
|
LightRaw::from(&light, &transform.value, &translation).as_bytes(),
|
||||||
|
|
|
@ -3,11 +3,11 @@ extern crate proc_macro;
|
||||||
mod modules;
|
mod modules;
|
||||||
|
|
||||||
use modules::{get_modules, get_path};
|
use modules::{get_modules, get_path};
|
||||||
use proc_macro::{TokenStream};
|
use proc_macro::TokenStream;
|
||||||
use proc_macro_crate::crate_name;
|
use proc_macro_crate::crate_name;
|
||||||
use quote::quote;
|
use quote::quote;
|
||||||
use syn::{
|
use syn::{
|
||||||
parse::{ParseStream, Parse},
|
parse::{Parse, ParseStream},
|
||||||
parse_macro_input,
|
parse_macro_input,
|
||||||
punctuated::Punctuated,
|
punctuated::Punctuated,
|
||||||
token::{Comma, Where},
|
token::{Comma, Where},
|
||||||
|
@ -48,19 +48,20 @@ pub fn derive_properties(input: TokenStream) -> TokenStream {
|
||||||
f,
|
f,
|
||||||
f.attrs
|
f.attrs
|
||||||
.iter()
|
.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| {
|
.map(|a| {
|
||||||
syn::custom_keyword!(ignore);
|
syn::custom_keyword!(ignore);
|
||||||
let mut attribute_args = PropAttributeArgs {
|
let mut attribute_args = PropAttributeArgs { ignore: None };
|
||||||
ignore: None,
|
|
||||||
};
|
|
||||||
a.parse_args_with(|input: ParseStream| {
|
a.parse_args_with(|input: ParseStream| {
|
||||||
if let Some(_) = input.parse::<Option<ignore>>()? {
|
if let Some(_) = input.parse::<Option<ignore>>()? {
|
||||||
attribute_args.ignore = Some(true);
|
attribute_args.ignore = Some(true);
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}).expect("invalid 'property' attribute format");
|
})
|
||||||
|
.expect("invalid 'property' attribute format");
|
||||||
|
|
||||||
attribute_args
|
attribute_args
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -11,7 +11,10 @@ use crate::{
|
||||||
shader::Shader,
|
shader::Shader,
|
||||||
};
|
};
|
||||||
use bevy_asset::{Assets, Handle};
|
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 bevy_property::Properties;
|
||||||
use std::{any::TypeId, collections::HashMap, ops::Range, sync::Arc};
|
use std::{any::TypeId, collections::HashMap, ops::Range, sync::Arc};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
@ -115,7 +118,6 @@ pub enum DrawError {
|
||||||
BufferAllocationFailure,
|
BufferAllocationFailure,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct DrawContext<'a> {
|
pub struct DrawContext<'a> {
|
||||||
pub pipelines: ResMut<'a, Assets<PipelineDescriptor>>,
|
pub pipelines: ResMut<'a, Assets<PipelineDescriptor>>,
|
||||||
pub shaders: ResMut<'a, Assets<Shader>>,
|
pub shaders: ResMut<'a, Assets<Shader>>,
|
||||||
|
@ -126,6 +128,20 @@ pub struct DrawContext<'a> {
|
||||||
pub current_pipeline: Option<Handle<PipelineDescriptor>>,
|
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> {
|
impl<'a> ResourceQuery for DrawContext<'a> {
|
||||||
type Fetch = FetchDrawContext;
|
type Fetch = FetchDrawContext;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,4 +14,4 @@ pub struct Operations<V> {
|
||||||
pub load: LoadOp<V>,
|
pub load: LoadOp<V>,
|
||||||
/// Whether data will be written to through this attachment.
|
/// Whether data will be written to through this attachment.
|
||||||
pub store: bool,
|
pub store: bool,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
draw::{Draw, RenderCommand},
|
draw::{Draw, RenderCommand},
|
||||||
pass::{ClearColor, PassDescriptor, TextureAttachment, LoadOp},
|
pass::{ClearColor, LoadOp, PassDescriptor, TextureAttachment},
|
||||||
pipeline::{
|
pipeline::{
|
||||||
BindGroupDescriptor, BindType, BindingDescriptor, PipelineDescriptor, UniformProperty,
|
BindGroupDescriptor, BindType, BindingDescriptor, PipelineDescriptor, UniformProperty,
|
||||||
},
|
},
|
||||||
|
|
|
@ -599,7 +599,9 @@ fn asset_render_resources_node_system<T: RenderResources>(
|
||||||
state
|
state
|
||||||
.uniform_buffer_arrays
|
.uniform_buffer_arrays
|
||||||
.setup_buffer_arrays(render_resource_context, state.dynamic_uniforms);
|
.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() {
|
for asset_handle in modified_assets.iter() {
|
||||||
let asset = assets.get(&asset_handle).expect(EXPECT_ASSET_MESSAGE);
|
let asset = assets.get(&asset_handle).expect(EXPECT_ASSET_MESSAGE);
|
||||||
|
|
|
@ -24,14 +24,8 @@ pub trait RenderResourceContext: Downcast + Send + Sync + 'static {
|
||||||
range: Range<u64>,
|
range: Range<u64>,
|
||||||
write: &mut dyn FnMut(&mut [u8], &dyn RenderResourceContext),
|
write: &mut dyn FnMut(&mut [u8], &dyn RenderResourceContext),
|
||||||
);
|
);
|
||||||
fn map_buffer(
|
fn map_buffer(&self, id: BufferId);
|
||||||
&self,
|
fn unmap_buffer(&self, id: BufferId);
|
||||||
id: BufferId,
|
|
||||||
);
|
|
||||||
fn unmap_buffer(
|
|
||||||
&self,
|
|
||||||
id: BufferId,
|
|
||||||
);
|
|
||||||
fn create_buffer_with_data(&self, buffer_info: BufferInfo, data: &[u8]) -> 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(&self, shader_handle: Handle<Shader>, shaders: &Assets<Shader>);
|
||||||
fn create_shader_module_from_source(&self, shader_handle: Handle<Shader>, shader: &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 {
|
wgpu::RenderPassDepthStencilAttachmentDescriptor {
|
||||||
attachment,
|
attachment,
|
||||||
depth_ops: depth_stencil_attachment_descriptor.depth_ops.as_ref().map(|ops| ops.wgpu_into()),
|
depth_ops: depth_stencil_attachment_descriptor
|
||||||
stencil_ops: depth_stencil_attachment_descriptor.stencil_ops.as_ref().map(|ops| ops.wgpu_into()),
|
.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