use std::any;
use gfx;
use slog::Logger;
use froggy;
use super::Vertex;
use super::mesh::Mesh;
pub struct MeshWrapper {
mesh: Box<any::Any + Send + Sync + 'static>,
}
pub struct MeshRepository<R: gfx::Resources> {
log: Logger,
mesh_storage: froggy::Storage<MeshWrapper>,
default_output_color_buffer: gfx::handle::RenderTargetView<R, gfx::format::Srgba8>,
default_output_stencil_buffer: gfx::handle::DepthStencilView<R, gfx::format::DepthStencil>,
}
impl<R: gfx::Resources> MeshRepository<R> {
pub fn new(
default_output_color_buffer: gfx::handle::RenderTargetView<R, gfx::format::Srgba8>,
default_output_stencil_buffer: gfx::handle::DepthStencilView<R, gfx::format::DepthStencil>,
parent_log: &Logger,
) -> MeshRepository<R> {
MeshRepository {
mesh_storage: froggy::Storage::new(),
default_output_color_buffer: default_output_color_buffer,
default_output_stencil_buffer: default_output_stencil_buffer,
log: parent_log.new(o!()),
}
}
pub fn create<F: gfx::Factory<R>>(
&mut self,
factory: &mut F,
vertexes: Vec<Vertex>,
triangle_vertex_indexes: Vec<u32>,
) -> froggy::Pointer<MeshWrapper> {
let mesh = Mesh::new(
factory,
vertexes,
triangle_vertex_indexes,
self.default_output_color_buffer.clone(),
self.default_output_stencil_buffer.clone(),
);
self.add_mesh(mesh)
}
pub fn add_mesh(&mut self, mesh: Mesh<R>) -> froggy::Pointer<MeshWrapper> {
trace!(self.log, "Adding mesh");
self.mesh_storage.create(
MeshWrapper { mesh: Box::new(mesh) },
)
}
pub fn collect_garbage(&mut self) {
self.mesh_storage.sync_pending()
}
}
impl<'a, R: gfx::Resources> MeshRepository<R> {
pub fn get_mut(&'a mut self, mesh_pointer: &froggy::Pointer<MeshWrapper>) -> &'a mut Mesh<R> {
let mesh_wrapper = &mut self.mesh_storage[&mesh_pointer];
let any_mesh_with_extra_constraints = &mut *mesh_wrapper.mesh;
let any_mesh = any_mesh_with_extra_constraints as &mut any::Any;
any_mesh.downcast_mut::<Mesh<R>>().expect(
"Unless we're mixing graphics backends, this should be impossible.",
)
}
}