mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-08 04:36:45 +01:00
dynamic device activation
This commit is contained in:
parent
b73aa8a0dc
commit
e4f3942757
9 changed files with 484 additions and 587 deletions
165
src/device.rs
165
src/device.rs
|
|
@ -102,6 +102,7 @@ pub struct DynamicDevice<T> {
|
|||
pub render: Mutex<Box<dyn FnMut(&T, &mut Buffer, Rect)->Usually<Rect> + Send>>,
|
||||
pub handle: Arc<Mutex<Box<dyn FnMut(&mut T, &AppEvent)->Usually<()> + Send>>>,
|
||||
pub process: Arc<Mutex<Box<dyn FnMut(&mut T, &Client, &ProcessScope)->Control + Send>>>,
|
||||
client: Option<DynamicAsyncClient>
|
||||
}
|
||||
|
||||
impl<T: Send + Sync> Device for DynamicDevice<T> {
|
||||
|
|
@ -113,7 +114,11 @@ impl<T: Send + Sync> Device for DynamicDevice<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T> DynamicDevice<T> {
|
||||
type DynamicAsyncClient = AsyncClient<DynamicNotifications, DynamicProcessHandler>;
|
||||
type DynamicNotifications = Notifications<Box<dyn Fn(AppEvent) + Send + Sync>>;
|
||||
type DynamicProcessHandler = ClosureProcessHandler<BoxedProcessHandler>;
|
||||
|
||||
impl<T: Send + Sync + 'static> DynamicDevice<T> {
|
||||
fn new <'a, R, H, P> (render: R, handle: H, process: P, state: T) -> Self where
|
||||
R: FnMut(&T, &mut Buffer, Rect)->Usually<Rect> + Send + 'static,
|
||||
H: FnMut(&mut T, &AppEvent) -> Result<(), Box<dyn Error>> + Send + 'static,
|
||||
|
|
@ -124,16 +129,14 @@ impl<T> DynamicDevice<T> {
|
|||
render: Mutex::new(Box::new(render)),
|
||||
handle: Arc::new(Mutex::new(Box::new(handle))),
|
||||
process: Arc::new(Mutex::new(Box::new(process))),
|
||||
client: None,
|
||||
}
|
||||
}
|
||||
fn state (&self) -> std::sync::MutexGuard<'_, T> {
|
||||
self.state.lock().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: NotificationHandler + 'static> DynamicDevice<T> {
|
||||
fn activate (&self, client: Client) -> Usually<()> {
|
||||
let notifications = {
|
||||
fn activate (mut self, client: Client) -> Usually<Self> {
|
||||
self.client = Some(client.activate_async(Notifications(Box::new({
|
||||
let state = self.state.clone();
|
||||
let handle = self.handle.clone();
|
||||
move|event|{
|
||||
|
|
@ -141,9 +144,7 @@ impl<T: NotificationHandler + 'static> DynamicDevice<T> {
|
|||
let mut handle = handle.lock().unwrap();
|
||||
handle(&mut state, &event).unwrap()
|
||||
}
|
||||
};
|
||||
let notifications = Notifications(Box::new(notifications));
|
||||
let handler = ClosureProcessHandler::new(Box::new({
|
||||
}) as Box<dyn Fn(AppEvent) + Send + Sync>), ClosureProcessHandler::new(Box::new({
|
||||
let state = self.state.clone();
|
||||
let process = self.process.clone();
|
||||
move|client: &Client, scope: &ProcessScope|{
|
||||
|
|
@ -151,9 +152,8 @@ impl<T: NotificationHandler + 'static> DynamicDevice<T> {
|
|||
let mut process = process.lock().unwrap();
|
||||
(process)(&mut state, client, scope)
|
||||
}
|
||||
}) as BoxedProcessHandler);
|
||||
client.activate_async(notifications, handler)?;
|
||||
Ok(())
|
||||
}) as BoxedProcessHandler))?);
|
||||
Ok(self)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -185,14 +185,6 @@ pub enum AppEvent {
|
|||
Jack(JackEvent)
|
||||
}
|
||||
|
||||
pub fn activate_jack_client <N: NotificationHandler + Sync + 'static> (
|
||||
client: Client,
|
||||
notifications: N,
|
||||
handler: BoxedProcessHandler
|
||||
) -> Result<Jack<N>, Box<dyn Error>> {
|
||||
Ok(client.activate_async(notifications, ClosureProcessHandler::new(handler))?)
|
||||
}
|
||||
|
||||
fn panic_hook (info: &std::panic::PanicInfo) {
|
||||
stdout()
|
||||
.execute(crossterm::terminal::LeaveAlternateScreen)
|
||||
|
|
@ -223,14 +215,17 @@ pub struct Notifications<T: Fn(AppEvent) + Send>(T);
|
|||
|
||||
impl<T: Fn(AppEvent) + Send> NotificationHandler for Notifications<T> {
|
||||
fn thread_init (&self, _: &Client) {
|
||||
println!("JACK: thread init");
|
||||
self.0(AppEvent::Jack(JackEvent::ThreadInit));
|
||||
}
|
||||
|
||||
fn shutdown (&mut self, status: ClientStatus, reason: &str) {
|
||||
println!("JACK: shutdown with status {:?} because \"{}\"", status, reason);
|
||||
self.0(AppEvent::Jack(JackEvent::Shutdown));
|
||||
}
|
||||
|
||||
fn freewheel (&mut self, _: &Client, is_enabled: bool) {
|
||||
println!("JACK: freewheel mode is {}", if is_enabled { "on" } else { "off" });
|
||||
self.0(AppEvent::Jack(JackEvent::Freewheel));
|
||||
}
|
||||
|
||||
|
|
@ -240,145 +235,41 @@ impl<T: Fn(AppEvent) + Send> NotificationHandler for Notifications<T> {
|
|||
}
|
||||
|
||||
fn client_registration (&mut self, _: &Client, name: &str, is_reg: bool) {
|
||||
println!("JACK: {} client with name \"{name}\"",
|
||||
if is_reg { "registered" } else { "unregistered" });
|
||||
self.0(AppEvent::Jack(JackEvent::ClientRegistration));
|
||||
}
|
||||
|
||||
fn port_registration (&mut self, _: &Client, port_id: PortId, is_reg: bool) {
|
||||
println!("JACK: {} port with id {port_id}",
|
||||
if is_reg { "registered" } else { "unregistered" });
|
||||
self.0(AppEvent::Jack(JackEvent::PortRegistration));
|
||||
}
|
||||
|
||||
fn port_rename (&mut self, _: &Client, id: PortId, old: &str, new: &str) -> Control {
|
||||
println!("JACK: port with id {id} renamed from {old} to {new}",);
|
||||
self.0(AppEvent::Jack(JackEvent::PortRename));
|
||||
Control::Continue
|
||||
}
|
||||
|
||||
fn ports_connected (&mut self, _: &Client, id_a: PortId, id_b: PortId, are: bool) {
|
||||
fn ports_connected (&mut self, _: &Client, a: PortId, b: PortId, are: bool) {
|
||||
println!("JACK: ports with id {a} and {b} are {}", if are {
|
||||
"connected"
|
||||
} else {
|
||||
"disconnected"
|
||||
});
|
||||
self.0(AppEvent::Jack(JackEvent::PortsConnected));
|
||||
}
|
||||
|
||||
fn graph_reorder (&mut self, _: &Client) -> Control {
|
||||
println!("JACK: graph reordered");
|
||||
self.0(AppEvent::Jack(JackEvent::GraphReorder));
|
||||
Control::Continue
|
||||
}
|
||||
|
||||
fn xrun (&mut self, _: &Client) -> Control {
|
||||
println!("JACK: xrun occurred");
|
||||
self.0(AppEvent::Jack(JackEvent::XRun));
|
||||
Control::Continue
|
||||
}
|
||||
}
|
||||
|
||||
//pub struct Jack {
|
||||
//client: Option<AsyncClient<
|
||||
//Notifications,
|
||||
//ClosureProcessHandler<Box<dyn FnMut(&Client, &ProcessScope)->Control + Send>>
|
||||
//>>,
|
||||
//pub transport: Option<Transport>,
|
||||
//audio_ins: BTreeMap<String, Port<AudioIn>>,
|
||||
//audio_outs: BTreeMap<String, Port<AudioOut>>,
|
||||
//midi_ins: BTreeMap<String, Port<MidiIn>>,
|
||||
//midi_outs: BTreeMap<String, Port<MidiOut>>,
|
||||
//}
|
||||
|
||||
//impl Jack {
|
||||
//pub fn init_from_cli (options: &Cli)
|
||||
//-> Result<Arc<Mutex<Self>>, Box<dyn Error>>
|
||||
//{
|
||||
//let jack = Self::init(&options.jack_client_name)?;
|
||||
//{
|
||||
//let jack = jack.clone();
|
||||
//let mut jack = jack.lock().unwrap();
|
||||
//for port in options.jack_audio_ins.iter() {
|
||||
//jack.add_audio_in(port)?;
|
||||
//}
|
||||
//for port in options.jack_audio_outs.iter() {
|
||||
//jack.add_audio_out(port)?;
|
||||
//}
|
||||
//for port in options.jack_midi_ins.iter() {
|
||||
//jack.add_midi_in(port)?;
|
||||
//}
|
||||
//for port in options.jack_midi_outs.iter() {
|
||||
//jack.add_midi_out(port)?;
|
||||
//}
|
||||
//}
|
||||
//Ok(jack.clone())
|
||||
//}
|
||||
//fn init (name: &str)
|
||||
//-> Result<Arc<Mutex<Self>>, Box<dyn Error>>
|
||||
//{
|
||||
//let jack = Arc::new(Mutex::new(Self {
|
||||
//client: None,
|
||||
//transport: None,
|
||||
//audio_ins: BTreeMap::new(),
|
||||
//audio_outs: BTreeMap::new(),
|
||||
//midi_ins: BTreeMap::new(),
|
||||
//midi_outs: BTreeMap::new(),
|
||||
//}));
|
||||
//let (client, status) = Client::new(name, ClientOptions::NO_START_SERVER)?;
|
||||
//println!("Client status: {status:?}");
|
||||
//let jack1 = jack.clone();
|
||||
//let mut jack1 = jack1.lock().unwrap();
|
||||
//let jack2 = jack.clone();
|
||||
//jack1.transport = Some(client.transport());
|
||||
//jack1.client = Some(client.activate_async(
|
||||
//Notifications, ClosureProcessHandler::new(Box::new(
|
||||
//move |_client: &Client, _ps: &ProcessScope| -> Control {
|
||||
//let jack = jack2.lock().expect("Failed to lock jack mutex");
|
||||
//jack.read_inputs();
|
||||
//jack.write_outputs();
|
||||
//Control::Continue
|
||||
//}
|
||||
//) as Box<dyn FnMut(&Client, &ProcessScope)->Control + Send>)
|
||||
//)?);
|
||||
//Ok(jack)
|
||||
//}
|
||||
//fn start (&self) {
|
||||
//}
|
||||
//fn process (&self, _: &Client, ps: &ProcessScope) -> Control {
|
||||
//Control::Continue
|
||||
//}
|
||||
//fn add_audio_in (&mut self, name: &str) -> Result<&mut Self, Box<dyn Error>> {
|
||||
//let port = self.client
|
||||
//.as_ref()
|
||||
//.expect("Not initialized.")
|
||||
//.as_client()
|
||||
//.register_port(name, AudioIn::default())?;
|
||||
//self.audio_ins.insert(name.into(), port);
|
||||
//Ok(self)
|
||||
//}
|
||||
//fn add_audio_out (&mut self, name: &str) -> Result<&mut Self, Box<dyn Error>> {
|
||||
//let port = self.client
|
||||
//.as_ref()
|
||||
//.expect("Not initialized.")
|
||||
//.as_client()
|
||||
//.register_port(name, AudioOut::default())?;
|
||||
//self.audio_outs.insert(name.into(), port);
|
||||
//Ok(self)
|
||||
//}
|
||||
//fn add_midi_in (&mut self, name: &str) -> Result<&mut Self, Box<dyn Error>> {
|
||||
//let port = self.client
|
||||
//.as_ref()
|
||||
//.expect("Not initialized.")
|
||||
//.as_client()
|
||||
//.register_port(name, MidiIn::default())?;
|
||||
//self.midi_ins.insert(name.into(), port);
|
||||
//Ok(self)
|
||||
//}
|
||||
//fn add_midi_out (&mut self, name: &str) -> Result<&mut Self, Box<dyn Error>> {
|
||||
//let port = self.client
|
||||
//.as_ref()
|
||||
//.expect("Not initialized.")
|
||||
//.as_client()
|
||||
//.register_port(name, MidiOut::default())?;
|
||||
//self.midi_outs.insert(name.into(), port);
|
||||
//Ok(self)
|
||||
//}
|
||||
//fn read_inputs (&self) {
|
||||
//// read input buffers
|
||||
////println!("read");
|
||||
//}
|
||||
//fn write_outputs (&self) {
|
||||
//// clear output buffers
|
||||
//// write output buffers
|
||||
////println!("write");
|
||||
//}
|
||||
//}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue