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