simplify AssetStorage and Handles

This commit is contained in:
Carter Anderson 2020-01-11 12:32:38 -08:00
parent 41722830bd
commit 4d903df33c
11 changed files with 52 additions and 98 deletions

View file

@ -43,9 +43,9 @@ fn setup(world: &mut World) {
let cube_handle = {
let mut mesh_storage = world
.resources
.get_mut::<AssetStorage<Mesh, MeshType>>()
.get_mut::<AssetStorage<Mesh>>()
.unwrap();
mesh_storage.add(cube, "cube")
mesh_storage.add(cube)
};
world.insert(

View file

@ -33,11 +33,11 @@ fn setup(world: &mut World) {
let (cube_handle, plane_handle) = {
let mut mesh_storage = world
.resources
.get_mut::<AssetStorage<Mesh, MeshType>>()
.get_mut::<AssetStorage<Mesh>>()
.unwrap();
(
mesh_storage.add(cube, "cube"),
mesh_storage.add(plane, "plane"),
mesh_storage.add(cube),
mesh_storage.add(plane),
)
};

View file

@ -16,11 +16,11 @@ fn setup(world: &mut World) {
let (cube_handle, plane_handle) = {
let mut mesh_storage = world
.resources
.get_mut::<AssetStorage<Mesh, MeshType>>()
.get_mut::<AssetStorage<Mesh>>()
.unwrap();
(
mesh_storage.add(cube, "cube"),
mesh_storage.add(plane, "plane"),
mesh_storage.add(cube),
mesh_storage.add(plane),
)
};

View file

@ -14,9 +14,9 @@ fn setup(world: &mut World) {
let cube_handle = {
let mut mesh_storage = world
.resources
.get_mut::<AssetStorage<Mesh, MeshType>>()
.get_mut::<AssetStorage<Mesh>>()
.unwrap();
mesh_storage.add(cube, "cube")
mesh_storage.add(cube)
};
world.insert(

View file

@ -77,7 +77,7 @@ impl AppBuilder {
pub fn add_default_resources(mut self) -> Self {
let resources = &mut self.world.resources;
resources.insert(Time::new());
resources.insert(AssetStorage::<Mesh, MeshType>::new());
resources.insert(AssetStorage::<Mesh>::new());
self
}

View file

@ -2,113 +2,67 @@ mod gltf;
pub use self::gltf::load_gltf;
use std::{
collections::HashMap,
marker::PhantomData,
ops::Drop,
sync::{Arc, RwLock},
};
use std::{collections::HashMap, marker::PhantomData};
pub struct Handle<T> {
pub id: Arc<RwLock<usize>>,
pub id: usize,
marker: PhantomData<T>,
free_indices: Arc<RwLock<Vec<usize>>>,
}
impl<T> Clone for Handle<T> {
fn clone(&self) -> Self {
Handle {
id: self.id.clone(),
free_indices: self.free_indices.clone(),
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> {
fn load(descriptor: D) -> Self;
}
pub struct AssetStorage<T, D>
where
T: Asset<D>,
pub struct AssetStorage<T>
{
assets: Vec<Option<T>>,
free_indices: Arc<RwLock<Vec<usize>>>,
names: HashMap<String, Arc<RwLock<usize>>>,
marker: PhantomData<D>,
assets: HashMap<usize, T>,
names: HashMap<String, usize>,
current_index: usize,
}
impl<T, D> AssetStorage<T, D>
where
T: Asset<D>,
impl<T> AssetStorage<T>
{
pub fn new() -> AssetStorage<T, D> {
pub fn new() -> AssetStorage<T> {
AssetStorage {
assets: Vec::new(),
free_indices: Arc::new(RwLock::new(Vec::new())),
assets: 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) {
Some(id) => Some(Handle {
id: id.clone(),
marker: PhantomData,
free_indices: self.free_indices.clone(),
}),
Some(id) => self.assets.get_mut(id),
None => None,
}
}
pub fn add(&mut self, asset: T, name: &str) -> Handle<T> {
match self.free_indices.write().unwrap().pop() {
Some(id) => {
self.assets[id as usize] = Some(asset);
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(),
}
}
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(&mut self, asset: T) -> Handle<T> {
let id = self.current_index;
self.current_index += 1;
self.assets.insert(id, asset);
Handle {
id,
marker: PhantomData,
}
}
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> {
if id >= self.assets.len() {
None
} else {
if let Some(ref mut asset) = self.assets[id] {
Some(asset)
} else {
None
}
}
self.assets.get_mut(&id)
}
}

View file

@ -137,13 +137,13 @@ impl Pipeline for ForwardPipeline {
let mut mesh_storage = world
.resources
.get_mut::<AssetStorage<Mesh, MeshType>>()
.get_mut::<AssetStorage<Mesh>>()
.unwrap();
let mut last_mesh_id = None;
let mesh_query =
<(Read<Material>, Read<Handle<Mesh>>)>::query().filter(!component::<Instanced>());
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;
if let Some(last) = last_mesh_id {
@ -151,14 +151,14 @@ impl Pipeline for ForwardPipeline {
}
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);
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)]);
};
}
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.draw_indexed(0..mesh_asset.indices.len() as u32, 0, 0..1);
};

View file

@ -52,7 +52,7 @@ impl ForwardInstancedPipeline {
.iter(world)
.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();
slot.copy_from_slice(
SimpleMaterialUniforms {
@ -89,7 +89,7 @@ impl ForwardInstancedPipeline {
let mut last_mesh_id = None;
let mut data = Vec::with_capacity(entities_count);
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();
data.push(SimpleMaterialUniforms {
@ -263,7 +263,7 @@ impl Pipeline for ForwardInstancedPipeline {
let mut mesh_storage = world
.resources
.get_mut::<AssetStorage<Mesh, MeshType>>()
.get_mut::<AssetStorage<Mesh>>()
.unwrap();
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) {

View file

@ -171,10 +171,10 @@ impl Pipeline for ForwardShadowPassNew {
let mut mesh_storage = world
.resources
.get_mut::<AssetStorage<Mesh, MeshType>>()
.get_mut::<AssetStorage<Mesh>>()
.unwrap();
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);
pass.set_bind_group(1, material.bind_group.as_ref().unwrap(), &[]);
pass.set_index_buffer(mesh_asset.index_buffer.as_ref().unwrap(), 0);

View file

@ -159,10 +159,10 @@ impl Pipeline for ShadowPipeline {
let mut mesh_storage = world
.resources
.get_mut::<AssetStorage<Mesh, MeshType>>()
.get_mut::<AssetStorage<Mesh>>()
.unwrap();
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);
pass.set_bind_group(1, material.bind_group.as_ref().unwrap(), &[]);

View file

@ -65,7 +65,7 @@ impl UiPipeline {
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();
instance_buffer_infos.push(InstanceBufferInfo {
@ -114,7 +114,7 @@ impl Pipeline for UiPipeline {
{
let mut mesh_storage = world
.resources
.get_mut::<AssetStorage<Mesh, MeshType>>()
.get_mut::<AssetStorage<Mesh>>()
.unwrap();
let quad = Mesh::load(MeshType::Quad {
@ -123,7 +123,7 @@ impl Pipeline for UiPipeline {
south_west: 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 =
@ -220,7 +220,7 @@ impl Pipeline for UiPipeline {
let mut mesh_storage = world
.resources
.get_mut::<AssetStorage<Mesh, MeshType>>()
.get_mut::<AssetStorage<Mesh>>()
.unwrap();
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) {