Remove material_manager and resource
(Not used)
This commit is contained in:
parent
0174aeb60e
commit
883014998f
4 changed files with 0 additions and 456 deletions
|
@ -1,246 +0,0 @@
|
||||||
use std::{
|
|
||||||
any::TypeId,
|
|
||||||
error::Error,
|
|
||||||
sync::{Arc, RwLock, RwLockReadGuard},
|
|
||||||
};
|
|
||||||
|
|
||||||
use vulkano::{device::Device, format::Format, memory::allocator::StandardMemoryAllocator};
|
|
||||||
|
|
||||||
pub trait Pipeline {
|
|
||||||
fn load(
|
|
||||||
&mut self,
|
|
||||||
device: &Device,
|
|
||||||
memory_allocator: &StandardMemoryAllocator,
|
|
||||||
swapchain_format: Format,
|
|
||||||
depth_format: Format,
|
|
||||||
) -> Result<(), Box<dyn Error>>;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait Material {
|
|
||||||
fn pipeline_type_id() -> TypeId
|
|
||||||
where
|
|
||||||
Self: Sized;
|
|
||||||
|
|
||||||
fn load(
|
|
||||||
&mut self,
|
|
||||||
device: &Device,
|
|
||||||
memory_allocator: &StandardMemoryAllocator,
|
|
||||||
) -> Result<(), Box<dyn Error>>;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub enum MaterialState {
|
|
||||||
Loading,
|
|
||||||
Loaded,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub enum MaterialError {
|
|
||||||
PipelineNotFound,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct MaterialManager {
|
|
||||||
device: Arc<Device>,
|
|
||||||
memory_allocator: Arc<StandardMemoryAllocator>,
|
|
||||||
swapchain_format: Format,
|
|
||||||
depth_format: Format,
|
|
||||||
|
|
||||||
pipelines_id: Arc<RwLock<Vec<TypeId>>>,
|
|
||||||
pipelines_state: Arc<RwLock<Vec<Arc<RwLock<MaterialState>>>>>,
|
|
||||||
pipelines: Arc<RwLock<Vec<Arc<RwLock<dyn Pipeline>>>>>,
|
|
||||||
|
|
||||||
materials_id: Arc<RwLock<Vec<TypeId>>>,
|
|
||||||
materials_pipeline_id: Arc<RwLock<Vec<TypeId>>>,
|
|
||||||
materials_pipeline: Arc<RwLock<Vec<Arc<RwLock<dyn Pipeline>>>>>,
|
|
||||||
materials_pipeline_state: Arc<RwLock<Vec<Arc<RwLock<MaterialState>>>>>,
|
|
||||||
materials_state: Arc<RwLock<Vec<Arc<RwLock<MaterialState>>>>>,
|
|
||||||
materials: Arc<RwLock<Vec<Arc<RwLock<dyn Material>>>>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl MaterialManager {
|
|
||||||
pub fn new(
|
|
||||||
device: Arc<Device>,
|
|
||||||
memory_allocator: Arc<StandardMemoryAllocator>,
|
|
||||||
swapchain_format: Format,
|
|
||||||
depth_format: Format,
|
|
||||||
) -> Self {
|
|
||||||
Self {
|
|
||||||
device,
|
|
||||||
memory_allocator,
|
|
||||||
swapchain_format,
|
|
||||||
depth_format,
|
|
||||||
pipelines_id: Arc::new(RwLock::new(Vec::new())),
|
|
||||||
pipelines_state: Arc::new(RwLock::new(Vec::new())),
|
|
||||||
pipelines: Arc::new(RwLock::new(Vec::new())),
|
|
||||||
materials_id: Arc::new(RwLock::new(Vec::new())),
|
|
||||||
materials_pipeline_id: Arc::new(RwLock::new(Vec::new())),
|
|
||||||
materials_pipeline: Arc::new(RwLock::new(Vec::new())),
|
|
||||||
materials_pipeline_state: Arc::new(RwLock::new(Vec::new())),
|
|
||||||
materials_state: Arc::new(RwLock::new(Vec::new())),
|
|
||||||
materials: Arc::new(RwLock::new(Vec::new())),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn add_pipeline<P: Pipeline + Default + 'static>(&self) {
|
|
||||||
let type_id = TypeId::of::<P>();
|
|
||||||
let pipeline = Arc::new(RwLock::new(P::default()));
|
|
||||||
|
|
||||||
let mut pipelines_id = self.pipelines_id.write().unwrap();
|
|
||||||
let mut pipelines_state = self.pipelines_state.write().unwrap();
|
|
||||||
let mut pipelines = self.pipelines.write().unwrap();
|
|
||||||
|
|
||||||
pipelines_id.push(type_id);
|
|
||||||
pipelines_state.push(Arc::new(RwLock::new(MaterialState::Loading)));
|
|
||||||
pipelines.push(pipeline.clone());
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn add_material<M: Material + Default + 'static>(&self) -> Result<(), MaterialError> {
|
|
||||||
let pipeline_id = M::pipeline_type_id();
|
|
||||||
|
|
||||||
let pipeline_result = {
|
|
||||||
let pipelines_id = self.pipelines_id.read().unwrap();
|
|
||||||
let pipelines_state = self.pipelines_state.read().unwrap();
|
|
||||||
let pipelines = self.pipelines.read().unwrap();
|
|
||||||
|
|
||||||
pipelines_id
|
|
||||||
.iter()
|
|
||||||
.zip(pipelines.iter())
|
|
||||||
.zip(pipelines_state.iter())
|
|
||||||
.find(|((id, _), _)| *id == &pipeline_id)
|
|
||||||
.map(|((_, pipeline), state)| (pipeline.clone(), state.clone()))
|
|
||||||
};
|
|
||||||
|
|
||||||
let (pipeline, pipeline_state) = match pipeline_result {
|
|
||||||
Some(pipeline) => pipeline,
|
|
||||||
None => {
|
|
||||||
tracing::error!(
|
|
||||||
"Pipeline with id {pipeline_id:?} not found, please add it before adding a material"
|
|
||||||
);
|
|
||||||
return Err(MaterialError::PipelineNotFound);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let type_id = TypeId::of::<M>();
|
|
||||||
|
|
||||||
let mut materials_id = self.materials_id.write().unwrap();
|
|
||||||
let mut materials_pipeline_id = self.materials_pipeline_id.write().unwrap();
|
|
||||||
let mut materials_pipeline = self.materials_pipeline.write().unwrap();
|
|
||||||
let mut materials_pipeline_state = self.materials_pipeline_state.write().unwrap();
|
|
||||||
let mut materials_state = self.materials_state.write().unwrap();
|
|
||||||
let mut materials = self.materials.write().unwrap();
|
|
||||||
|
|
||||||
materials_id.push(type_id);
|
|
||||||
materials_pipeline_id.push(pipeline_id);
|
|
||||||
materials_pipeline.push(pipeline);
|
|
||||||
materials_pipeline_state.push(pipeline_state);
|
|
||||||
materials_state.push(Arc::new(RwLock::new(MaterialState::Loading)));
|
|
||||||
materials.push(Arc::new(RwLock::new(M::default())));
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn update_swapchain_format(&mut self, swapchain_format: Format) {
|
|
||||||
if self.swapchain_format == swapchain_format {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.swapchain_format = swapchain_format;
|
|
||||||
self.mark_all_pipelines_as_loading();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn mark_all_pipelines_as_loading(&self) {
|
|
||||||
let pipelines_state = self.pipelines_state.write().unwrap();
|
|
||||||
|
|
||||||
for state in pipelines_state.iter() {
|
|
||||||
let mut state = state.write().unwrap();
|
|
||||||
*state = MaterialState::Loading;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn load_pipelines(&self) {
|
|
||||||
let pipelines_state = self.pipelines_state.read().unwrap();
|
|
||||||
let pipelines = self.pipelines.read().unwrap();
|
|
||||||
|
|
||||||
let iter = pipelines_state
|
|
||||||
.iter()
|
|
||||||
.zip(pipelines.iter())
|
|
||||||
.filter(|(state, _)| {
|
|
||||||
let state = state.read().unwrap();
|
|
||||||
matches!(*state, MaterialState::Loading)
|
|
||||||
});
|
|
||||||
|
|
||||||
for (state, pipeline) in iter {
|
|
||||||
let mut pipeline = pipeline.write().unwrap();
|
|
||||||
let result = pipeline.load(
|
|
||||||
&self.device,
|
|
||||||
&self.memory_allocator,
|
|
||||||
self.swapchain_format,
|
|
||||||
self.depth_format,
|
|
||||||
);
|
|
||||||
|
|
||||||
match result {
|
|
||||||
Ok(_) => {
|
|
||||||
let mut state = state.write().unwrap();
|
|
||||||
*state = MaterialState::Loaded;
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
tracing::error!("Failed to load pipeline: {e}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn load_materials(&self) {
|
|
||||||
let materials_state = self.materials_state.read().unwrap();
|
|
||||||
let materials = self.materials.read().unwrap();
|
|
||||||
|
|
||||||
let iter = materials_state
|
|
||||||
.iter()
|
|
||||||
.zip(materials.iter())
|
|
||||||
.filter(|(state, _)| {
|
|
||||||
let state = state.read().unwrap();
|
|
||||||
matches!(*state, MaterialState::Loading)
|
|
||||||
});
|
|
||||||
|
|
||||||
for (state, material) in iter {
|
|
||||||
let mut material = material.write().unwrap();
|
|
||||||
let result = material.load(&self.device, &self.memory_allocator);
|
|
||||||
|
|
||||||
match result {
|
|
||||||
Ok(_) => {
|
|
||||||
let mut state = state.write().unwrap();
|
|
||||||
*state = MaterialState::Loaded;
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
tracing::error!("Failed to load material: {e}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn render_materials<F>(&self, f: F)
|
|
||||||
where
|
|
||||||
F: Fn(RwLockReadGuard<'_, dyn Material>, RwLockReadGuard<'_, dyn Pipeline>),
|
|
||||||
{
|
|
||||||
let materials = self.materials.read().unwrap();
|
|
||||||
let materials_state = self.materials_state.read().unwrap();
|
|
||||||
let materials_pipeline = self.materials_pipeline.read().unwrap();
|
|
||||||
let materials_pipeline_state = self.materials_pipeline_state.read().unwrap();
|
|
||||||
|
|
||||||
materials
|
|
||||||
.iter()
|
|
||||||
.zip(materials_state.iter())
|
|
||||||
.zip(materials_pipeline.iter())
|
|
||||||
.zip(materials_pipeline_state.iter())
|
|
||||||
.filter(|(((_, material_state), _), pipeline_state)| {
|
|
||||||
let material_state = material_state.read().unwrap();
|
|
||||||
let pipeline_state = pipeline_state.read().unwrap();
|
|
||||||
matches!(*material_state, MaterialState::Loaded)
|
|
||||||
&& matches!(*pipeline_state, MaterialState::Loaded)
|
|
||||||
})
|
|
||||||
.for_each(|(((material, _), pipeline), _)| {
|
|
||||||
let material = material.read().unwrap();
|
|
||||||
let pipeline = pipeline.read().unwrap();
|
|
||||||
|
|
||||||
f(material, pipeline);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,4 +1,3 @@
|
||||||
pub mod material_manager;
|
|
||||||
pub mod primitives;
|
pub mod primitives;
|
||||||
pub mod render_pass_manager;
|
pub mod render_pass_manager;
|
||||||
pub mod resources;
|
pub mod resources;
|
||||||
|
|
|
@ -4,7 +4,6 @@ mod descriptor_set;
|
||||||
|
|
||||||
pub mod camera;
|
pub mod camera;
|
||||||
pub mod mvp;
|
pub mod mvp;
|
||||||
pub mod resource;
|
|
||||||
pub mod transform;
|
pub mod transform;
|
||||||
pub mod vertex;
|
pub mod vertex;
|
||||||
pub use buffer::{AsBindableBuffer, AsIndexBuffer, AsUniformBuffer, AsVertexBuffer};
|
pub use buffer::{AsBindableBuffer, AsIndexBuffer, AsUniformBuffer, AsVertexBuffer};
|
||||||
|
|
|
@ -1,208 +0,0 @@
|
||||||
use std::{
|
|
||||||
collections::HashMap,
|
|
||||||
error::Error,
|
|
||||||
fmt::{self, Debug, Display},
|
|
||||||
hash::Hash,
|
|
||||||
sync::Arc,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct ResourceLoadError {
|
|
||||||
pub message: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Display for ResourceLoadError {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
write!(f, "Resource load error: {}", self.message)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Error for ResourceLoadError {}
|
|
||||||
|
|
||||||
impl ResourceLoadError {
|
|
||||||
pub fn new(message: impl Into<String>) -> Self {
|
|
||||||
Self {
|
|
||||||
message: message.into(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait AsResourceManager<THandle, TResource>
|
|
||||||
where
|
|
||||||
THandle: Clone + Eq + Hash + Debug,
|
|
||||||
{
|
|
||||||
/// Type d'erreur lors du chargement
|
|
||||||
type LoadError: Error;
|
|
||||||
|
|
||||||
/// Charge une ressource avec l'handle donné
|
|
||||||
fn load(&mut self, handle: THandle, resource: TResource) -> Result<(), Self::LoadError>;
|
|
||||||
|
|
||||||
/// Récupère une ressource par son handle
|
|
||||||
fn get(&self, handle: &THandle) -> Option<&TResource>;
|
|
||||||
|
|
||||||
/// Récupère une ressource mutable par son handle
|
|
||||||
fn get_mut(&mut self, handle: &THandle) -> Option<&mut TResource>;
|
|
||||||
|
|
||||||
/// Supprime une ressource
|
|
||||||
fn unload(&mut self, handle: &THandle) -> Option<TResource>;
|
|
||||||
|
|
||||||
/// Vérifie si une ressource est chargée
|
|
||||||
fn is_loaded(&self, handle: &THandle) -> bool;
|
|
||||||
|
|
||||||
/// Retourne tous les handles chargés
|
|
||||||
fn loaded_handles(&self) -> Vec<THandle>;
|
|
||||||
|
|
||||||
/// Nettoie toutes les ressources
|
|
||||||
fn clear(&mut self);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Implémentation basique d'un gestionnaire de ressources
|
|
||||||
pub struct BasicResourceManager<THandle, TResource>
|
|
||||||
where
|
|
||||||
THandle: Clone + Eq + Hash + Debug,
|
|
||||||
{
|
|
||||||
resources: HashMap<THandle, TResource>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<THandle, TResource> BasicResourceManager<THandle, TResource>
|
|
||||||
where
|
|
||||||
THandle: Clone + Eq + Hash + Debug,
|
|
||||||
{
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
resources: HashMap::new(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn with_capacity(capacity: usize) -> Self {
|
|
||||||
Self {
|
|
||||||
resources: HashMap::with_capacity(capacity),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<THandle, TResource> Default for BasicResourceManager<THandle, TResource>
|
|
||||||
where
|
|
||||||
THandle: Clone + Eq + Hash + Debug,
|
|
||||||
{
|
|
||||||
fn default() -> Self {
|
|
||||||
Self::new()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<THandle, TResource> AsResourceManager<THandle, TResource>
|
|
||||||
for BasicResourceManager<THandle, TResource>
|
|
||||||
where
|
|
||||||
THandle: Clone + Eq + Hash + Debug,
|
|
||||||
{
|
|
||||||
type LoadError = ResourceLoadError;
|
|
||||||
|
|
||||||
fn load(&mut self, handle: THandle, resource: TResource) -> Result<(), Self::LoadError> {
|
|
||||||
self.resources.insert(handle, resource);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get(&self, handle: &THandle) -> Option<&TResource> {
|
|
||||||
self.resources.get(handle)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_mut(&mut self, handle: &THandle) -> Option<&mut TResource> {
|
|
||||||
self.resources.get_mut(handle)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn unload(&mut self, handle: &THandle) -> Option<TResource> {
|
|
||||||
self.resources.remove(handle)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_loaded(&self, handle: &THandle) -> bool {
|
|
||||||
self.resources.contains_key(handle)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn loaded_handles(&self) -> Vec<THandle> {
|
|
||||||
self.resources.keys().cloned().collect()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn clear(&mut self) {
|
|
||||||
self.resources.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct ThreadSafeResourceManager<THandle, TResource>
|
|
||||||
where
|
|
||||||
THandle: Clone + Eq + Hash + Debug,
|
|
||||||
{
|
|
||||||
resources: Arc<std::sync::RwLock<HashMap<THandle, Arc<TResource>>>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<THandle, TResource> ThreadSafeResourceManager<THandle, TResource>
|
|
||||||
where
|
|
||||||
THandle: Clone + Eq + Hash + Debug,
|
|
||||||
{
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
resources: Arc::new(std::sync::RwLock::new(HashMap::new())),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn load(&self, handle: THandle, resource: TResource) -> Result<(), ResourceLoadError> {
|
|
||||||
let mut resources = self
|
|
||||||
.resources
|
|
||||||
.write()
|
|
||||||
.map_err(|_| ResourceLoadError::new("Failed to acquire write lock"))?;
|
|
||||||
resources.insert(handle, Arc::new(resource));
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get(&self, handle: &THandle) -> Option<Arc<TResource>> {
|
|
||||||
let resources = self.resources.read().ok()?;
|
|
||||||
resources.get(handle).cloned()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn unload(&self, handle: &THandle) -> Option<Arc<TResource>> {
|
|
||||||
let mut resources = self.resources.write().ok()?;
|
|
||||||
resources.remove(handle)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn is_loaded(&self, handle: &THandle) -> bool {
|
|
||||||
if let Ok(resources) = self.resources.read() {
|
|
||||||
resources.contains_key(handle)
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn loaded_handles(&self) -> Vec<THandle> {
|
|
||||||
if let Ok(resources) = self.resources.read() {
|
|
||||||
resources.keys().cloned().collect()
|
|
||||||
} else {
|
|
||||||
Vec::new()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn clear(&self) {
|
|
||||||
if let Ok(mut resources) = self.resources.write() {
|
|
||||||
resources.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<THandle, TResource> Clone for ThreadSafeResourceManager<THandle, TResource>
|
|
||||||
where
|
|
||||||
THandle: Clone + Eq + Hash + Debug,
|
|
||||||
{
|
|
||||||
fn clone(&self) -> Self {
|
|
||||||
Self {
|
|
||||||
resources: Arc::clone(&self.resources),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait AsAsyncLoadable<THandle>
|
|
||||||
where
|
|
||||||
THandle: Clone + Eq + Hash + Debug + Send + Sync,
|
|
||||||
{
|
|
||||||
type Resource: Send + Sync;
|
|
||||||
type LoadError: Error + Send + Sync;
|
|
||||||
|
|
||||||
async fn load_async(handle: THandle) -> Result<Self::Resource, Self::LoadError>;
|
|
||||||
}
|
|
Loading…
Add table
Add a link
Reference in a new issue