use std::collections::HashMap;
use std::sync::Arc;
use super::effect::MaskedFilterPipeline;
pub struct FilterPipelineRegistration {
pub type_id: &'static str,
pub display_name: &'static str,
pub create_pipeline: fn(&wgpu::Device) -> MaskedFilterPipeline,
}
pub struct FilterPipelineRegistry {
entries: HashMap<&'static str, RegistryEntry>,
}
struct RegistryEntry {
display_name: &'static str,
create_pipeline: fn(&wgpu::Device) -> MaskedFilterPipeline,
cached_pipeline: Option<Arc<MaskedFilterPipeline>>,
}
impl Default for FilterPipelineRegistry {
fn default() -> Self {
Self::new()
}
}
impl FilterPipelineRegistry {
pub fn new() -> Self {
let mut entries = HashMap::new();
for reg in super::filters::registrations() {
entries.insert(
reg.type_id,
RegistryEntry {
display_name: reg.display_name,
create_pipeline: reg.create_pipeline,
cached_pipeline: None,
},
);
}
FilterPipelineRegistry { entries }
}
pub fn types(&self) -> Vec<(&'static str, &'static str)> {
let mut types: Vec<_> = self
.entries
.iter()
.map(|(&id, e)| (id, e.display_name))
.collect();
types.sort_by_key(|(id, _)| *id);
types
}
pub fn has(&self, type_id: &str) -> bool {
self.entries.contains_key(type_id)
}
pub fn display_name(&self, type_id: &str) -> &'static str {
self.entries
.get(type_id)
.map(|e| e.display_name)
.unwrap_or("")
}
pub fn pipeline(
&mut self,
type_id: &str,
device: &wgpu::Device,
) -> Option<Arc<MaskedFilterPipeline>> {
let entry = self.entries.get_mut(type_id)?;
Some(
entry
.cached_pipeline
.get_or_insert_with(|| Arc::new((entry.create_pipeline)(device)))
.clone(),
)
}
}