use std::collections::HashMap;
use aether_core::node::DspNode;
use crate::ParamDef;
pub type NodeFactory = fn() -> Box<dyn DspNode>;
#[derive(Clone)]
pub struct NodeEntry {
pub type_name: &'static str,
pub param_defs: &'static [ParamDef],
pub factory: NodeFactory,
}
pub struct NodeRegistry {
entries: HashMap<&'static str, NodeEntry>,
}
impl NodeRegistry {
pub fn new() -> Self {
Self { entries: HashMap::new() }
}
pub fn register(&mut self, entry: NodeEntry) {
self.entries.insert(entry.type_name, entry);
}
pub fn create(&self, type_name: &str) -> Option<Box<dyn DspNode>> {
self.entries.get(type_name).map(|e| (e.factory)())
}
pub fn list(&self) -> Vec<&'static str> {
let mut names: Vec<_> = self.entries.keys().copied().collect();
names.sort_unstable();
names
}
pub fn param_defs(&self, type_name: &str) -> Option<&[ParamDef]> {
self.entries.get(type_name).map(|e| e.param_defs)
}
pub fn len(&self) -> usize { self.entries.len() }
pub fn is_empty(&self) -> bool { self.entries.is_empty() }
}
impl Default for NodeRegistry {
fn default() -> Self { Self::new() }
}
#[macro_export]
macro_rules! register_node {
($registry:expr, $ty:ty) => {{
use $crate::{AetherNodeMeta, DspProcess, into_node};
$registry.register($crate::node::NodeEntry {
type_name: <$ty as AetherNodeMeta>::type_name(),
param_defs: <$ty as AetherNodeMeta>::param_defs(),
factory: || {
let node = <$ty as Default>::default();
into_node(node)
},
});
}};
}