simplify AssetStorage and Handles
This commit is contained in:
		
							parent
							
								
									41722830bd
								
							
						
					
					
						commit
						4d903df33c
					
				| @ -43,9 +43,9 @@ fn setup(world: &mut World) { | |||||||
|     let cube_handle = { |     let cube_handle = { | ||||||
|         let mut mesh_storage = world |         let mut mesh_storage = world | ||||||
|             .resources |             .resources | ||||||
|             .get_mut::<AssetStorage<Mesh, MeshType>>() |             .get_mut::<AssetStorage<Mesh>>() | ||||||
|             .unwrap(); |             .unwrap(); | ||||||
|         mesh_storage.add(cube, "cube") |         mesh_storage.add(cube) | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     world.insert( |     world.insert( | ||||||
|  | |||||||
| @ -33,11 +33,11 @@ fn setup(world: &mut World) { | |||||||
|     let (cube_handle, plane_handle) = { |     let (cube_handle, plane_handle) = { | ||||||
|         let mut mesh_storage = world |         let mut mesh_storage = world | ||||||
|             .resources |             .resources | ||||||
|             .get_mut::<AssetStorage<Mesh, MeshType>>() |             .get_mut::<AssetStorage<Mesh>>() | ||||||
|             .unwrap(); |             .unwrap(); | ||||||
|         ( |         ( | ||||||
|             mesh_storage.add(cube, "cube"), |             mesh_storage.add(cube), | ||||||
|             mesh_storage.add(plane, "plane"), |             mesh_storage.add(plane), | ||||||
|         ) |         ) | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -16,11 +16,11 @@ fn setup(world: &mut World) { | |||||||
|     let (cube_handle, plane_handle) = { |     let (cube_handle, plane_handle) = { | ||||||
|         let mut mesh_storage = world |         let mut mesh_storage = world | ||||||
|             .resources |             .resources | ||||||
|             .get_mut::<AssetStorage<Mesh, MeshType>>() |             .get_mut::<AssetStorage<Mesh>>() | ||||||
|             .unwrap(); |             .unwrap(); | ||||||
|         ( |         ( | ||||||
|             mesh_storage.add(cube, "cube"), |             mesh_storage.add(cube), | ||||||
|             mesh_storage.add(plane, "plane"), |             mesh_storage.add(plane), | ||||||
|         ) |         ) | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -14,9 +14,9 @@ fn setup(world: &mut World) { | |||||||
|     let cube_handle = { |     let cube_handle = { | ||||||
|         let mut mesh_storage = world |         let mut mesh_storage = world | ||||||
|             .resources |             .resources | ||||||
|             .get_mut::<AssetStorage<Mesh, MeshType>>() |             .get_mut::<AssetStorage<Mesh>>() | ||||||
|             .unwrap(); |             .unwrap(); | ||||||
|         mesh_storage.add(cube, "cube") |         mesh_storage.add(cube) | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     world.insert( |     world.insert( | ||||||
|  | |||||||
| @ -77,7 +77,7 @@ impl AppBuilder { | |||||||
|     pub fn add_default_resources(mut self) -> Self { |     pub fn add_default_resources(mut self) -> Self { | ||||||
|         let resources = &mut self.world.resources; |         let resources = &mut self.world.resources; | ||||||
|         resources.insert(Time::new()); |         resources.insert(Time::new()); | ||||||
|         resources.insert(AssetStorage::<Mesh, MeshType>::new()); |         resources.insert(AssetStorage::<Mesh>::new()); | ||||||
|         self |         self | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -2,113 +2,67 @@ mod gltf; | |||||||
| 
 | 
 | ||||||
| pub use self::gltf::load_gltf; | pub use self::gltf::load_gltf; | ||||||
| 
 | 
 | ||||||
| use std::{ | use std::{collections::HashMap, marker::PhantomData}; | ||||||
|     collections::HashMap, |  | ||||||
|     marker::PhantomData, |  | ||||||
|     ops::Drop, |  | ||||||
|     sync::{Arc, RwLock}, |  | ||||||
| }; |  | ||||||
| 
 | 
 | ||||||
| pub struct Handle<T> { | pub struct Handle<T> { | ||||||
|     pub id: Arc<RwLock<usize>>, |     pub id: usize, | ||||||
|     marker: PhantomData<T>, |     marker: PhantomData<T>, | ||||||
|     free_indices: Arc<RwLock<Vec<usize>>>, |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl<T> Clone for Handle<T> { | impl<T> Clone for Handle<T> { | ||||||
|     fn clone(&self) -> Self { |     fn clone(&self) -> Self { | ||||||
|         Handle { |         Handle { | ||||||
|             id: self.id.clone(), |             id: self.id.clone(), | ||||||
|             free_indices: self.free_indices.clone(), |  | ||||||
|             marker: PhantomData, |             marker: PhantomData, | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl<T> Drop for Handle<T> { |  | ||||||
|     fn drop(&mut self) { |  | ||||||
|         // TODO: Maybe this should be 1
 |  | ||||||
|         // TODO: Is this even necessary?
 |  | ||||||
|         if Arc::strong_count(&self.id) == 0 { |  | ||||||
|             let id = *self.id.read().unwrap(); |  | ||||||
|             self.free_indices.write().unwrap().push(id); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| pub trait Asset<D> { | pub trait Asset<D> { | ||||||
|     fn load(descriptor: D) -> Self; |     fn load(descriptor: D) -> Self; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pub struct AssetStorage<T, D> | pub struct AssetStorage<T> | ||||||
| where |  | ||||||
|     T: Asset<D>, |  | ||||||
| { | { | ||||||
|     assets: Vec<Option<T>>, |     assets: HashMap<usize, T>, | ||||||
|     free_indices: Arc<RwLock<Vec<usize>>>, |     names: HashMap<String, usize>, | ||||||
|     names: HashMap<String, Arc<RwLock<usize>>>, |     current_index: usize, | ||||||
|     marker: PhantomData<D>, |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl<T, D> AssetStorage<T, D> | impl<T> AssetStorage<T> | ||||||
| where |  | ||||||
|     T: Asset<D>, |  | ||||||
| { | { | ||||||
|     pub fn new() -> AssetStorage<T, D> { |     pub fn new() -> AssetStorage<T> { | ||||||
|         AssetStorage { |         AssetStorage { | ||||||
|             assets: Vec::new(), |             assets: HashMap::new(), | ||||||
|             free_indices: Arc::new(RwLock::new(Vec::new())), |  | ||||||
|             names: HashMap::new(), |             names: HashMap::new(), | ||||||
|             marker: PhantomData, |             current_index: 0, | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     pub fn get_named(&self, name: &str) -> Option<Handle<T>> { |     pub fn get_named(&mut self, name: &str) -> Option<&mut T> { | ||||||
|         match self.names.get(name) { |         match self.names.get(name) { | ||||||
|             Some(id) => Some(Handle { |             Some(id) => self.assets.get_mut(id), | ||||||
|                 id: id.clone(), |  | ||||||
|                 marker: PhantomData, |  | ||||||
|                 free_indices: self.free_indices.clone(), |  | ||||||
|             }), |  | ||||||
|             None => None, |             None => None, | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     pub fn add(&mut self, asset: T, name: &str) -> Handle<T> { |     pub fn add(&mut self, asset: T) -> Handle<T> { | ||||||
|         match self.free_indices.write().unwrap().pop() { |         let id = self.current_index; | ||||||
|             Some(id) => { |         self.current_index += 1; | ||||||
|                 self.assets[id as usize] = Some(asset); |         self.assets.insert(id, asset); | ||||||
|                 let handle = Arc::new(RwLock::new(id)); |         Handle { | ||||||
|                 self.names.insert(name.to_string(), handle.clone()); |             id, | ||||||
|                 Handle { |             marker: PhantomData, | ||||||
|                     id: handle, |  | ||||||
|                     marker: PhantomData, |  | ||||||
|                     free_indices: self.free_indices.clone(), |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|             None => { |  | ||||||
|                 self.assets.push(Some(asset)); |  | ||||||
|                 let id = self.assets.len() - 1; |  | ||||||
|                 let handle = Arc::new(RwLock::new(id)); |  | ||||||
|                 self.names.insert(name.to_string(), handle.clone()); |  | ||||||
|                 Handle { |  | ||||||
|                     id: handle, |  | ||||||
|                     marker: PhantomData, |  | ||||||
|                     free_indices: self.free_indices.clone(), |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     pub fn add_named(&mut self, asset: T, name: &str) -> Handle<T> { | ||||||
|  |         let handle = self.add(asset); | ||||||
|  |         self.names.insert(name.to_string(), handle.id); | ||||||
|  |         handle | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     pub fn get(&mut self, id: usize) -> Option<&mut T> { |     pub fn get(&mut self, id: usize) -> Option<&mut T> { | ||||||
|         if id >= self.assets.len() { |         self.assets.get_mut(&id) | ||||||
|             None |  | ||||||
|         } else { |  | ||||||
|             if let Some(ref mut asset) = self.assets[id] { |  | ||||||
|                 Some(asset) |  | ||||||
|             } else { |  | ||||||
|                 None |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -137,13 +137,13 @@ impl Pipeline for ForwardPipeline { | |||||||
| 
 | 
 | ||||||
|         let mut mesh_storage = world |         let mut mesh_storage = world | ||||||
|             .resources |             .resources | ||||||
|             .get_mut::<AssetStorage<Mesh, MeshType>>() |             .get_mut::<AssetStorage<Mesh>>() | ||||||
|             .unwrap(); |             .unwrap(); | ||||||
|         let mut last_mesh_id = None; |         let mut last_mesh_id = None; | ||||||
|         let mesh_query = |         let mesh_query = | ||||||
|             <(Read<Material>, Read<Handle<Mesh>>)>::query().filter(!component::<Instanced>()); |             <(Read<Material>, Read<Handle<Mesh>>)>::query().filter(!component::<Instanced>()); | ||||||
|         for (material, mesh) in mesh_query.iter(world) { |         for (material, mesh) in mesh_query.iter(world) { | ||||||
|             let current_mesh_id = *mesh.id.read().unwrap(); |             let current_mesh_id = mesh.id; | ||||||
| 
 | 
 | ||||||
|             let mut should_load_mesh = last_mesh_id == None; |             let mut should_load_mesh = last_mesh_id == None; | ||||||
|             if let Some(last) = last_mesh_id { |             if let Some(last) = last_mesh_id { | ||||||
| @ -151,14 +151,14 @@ impl Pipeline for ForwardPipeline { | |||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             if should_load_mesh { |             if should_load_mesh { | ||||||
|                 if let Some(mesh_asset) = mesh_storage.get(*mesh.id.read().unwrap()) { |                 if let Some(mesh_asset) = mesh_storage.get(mesh.id) { | ||||||
|                     mesh_asset.setup_buffers(&render_graph.device); |                     mesh_asset.setup_buffers(&render_graph.device); | ||||||
|                     pass.set_index_buffer(mesh_asset.index_buffer.as_ref().unwrap(), 0); |                     pass.set_index_buffer(mesh_asset.index_buffer.as_ref().unwrap(), 0); | ||||||
|                     pass.set_vertex_buffers(0, &[(&mesh_asset.vertex_buffer.as_ref().unwrap(), 0)]); |                     pass.set_vertex_buffers(0, &[(&mesh_asset.vertex_buffer.as_ref().unwrap(), 0)]); | ||||||
|                 }; |                 }; | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             if let Some(ref mesh_asset) = mesh_storage.get(*mesh.id.read().unwrap()) { |             if let Some(ref mesh_asset) = mesh_storage.get(mesh.id) { | ||||||
|                 pass.set_bind_group(1, material.bind_group.as_ref().unwrap(), &[]); |                 pass.set_bind_group(1, material.bind_group.as_ref().unwrap(), &[]); | ||||||
|                 pass.draw_indexed(0..mesh_asset.indices.len() as u32, 0, 0..1); |                 pass.draw_indexed(0..mesh_asset.indices.len() as u32, 0, 0..1); | ||||||
|             }; |             }; | ||||||
|  | |||||||
| @ -52,7 +52,7 @@ impl ForwardInstancedPipeline { | |||||||
|             .iter(world) |             .iter(world) | ||||||
|             .zip(temp_buf_data.data.chunks_exact_mut(size)) |             .zip(temp_buf_data.data.chunks_exact_mut(size)) | ||||||
|         { |         { | ||||||
|             last_mesh_id = Some(*mesh.id.read().unwrap()); |             last_mesh_id = Some(mesh.id); | ||||||
|             let (_, _, translation) = transform.0.to_scale_rotation_translation(); |             let (_, _, translation) = transform.0.to_scale_rotation_translation(); | ||||||
|             slot.copy_from_slice( |             slot.copy_from_slice( | ||||||
|                 SimpleMaterialUniforms { |                 SimpleMaterialUniforms { | ||||||
| @ -89,7 +89,7 @@ impl ForwardInstancedPipeline { | |||||||
|         let mut last_mesh_id = None; |         let mut last_mesh_id = None; | ||||||
|         let mut data = Vec::with_capacity(entities_count); |         let mut data = Vec::with_capacity(entities_count); | ||||||
|         for (material, transform, mesh, _) in entities.iter(world) { |         for (material, transform, mesh, _) in entities.iter(world) { | ||||||
|             last_mesh_id = Some(*mesh.id.read().unwrap()); |             last_mesh_id = Some(mesh.id); | ||||||
|             let (_, _, translation) = transform.0.to_scale_rotation_translation(); |             let (_, _, translation) = transform.0.to_scale_rotation_translation(); | ||||||
| 
 | 
 | ||||||
|             data.push(SimpleMaterialUniforms { |             data.push(SimpleMaterialUniforms { | ||||||
| @ -263,7 +263,7 @@ impl Pipeline for ForwardInstancedPipeline { | |||||||
| 
 | 
 | ||||||
|         let mut mesh_storage = world |         let mut mesh_storage = world | ||||||
|             .resources |             .resources | ||||||
|             .get_mut::<AssetStorage<Mesh, MeshType>>() |             .get_mut::<AssetStorage<Mesh>>() | ||||||
|             .unwrap(); |             .unwrap(); | ||||||
|         for instance_buffer_info in self.instance_buffer_infos.as_ref().unwrap().iter() { |         for instance_buffer_info in self.instance_buffer_infos.as_ref().unwrap().iter() { | ||||||
|             if let Some(mesh_asset) = mesh_storage.get(instance_buffer_info.mesh_id) { |             if let Some(mesh_asset) = mesh_storage.get(instance_buffer_info.mesh_id) { | ||||||
|  | |||||||
| @ -171,10 +171,10 @@ impl Pipeline for ForwardShadowPassNew { | |||||||
| 
 | 
 | ||||||
|         let mut mesh_storage = world |         let mut mesh_storage = world | ||||||
|             .resources |             .resources | ||||||
|             .get_mut::<AssetStorage<Mesh, MeshType>>() |             .get_mut::<AssetStorage<Mesh>>() | ||||||
|             .unwrap(); |             .unwrap(); | ||||||
|         for (material, mesh) in mesh_query.iter(world) { |         for (material, mesh) in mesh_query.iter(world) { | ||||||
|             if let Some(mesh_asset) = mesh_storage.get(*mesh.id.read().unwrap()) { |             if let Some(mesh_asset) = mesh_storage.get(mesh.id) { | ||||||
|                 mesh_asset.setup_buffers(&render_graph.device); |                 mesh_asset.setup_buffers(&render_graph.device); | ||||||
|                 pass.set_bind_group(1, material.bind_group.as_ref().unwrap(), &[]); |                 pass.set_bind_group(1, material.bind_group.as_ref().unwrap(), &[]); | ||||||
|                 pass.set_index_buffer(mesh_asset.index_buffer.as_ref().unwrap(), 0); |                 pass.set_index_buffer(mesh_asset.index_buffer.as_ref().unwrap(), 0); | ||||||
|  | |||||||
| @ -159,10 +159,10 @@ impl Pipeline for ShadowPipeline { | |||||||
| 
 | 
 | ||||||
|         let mut mesh_storage = world |         let mut mesh_storage = world | ||||||
|             .resources |             .resources | ||||||
|             .get_mut::<AssetStorage<Mesh, MeshType>>() |             .get_mut::<AssetStorage<Mesh>>() | ||||||
|             .unwrap(); |             .unwrap(); | ||||||
|         for (material, mesh) in mesh_query.iter(world) { |         for (material, mesh) in mesh_query.iter(world) { | ||||||
|             if let Some(mesh_asset) = mesh_storage.get(*mesh.id.read().unwrap()) { |             if let Some(mesh_asset) = mesh_storage.get(mesh.id) { | ||||||
|                 mesh_asset.setup_buffers(&render_graph.device); |                 mesh_asset.setup_buffers(&render_graph.device); | ||||||
| 
 | 
 | ||||||
|                 pass.set_bind_group(1, material.bind_group.as_ref().unwrap(), &[]); |                 pass.set_bind_group(1, material.bind_group.as_ref().unwrap(), &[]); | ||||||
|  | |||||||
| @ -65,7 +65,7 @@ impl UiPipeline { | |||||||
|             wgpu::BufferUsage::COPY_SRC | wgpu::BufferUsage::VERTEX, |             wgpu::BufferUsage::COPY_SRC | wgpu::BufferUsage::VERTEX, | ||||||
|         ); |         ); | ||||||
| 
 | 
 | ||||||
|         let mesh_id = *self.quad.as_ref().unwrap().id.read().unwrap(); |         let mesh_id = self.quad.as_ref().unwrap().id; | ||||||
| 
 | 
 | ||||||
|         let mut instance_buffer_infos = Vec::new(); |         let mut instance_buffer_infos = Vec::new(); | ||||||
|         instance_buffer_infos.push(InstanceBufferInfo { |         instance_buffer_infos.push(InstanceBufferInfo { | ||||||
| @ -114,7 +114,7 @@ impl Pipeline for UiPipeline { | |||||||
|         { |         { | ||||||
|             let mut mesh_storage = world |             let mut mesh_storage = world | ||||||
|                 .resources |                 .resources | ||||||
|                 .get_mut::<AssetStorage<Mesh, MeshType>>() |                 .get_mut::<AssetStorage<Mesh>>() | ||||||
|                 .unwrap(); |                 .unwrap(); | ||||||
| 
 | 
 | ||||||
|             let quad = Mesh::load(MeshType::Quad { |             let quad = Mesh::load(MeshType::Quad { | ||||||
| @ -123,7 +123,7 @@ impl Pipeline for UiPipeline { | |||||||
|                 south_west: math::vec2(-0.5, -0.5), |                 south_west: math::vec2(-0.5, -0.5), | ||||||
|                 south_east: math::vec2(0.5, -0.5), |                 south_east: math::vec2(0.5, -0.5), | ||||||
|             }); |             }); | ||||||
|             self.quad = Some(mesh_storage.add(quad, "ui_quad")); |             self.quad = Some(mesh_storage.add(quad)); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         let pipeline_layout = |         let pipeline_layout = | ||||||
| @ -220,7 +220,7 @@ impl Pipeline for UiPipeline { | |||||||
| 
 | 
 | ||||||
|         let mut mesh_storage = world |         let mut mesh_storage = world | ||||||
|             .resources |             .resources | ||||||
|             .get_mut::<AssetStorage<Mesh, MeshType>>() |             .get_mut::<AssetStorage<Mesh>>() | ||||||
|             .unwrap(); |             .unwrap(); | ||||||
|         for instance_buffer_info in instance_buffer_infos.as_ref().unwrap().iter() { |         for instance_buffer_info in instance_buffer_infos.as_ref().unwrap().iter() { | ||||||
|             if let Some(mesh_asset) = mesh_storage.get(instance_buffer_info.mesh_id) { |             if let Some(mesh_asset) = mesh_storage.get(instance_buffer_info.mesh_id) { | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Carter Anderson
						Carter Anderson