draw ports; fix process callback

This commit is contained in:
🪞👃🪞 2024-06-22 20:05:48 +03:00
parent 72ead536be
commit 9e550a73ae
8 changed files with 268 additions and 175 deletions

View file

@ -19,6 +19,11 @@ pub use self::plugin::Plugin;
pub use self::launcher::Launcher;
use crossterm::event;
use ::jack::{AudioIn, AudioOut, MidiIn, MidiOut, Port, PortSpec, Client};
pub trait Device: Render + Handle + DevicePorts + Send + Sync {}
impl<T: Render + Handle + DevicePorts + Send + Sync> Device for T {}
pub trait Handle {
// Returns Ok(true) if the device handled the event.
@ -36,15 +41,59 @@ pub trait Render {
}
}
pub trait DevicePorts {
fn audio_ins (&self) -> Usually<Vec<String>> {
Ok(vec![])
}
fn audio_outs (&self) -> Usually<Vec<String>> {
Ok(vec![])
}
fn midi_ins (&self) -> Usually<Vec<String>> {
Ok(vec![])
}
fn midi_outs (&self) -> Usually<Vec<String>> {
Ok(vec![])
}
fn connect (&mut self, connect: bool, source: &str, target: &str)
-> Usually<()>
{
Ok(())
}
fn connect_all (&mut self, connections: &[(bool, &str, &str)])
-> Usually<()>
{
for (connect, source, target) in connections.iter() {
self.connect(*connect, source, target)?;
}
Ok(())
}
}
impl Render for Box<dyn Device> {
fn render (&self, b: &mut Buffer, a: Rect) -> Usually<Rect> {
(**self).render(b, a)
}
}
pub trait Device: Render + Handle + Send + Sync {}
pub struct DevicePort<T: PortSpec> {
pub name: String,
pub port: Port<T>,
pub connect: Vec<String>,
}
impl<T: Render + Handle + Send + Sync> Device for T {}
impl<T: PortSpec + Default> DevicePort<T> {
pub fn new (client: &Client, name: &str, connect: &[&str]) -> Usually<Self> {
let mut connects = vec![];
for port in connect.iter() {
connects.push(port.to_string());
}
Ok(Self {
name: name.to_string(),
port: client.register_port(name, T::default())?,
connect: connects,
})
}
}
impl WidgetRef for &dyn Render {
fn render_ref (&self, area: Rect, buf: &mut Buffer) {
@ -147,6 +196,21 @@ impl<T> Render for DynamicDevice<T> {
}
}
impl<T: DevicePorts + Send + Sync + 'static> DevicePorts for DynamicDevice<T> {
fn audio_ins (&self) -> Usually<Vec<String>> {
self.state().audio_ins()
}
fn audio_outs (&self) -> Usually<Vec<String>> {
self.state().audio_outs()
}
fn midi_ins (&self) -> Usually<Vec<String>> {
self.state().midi_ins()
}
fn midi_outs (&self) -> Usually<Vec<String>> {
self.state().midi_outs()
}
}
type DynamicAsyncClient = AsyncClient<DynamicNotifications, DynamicProcessHandler>;
type DynamicNotifications = Notifications<Box<dyn Fn(AppEvent) + Send + Sync>>;
type DynamicProcessHandler = ClosureProcessHandler<BoxedProcessHandler>;