From 946d5d1024619c76c48e385889b8293383f78dfa Mon Sep 17 00:00:00 2001 From: Carter Anderson Date: Sun, 19 Jul 2020 14:23:06 -0700 Subject: [PATCH] ecs: refactor resources fixes unintialized global resource memory --- crates/bevy_app/src/schedule_runner.rs | 4 +- .../bevy_ecs/src/resource/resource_query.rs | 178 +++++++---------- crates/bevy_ecs/src/resource/resources.rs | 184 ++++++++++-------- crates/bevy_ecs/src/system/into_system.rs | 8 +- crates/bevy_render/src/draw.rs | 92 ++++----- .../src/render_graph/nodes/pass_node.rs | 2 +- crates/bevy_winit/src/lib.rs | 2 +- 7 files changed, 209 insertions(+), 261 deletions(-) diff --git a/crates/bevy_app/src/schedule_runner.rs b/crates/bevy_app/src/schedule_runner.rs index 912682d197..d714abe17f 100644 --- a/crates/bevy_app/src/schedule_runner.rs +++ b/crates/bevy_app/src/schedule_runner.rs @@ -45,7 +45,7 @@ impl AppPlugin for ScheduleRunnerPlugin { app.schedule.run(&mut app.world, &mut app.resources); } RunMode::Loop { wait } => loop { - if let Ok(app_exit_events) = app.resources.get_mut::>() { + if let Some(app_exit_events) = app.resources.get_mut::>() { if app_exit_event_reader.latest(&app_exit_events).is_some() { break; } @@ -53,7 +53,7 @@ impl AppPlugin for ScheduleRunnerPlugin { app.schedule.run(&mut app.world, &mut app.resources); - if let Ok(app_exit_events) = app.resources.get_mut::>() { + if let Some(app_exit_events) = app.resources.get_mut::>() { if app_exit_event_reader.latest(&app_exit_events).is_some() { break; } diff --git a/crates/bevy_ecs/src/resource/resource_query.rs b/crates/bevy_ecs/src/resource/resource_query.rs index 2aaf6d734f..12b633bf10 100644 --- a/crates/bevy_ecs/src/resource/resource_query.rs +++ b/crates/bevy_ecs/src/resource/resource_query.rs @@ -1,31 +1,26 @@ +use super::{FromResources, Resources}; use crate::{ system::{SystemId, TypeAccess}, + ResourceIndex, }; use core::{ any::TypeId, ops::{Deref, DerefMut}, ptr::NonNull, }; -use hecs::{smaller_tuples_too, MissingComponent, Component, Archetype}; -use std::collections::HashMap; -use super::{Resources, FromResources}; +use hecs::{smaller_tuples_too, Component}; +use std::marker::PhantomData; + /// Shared borrow of an entity's component pub struct Res<'a, T: Component> { - archetype: &'a Archetype, - target: NonNull, + value: &'a T, } impl<'a, T: Component> Res<'a, T> { - #[allow(missing_docs)] - pub unsafe fn new(archetype: &'a Archetype, index: u32) -> Result { - let target = NonNull::new_unchecked( - archetype - .get::() - .ok_or_else(MissingComponent::new::)? - .as_ptr() - .add(index as usize), - ); - Ok(Self { archetype, target }) + pub unsafe fn new(value: NonNull) -> Self { + Self { + value: &*value.as_ptr(), + } } } @@ -33,22 +28,9 @@ 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> UnsafeClone for ResMut<'a, T> { - unsafe fn unsafe_clone(&self) -> Self { - Self { - archetype: self.archetype, - target: self.target, - } - } -} - impl<'a, T: Component> UnsafeClone for Res<'a, T> { unsafe fn unsafe_clone(&self) -> Self { - Self { - archetype: self.archetype, - target: self.target, - } + Self { value: self.value } } } @@ -58,27 +40,22 @@ unsafe impl Sync for Res<'_, T> {} impl<'a, T: Component> Deref for Res<'a, T> { type Target = T; fn deref(&self) -> &T { - unsafe { self.target.as_ref() } + self.value } } /// Unique borrow of a resource pub struct ResMut<'a, T: Component> { - archetype: &'a Archetype, - target: NonNull, + _marker: PhantomData<&'a T>, + value: *mut T, } impl<'a, T: Component> ResMut<'a, T> { - #[allow(missing_docs)] - pub unsafe fn new(archetype: &'a Archetype, index: u32) -> Result { - let target = NonNull::new_unchecked( - archetype - .get::() - .ok_or_else(MissingComponent::new::)? - .as_ptr() - .add(index as usize), - ); - Ok(Self { archetype, target }) + pub unsafe fn new(value: NonNull) -> Self { + Self { + value: value.as_ptr(), + _marker: Default::default(), + } } } @@ -88,40 +65,35 @@ unsafe impl Sync for ResMut<'_, T> {} impl<'a, T: Component> Deref for ResMut<'a, T> { type Target = T; fn deref(&self) -> &T { - unsafe { self.target.as_ref() } + unsafe { &*self.value } } } impl<'a, T: Component> DerefMut for ResMut<'a, T> { fn deref_mut(&mut self) -> &mut T { - unsafe { self.target.as_mut() } + unsafe { &mut *self.value } + } +} + +impl<'a, T: Component> UnsafeClone for ResMut<'a, T> { + unsafe fn unsafe_clone(&self) -> Self { + Self { + value: self.value, + _marker: Default::default(), + } } } pub struct Local<'a, T: Component + FromResources> { - archetype: &'a Archetype, - target: NonNull, -} - -impl<'a, T: Component + FromResources> Local<'a, T> { - #[allow(missing_docs)] - pub unsafe fn new(archetype: &'a Archetype, index: u32) -> Result { - let target = NonNull::new_unchecked( - archetype - .get::() - .ok_or_else(MissingComponent::new::)? - .as_ptr() - .add(index as usize), - ); - Ok(Self { archetype, target }) - } + value: *mut T, + _marker: PhantomData<&'a T>, } impl<'a, T: Component + FromResources> UnsafeClone for Local<'a, T> { unsafe fn unsafe_clone(&self) -> Self { Self { - archetype: self.archetype, - target: self.target, + value: self.value, + _marker: Default::default(), } } } @@ -129,13 +101,13 @@ impl<'a, T: Component + FromResources> UnsafeClone for Local<'a, T> { impl<'a, T: Component + FromResources> Deref for Local<'a, T> { type Target = T; fn deref(&self) -> &T { - unsafe { self.target.as_ref() } + unsafe { &*self.value } } } impl<'a, T: Component + FromResources> DerefMut for Local<'a, T> { fn deref_mut(&mut self) -> &mut T { - unsafe { self.target.as_mut() } + unsafe { &mut *self.value } } } @@ -152,8 +124,8 @@ pub trait FetchResource<'a>: Sized { type Item: UnsafeClone; fn access() -> TypeAccess; - fn borrow(resource_archetypes: &HashMap); - fn release(resource_archetypes: &HashMap); + fn borrow(resources: &Resources); + fn release(resources: &Resources); /// Construct a `Fetch` for `archetype` if it should be traversed /// @@ -171,19 +143,17 @@ pub struct FetchResourceRead(NonNull); impl<'a, T: Component> FetchResource<'a> for FetchResourceRead { type Item = Res<'a, T>; unsafe fn get(resources: &'a Resources, _system_id: Option) -> Self::Item { - resources.get_res::() + Res::new(resources.get_unsafe_ref::(ResourceIndex::Global)) } - fn borrow(resource_archetypes: &HashMap) { - if let Some(archetype) = resource_archetypes.get(&TypeId::of::()) { - archetype.borrow::(); - } + fn borrow(resources: &Resources) { + resources.borrow::(); } - fn release(resource_archetypes: &HashMap) { - if let Some(archetype) = resource_archetypes.get(&TypeId::of::()) { - archetype.release::(); - } + + fn release(resources: &Resources) { + resources.release::(); } + fn access() -> TypeAccess { let mut access = TypeAccess::default(); access.immutable.insert(TypeId::of::()); @@ -200,19 +170,17 @@ pub struct FetchResourceWrite(NonNull); impl<'a, T: Component> FetchResource<'a> for FetchResourceWrite { type Item = ResMut<'a, T>; unsafe fn get(resources: &'a Resources, _system_id: Option) -> Self::Item { - resources.get_res_mut::() + ResMut::new(resources.get_unsafe_ref::(ResourceIndex::Global)) } - fn borrow(resource_archetypes: &HashMap) { - if let Some(archetype) = resource_archetypes.get(&TypeId::of::()) { - archetype.borrow_mut::(); - } + fn borrow(resources: &Resources) { + resources.borrow_mut::(); } - fn release(resource_archetypes: &HashMap) { - if let Some(archetype) = resource_archetypes.get(&TypeId::of::()) { - archetype.release_mut::(); - } + + fn release(resources: &Resources) { + resources.release_mut::(); } + fn access() -> TypeAccess { let mut access = TypeAccess::default(); access.mutable.insert(TypeId::of::()); @@ -235,33 +203,23 @@ pub struct FetchResourceLocalMut(NonNull); impl<'a, T: Component + FromResources> FetchResource<'a> for FetchResourceLocalMut { type Item = Local<'a, T>; unsafe fn get(resources: &'a Resources, system_id: Option) -> Self::Item { - if let Some(system_id) = system_id { - let archetype = resources - .resource_archetypes - .get(&TypeId::of::()) - .unwrap_or_else(|| { - panic!("Resource does not exist {}", std::any::type_name::()) - }); - let index = resources - .system_id_to_archetype_index - .get(&system_id.0) - .expect("System does not have this resource"); - Local::new(archetype, *index).expect("Resource does not exist") - } else { - panic!("Only Systems can use Local resources"); + let id = system_id.expect("Local resources can only be used by systems"); + Local { + value: resources + .get_unsafe_ref::(ResourceIndex::System(id)) + .as_ptr(), + _marker: Default::default(), } } - fn borrow(resource_archetypes: &HashMap) { - if let Some(archetype) = resource_archetypes.get(&TypeId::of::()) { - archetype.borrow_mut::(); - } + fn borrow(resources: &Resources) { + resources.borrow_mut::(); } - fn release(resource_archetypes: &HashMap) { - if let Some(archetype) = resource_archetypes.get(&TypeId::of::()) { - archetype.release_mut::(); - } + + fn release(resources: &Resources) { + resources.release_mut::(); } + fn access() -> TypeAccess { let mut access = TypeAccess::default(); access.mutable.insert(TypeId::of::()); @@ -275,13 +233,13 @@ macro_rules! tuple_impl { type Item = ($($name::Item,)*); #[allow(unused_variables)] - fn borrow(resource_archetypes: &HashMap) { - $($name::borrow(resource_archetypes);)* + fn borrow(resources: &Resources) { + $($name::borrow(resources);)* } #[allow(unused_variables)] - fn release(resource_archetypes: &HashMap) { - $($name::release(resource_archetypes);)* + fn release(resources: &Resources) { + $($name::release(resources);)* } #[allow(unused_variables)] diff --git a/crates/bevy_ecs/src/resource/resources.rs b/crates/bevy_ecs/src/resource/resources.rs index b88f0d01da..5630a21d77 100644 --- a/crates/bevy_ecs/src/resource/resources.rs +++ b/crates/bevy_ecs/src/resource/resources.rs @@ -1,78 +1,79 @@ -use super::{FetchResource, Res, ResMut, ResourceQuery}; +use super::{FetchResource, ResourceQuery}; use crate::system::SystemId; use core::any::TypeId; -use hecs::{Archetype, ComponentError, Ref, RefMut, TypeInfo}; -use std::collections::HashMap; +use hecs::{Archetype, Ref, RefMut, TypeInfo}; +use std::{collections::HashMap, ptr::NonNull}; pub trait Resource: Send + Sync + 'static {} impl Resource for T {} +pub struct ResourceData { + archetype: Archetype, + default_index: Option, + system_id_to_archetype_index: HashMap, +} + +pub enum ResourceIndex { + Global, + System(SystemId), +} + #[derive(Default)] pub struct Resources { - pub(crate) resource_archetypes: HashMap, - pub(crate) system_id_to_archetype_index: HashMap, + pub(crate) resource_data: HashMap, } impl Resources { pub fn insert(&mut self, resource: T) { - self.insert_index(resource, 0); + self.insert_resource(resource, ResourceIndex::Global); } pub fn contains(&self) -> bool { - self.get_index::(0).is_ok() + self.get_resource::(ResourceIndex::Global).is_some() } - pub fn get(&self) -> Result, ComponentError> { - self.get_index(0) + pub fn get(&self) -> Option> { + self.get_resource(ResourceIndex::Global) } - pub fn get_mut(&self) -> Result, ComponentError> { - self.get_index_mut(0) + pub fn get_mut(&self) -> Option> { + self.get_resource_mut(ResourceIndex::Global) } - pub fn get_local<'a, T: Resource>( - &'a self, - id: SystemId, - ) -> Result, ComponentError> { - self.system_id_to_archetype_index - .get(&id.0) - .ok_or_else(|| ComponentError::NoSuchEntity) - .and_then(|index| self.get_index(*index)) + pub fn get_local<'a, T: Resource>(&'a self, id: SystemId) -> Option> { + self.get_resource(ResourceIndex::System(id)) } - pub fn get_local_mut<'a, T: Resource>( - &'a self, - id: SystemId, - ) -> Result, ComponentError> { - self.system_id_to_archetype_index - .get(&id.0) - .ok_or_else(|| ComponentError::NoSuchEntity) - .and_then(|index| self.get_index_mut(*index)) + pub fn get_local_mut<'a, T: Resource>(&'a self, id: SystemId) -> Option> { + self.get_resource_mut(ResourceIndex::System(id)) } pub fn insert_local(&mut self, id: SystemId, resource: T) { - if let Some(index) = self.system_id_to_archetype_index.get(&id.0).cloned() { - self.insert_index(resource, index); - } else { - let mut index = self.archetype_len::(); - // index 0 is reserved for the global non-system resource - if index == 0 { - self.allocate_next::(); - index += 1; - } - self.insert_index(resource, index); - self.system_id_to_archetype_index.insert(id.0, index); - } + self.insert_resource(resource, ResourceIndex::System(id)) } - fn insert_index(&mut self, mut resource: T, index: u32) { + fn insert_resource(&mut self, mut resource: T, resource_index: ResourceIndex) { let type_id = TypeId::of::(); - let archetype = self.resource_archetypes.entry(type_id).or_insert_with(|| { + let data = self.resource_data.entry(type_id).or_insert_with(|| { let mut types = Vec::new(); types.push(TypeInfo::of::()); - Archetype::new(types) + ResourceData { + archetype: Archetype::new(types), + default_index: None, + system_id_to_archetype_index: HashMap::new(), + } }); + let archetype = &mut data.archetype; + + let index = match resource_index { + ResourceIndex::Global => *data.default_index.get_or_insert_with(|| archetype.len()), + ResourceIndex::System(id) => *data + .system_id_to_archetype_index + .entry(id.0) + .or_insert_with(|| archetype.len()), + }; + if index == archetype.len() { unsafe { archetype.allocate(index) }; } else if index > archetype.len() { @@ -86,42 +87,33 @@ impl Resources { } } - fn allocate_next(&mut self) { - let type_id = TypeId::of::(); - let archetype = self.resource_archetypes.entry(type_id).or_insert_with(|| { - let mut types = Vec::new(); - types.push(TypeInfo::of::()); - Archetype::new(types) - }); - - let index = archetype.len(); - unsafe { archetype.allocate(index) }; - } - - fn get_index(&self, index: u32) -> Result, ComponentError> { - self.resource_archetypes + fn get_resource(&self, resource_index: ResourceIndex) -> Option> { + self.resource_data .get(&TypeId::of::()) - .ok_or_else(|| ComponentError::NoSuchEntity) - .and_then(|archetype| unsafe { - Ref::new(archetype, index).map_err(|err| ComponentError::MissingComponent(err)) + .and_then(|data| unsafe { + let index = match resource_index { + ResourceIndex::Global => data.default_index?, + ResourceIndex::System(id) => *data.system_id_to_archetype_index.get(&id.0)?, + }; + Ref::new(&data.archetype, index).ok() }) } - fn get_index_mut(&self, index: u32) -> Result, ComponentError> { - self.resource_archetypes + fn get_resource_mut( + &self, + resource_index: ResourceIndex, + ) -> Option> { + self.resource_data .get(&TypeId::of::()) - .ok_or_else(|| ComponentError::NoSuchEntity) - .and_then(|archetype| unsafe { - RefMut::new(archetype, index).map_err(|err| ComponentError::MissingComponent(err)) + .and_then(|data| unsafe { + let index = match resource_index { + ResourceIndex::Global => data.default_index?, + ResourceIndex::System(id) => *data.system_id_to_archetype_index.get(&id.0)?, + }; + RefMut::new(&data.archetype, index).ok() }) } - fn archetype_len(&self) -> u32 { - self.resource_archetypes - .get(&TypeId::of::()) - .map_or(0, |a| a.len()) - } - pub fn query(&self) -> ::Item { unsafe { Q::Fetch::get(&self, None) } } @@ -134,21 +126,45 @@ impl Resources { } #[inline] - pub unsafe fn get_res(&self) -> Res<'_, T> { - let archetype = self - .resource_archetypes + pub unsafe fn get_unsafe_ref(&self, resource_index: ResourceIndex) -> NonNull { + self.resource_data .get(&TypeId::of::()) - .unwrap_or_else(|| panic!("Resource does not exist {}", std::any::type_name::())); - Res::new(archetype, 0).expect("Resource does not exist") + .and_then(|data| { + let index = match resource_index { + ResourceIndex::Global => data.default_index?, + ResourceIndex::System(id) => { + data.system_id_to_archetype_index.get(&id.0).cloned()? + } + }; + Some(NonNull::new_unchecked( + data.archetype.get::()?.as_ptr().add(index as usize), + )) + }) + .unwrap_or_else(|| panic!("Resource does not exist {}", std::any::type_name::())) } - #[inline] - pub unsafe fn get_res_mut(&self) -> ResMut<'_, T> { - let archetype = self - .resource_archetypes - .get(&TypeId::of::()) - .unwrap_or_else(|| panic!("Resource does not exist {}", std::any::type_name::())); - ResMut::new(archetype, 0).expect("Resource does not exist") + pub fn borrow(&self) { + if let Some(data) = self.resource_data.get(&TypeId::of::()) { + data.archetype.borrow::(); + } + } + + pub fn release(&self) { + if let Some(data) = self.resource_data.get(&TypeId::of::()) { + data.archetype.release::(); + } + } + + pub fn borrow_mut(&self) { + if let Some(data) = self.resource_data.get(&TypeId::of::()) { + data.archetype.borrow_mut::(); + } + } + + pub fn release_mut(&self) { + if let Some(data) = self.resource_data.get(&TypeId::of::()) { + data.archetype.release_mut::(); + } } } @@ -176,7 +192,7 @@ mod tests { #[test] fn resource() { let mut resources = Resources::default(); - assert!(resources.get::().is_err()); + assert!(resources.get::().is_none()); resources.insert(123); assert_eq!(*resources.get::().expect("resource exists"), 123); @@ -195,7 +211,7 @@ mod tests { assert_eq!(*resources.get::().expect("resource exists"), -1.0); - assert!(resources.get_local::(SystemId(0)).is_err()); + assert!(resources.get_local::(SystemId(0)).is_none()); resources.insert_local(SystemId(0), 111); assert_eq!( *resources diff --git a/crates/bevy_ecs/src/system/into_system.rs b/crates/bevy_ecs/src/system/into_system.rs index e9952084a3..8fe00c09cf 100644 --- a/crates/bevy_ecs/src/system/into_system.rs +++ b/crates/bevy_ecs/src/system/into_system.rs @@ -105,14 +105,14 @@ macro_rules! impl_into_foreach_system { name: core::any::type_name::().into(), id, func: move |world, resources, _archetype_access, state| { - <<($($resource,)*) as ResourceQuery>::Fetch as FetchResource>::borrow(&resources.resource_archetypes); + <<($($resource,)*) as ResourceQuery>::Fetch as FetchResource>::borrow(&resources); { let ($($resource,)*) = resources.query_system::<($($resource,)*)>(id); for ($($component,)*) in world.query::<($($component,)*)>().iter() { fn_call!(self, ($($commands, state)*), ($($resource),*), ($($component),*)) } } - <<($($resource,)*) as ResourceQuery>::Fetch as FetchResource>::release(&resources.resource_archetypes); + <<($($resource,)*) as ResourceQuery>::Fetch as FetchResource>::release(&resources); }, thread_local_func: move |world, resources, state| { state.apply(world, resources); @@ -251,7 +251,7 @@ macro_rules! impl_into_query_system { id, name: core::any::type_name::().into(), func: move |world, resources, archetype_access, state| { - <<($($resource,)*) as ResourceQuery>::Fetch as FetchResource>::borrow(&resources.resource_archetypes); + <<($($resource,)*) as ResourceQuery>::Fetch as FetchResource>::borrow(&resources); { let ($($resource,)*) = resources.query_system::<($($resource,)*)>(id); let mut i = 0; @@ -267,7 +267,7 @@ macro_rules! impl_into_query_system { let commands = &state.commands; fn_call!(self, ($($commands, commands)*), ($($resource),*), ($($query),*)) } - <<($($resource,)*) as ResourceQuery>::Fetch as FetchResource>::release(&resources.resource_archetypes); + <<($($resource,)*) as ResourceQuery>::Fetch as FetchResource>::release(&resources); }, thread_local_func: move |world, resources, state| { state.commands.apply(world, resources); diff --git a/crates/bevy_render/src/draw.rs b/crates/bevy_render/src/draw.rs index 0129a6aff8..c31f34cecc 100644 --- a/crates/bevy_render/src/draw.rs +++ b/crates/bevy_render/src/draw.rs @@ -11,11 +11,11 @@ use crate::{ }; use bevy_asset::{Assets, Handle}; use bevy_ecs::{ - Archetype, FetchResource, Query, Res, ResMut, ResourceQuery, Resources, SystemId, TypeAccess, - UnsafeClone, + FetchResource, Query, Res, ResMut, ResourceIndex, ResourceQuery, Resources, SystemId, + TypeAccess, UnsafeClone, }; use bevy_property::Properties; -use std::{any::TypeId, collections::HashMap, ops::Range, sync::Arc}; +use std::{any::TypeId, ops::Range, sync::Arc}; use thiserror::Error; #[derive(Debug, Clone, Eq, PartialEq)] @@ -150,66 +150,40 @@ pub struct FetchDrawContext; // TODO: derive this impl impl<'a> FetchResource<'a> for FetchDrawContext { type Item = DrawContext<'a>; - fn borrow(resource_archetypes: &HashMap) { - resource_archetypes - .get(&TypeId::of::>()) - .unwrap() - .borrow_mut::>(); - resource_archetypes - .get(&TypeId::of::>()) - .unwrap() - .borrow_mut::>(); - resource_archetypes - .get(&TypeId::of::()) - .unwrap() - .borrow_mut::(); - resource_archetypes - .get(&TypeId::of::>()) - .unwrap() - .borrow::>(); - resource_archetypes - .get(&TypeId::of::()) - .unwrap() - .borrow::(); - resource_archetypes - .get(&TypeId::of::()) - .unwrap() - .borrow::(); + fn borrow(resources: &Resources) { + resources.borrow_mut::>(); + resources.borrow_mut::>(); + resources.borrow_mut::(); + resources.borrow::>(); + resources.borrow::(); + resources.borrow::(); } - fn release(resource_archetypes: &HashMap) { - resource_archetypes - .get(&TypeId::of::>()) - .unwrap() - .release_mut::>(); - resource_archetypes - .get(&TypeId::of::>()) - .unwrap() - .release_mut::>(); - resource_archetypes - .get(&TypeId::of::()) - .unwrap() - .release_mut::(); - resource_archetypes - .get(&TypeId::of::>()) - .unwrap() - .release::>(); - resource_archetypes - .get(&TypeId::of::()) - .unwrap() - .release::(); - resource_archetypes - .get(&TypeId::of::()) - .unwrap() - .release::(); + fn release(resources: &Resources) { + resources.release_mut::>(); + resources.release_mut::>(); + resources.release_mut::(); + resources.release::>(); + resources.release::(); + resources.release::(); } unsafe fn get(resources: &'a Resources, _system_id: Option) -> Self::Item { DrawContext { - pipelines: resources.get_res_mut::>(), - shaders: resources.get_res_mut::>(), - pipeline_compiler: resources.get_res_mut::(), - render_resource_context: resources.get_res::>(), - vertex_buffer_descriptors: resources.get_res::(), - shared_buffers: resources.get_res::(), + pipelines: ResMut::new( + resources.get_unsafe_ref::>(ResourceIndex::Global), + ), + shaders: ResMut::new(resources.get_unsafe_ref::>(ResourceIndex::Global)), + pipeline_compiler: ResMut::new( + resources.get_unsafe_ref::(ResourceIndex::Global), + ), + render_resource_context: Res::new( + resources.get_unsafe_ref::>(ResourceIndex::Global), + ), + vertex_buffer_descriptors: Res::new( + resources.get_unsafe_ref::(ResourceIndex::Global), + ), + shared_buffers: Res::new( + resources.get_unsafe_ref::(ResourceIndex::Global), + ), current_pipeline: None, } } 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 c00b32a24b..b35d24df1a 100644 --- a/crates/bevy_render/src/render_graph/nodes/pass_node.rs +++ b/crates/bevy_render/src/render_graph/nodes/pass_node.rs @@ -109,7 +109,7 @@ impl Node for PassNode { for (i, color_attachment) in self.descriptor.color_attachments.iter_mut().enumerate() { if self.default_clear_color_inputs.contains(&i) { - if let Ok(default_clear_color) = resources.get::() { + if let Some(default_clear_color) = resources.get::() { color_attachment.ops.load = LoadOp::Clear(default_clear_color.0); } } diff --git a/crates/bevy_winit/src/lib.rs b/crates/bevy_winit/src/lib.rs index 0ecfb8a2bb..7730fd80c8 100644 --- a/crates/bevy_winit/src/lib.rs +++ b/crates/bevy_winit/src/lib.rs @@ -52,7 +52,7 @@ pub fn winit_runner(mut app: App) { ControlFlow::Poll }; - if let Ok(app_exit_events) = app.resources.get_mut::>() { + if let Some(app_exit_events) = app.resources.get_mut::>() { if app_exit_event_reader.latest(&app_exit_events).is_some() { *control_flow = ControlFlow::Exit; }