pub mod chord;
pub mod effects;
pub mod note;
use crate::language::syntax::ast::nodes::Value;
use anyhow::Result;
use std::collections::HashMap;
#[derive(Debug, Clone)]
pub struct FunctionContext {
pub target: String,
pub state: HashMap<String, Value>,
pub start_time: f32,
pub duration: f32,
pub tempo: f32,
}
impl FunctionContext {
pub fn new(target: String, start_time: f32, tempo: f32) -> Self {
Self {
target,
state: HashMap::new(),
start_time,
duration: 0.0,
tempo,
}
}
pub fn set(&mut self, key: impl Into<String>, value: Value) {
self.state.insert(key.into(), value);
}
pub fn get(&self, key: &str) -> Option<&Value> {
self.state.get(key)
}
}
pub trait FunctionExecutor {
fn execute(&self, context: &mut FunctionContext, args: &[Value]) -> Result<()>;
fn name(&self) -> &str;
}
pub struct FunctionRegistry {
functions: HashMap<String, Box<dyn FunctionExecutor>>,
}
impl FunctionRegistry {
pub fn new() -> Self {
let mut registry = Self {
functions: HashMap::new(),
};
registry.register(Box::new(note::NoteFunction));
registry.register(Box::new(chord::ChordFunction));
registry.register(Box::new(effects::VelocityFunction));
registry.register(Box::new(effects::DurationFunction));
registry.register(Box::new(effects::PanFunction));
registry.register(Box::new(effects::DetuneFunction));
registry.register(Box::new(effects::SpreadFunction));
registry.register(Box::new(effects::GainFunction));
registry.register(Box::new(effects::AttackFunction));
registry.register(Box::new(effects::ReleaseFunction));
registry.register(Box::new(effects::DelayFunction));
registry.register(Box::new(effects::ReverbFunction));
registry.register(Box::new(effects::DriveFunction));
registry.register(Box::new(effects::ChorusFunction));
registry.register(Box::new(effects::FlangerFunction));
registry.register(Box::new(effects::PhaserFunction));
registry.register(Box::new(effects::CompressorFunction));
registry.register(Box::new(effects::DistortionFunction));
registry
}
pub fn register(&mut self, executor: Box<dyn FunctionExecutor>) {
self.functions.insert(executor.name().to_string(), executor);
}
pub fn execute(&self, name: &str, context: &mut FunctionContext, args: &[Value]) -> Result<()> {
if let Some(func) = self.functions.get(name) {
func.execute(context, args)
} else {
Err(anyhow::anyhow!("Unknown function: {}", name))
}
}
pub fn has(&self, name: &str) -> bool {
self.functions.contains_key(name)
}
}
impl Default for FunctionRegistry {
fn default() -> Self {
Self::new()
}
}