rust-jack
rust-jack copied to clipboard
Keeping activate_async result in a struct
More probably a bug by me. In my first rust-jack (and even Rust, so be gentle with a beginner :) tryout, I would like to make a small oscilloscope and STFT spectrum analyzer using egui and rust-jack. I need to keep the client around in my code for stopping it on an input from the GUI, so (for now at least) I would like to write something along those lines:
pub struct SinePlot {
line_plot: LinePlot, // egui plot
jclient: (jack::AsyncClient<Notifications, dyn jack::ProcessHandler>, jack::Error), // app.rs LINE 108
}
...
impl Default for SinePlot {
fn default() -> Self {
let (client, _status) = jack::Client::new("birdsong_rs", jack::ClientOptions::NO_START_SERVER).unwrap();
// Register ports. They will be used in a callback that will be
// called when new data is available.
let in_l = client
.register_port("in_l", jack::AudioIn::default())
.unwrap();
let in_r = client
.register_port("in_r", jack::AudioIn::default())
.unwrap();
let mut out_l = client
.register_port("out_l", jack::AudioOut::default())
.unwrap();
let mut out_r = client
.register_port("out_r", jack::AudioOut::default())
.unwrap();
let process_callback = move |_: &jack::Client, ps: &jack::ProcessScope| -> jack::Control {
let out_l_p = out_l.as_mut_slice(ps);
let out_r_p = out_r.as_mut_slice(ps);
let in_l_p = in_l.as_slice(ps);
let in_r_p = in_r.as_slice(ps);
out_l_p.clone_from_slice(in_l_p);
out_r_p.clone_from_slice(in_r_p);
jack::Control::Continue
};
let process = jack::ClosureProcessHandler::new(process_callback);
// Activate the client, which starts the processing.
Self {
line_plot: LinePlot::default(),
// or Rc::new(client.activate...) in case it's needed :
jclient: client.activate_async(Notifications, process).unwrap(),
}
}
}
But typing the result of async_client is not easy, nor having an allocation size for it it seems:
error[E0038]: the trait "ProcessHandler" cannot be made into an object
--> src/app.rs:108:48
|
108 | jclient: (jack::AsyncClient<Notifications, dyn jack::ProcessHandler>, jack::Error),
| ^^^^^^^^^^^^^^^^^^^^^^^^ "ProcessHandler" cannot be made into an object
|
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> /home/catseye/.cargo/registry/src/index.crates.io-6f17d22bba15001f/jack-0.11.4/src/client/callbacks.rs:78:11
|
78 | const SLOW_SYNC:bool = false;
| ^^^^^^^^^ the trait cannot be made into an object because it contains this associated `const`
= help: the following types implement the trait, consider defining an enum where each variant holds one of these types, implementing `ProcessHandler` for this new enum and using it instead:
()
jack::ClosureProcessHandler<F>
error[E0277]: the size for values of type "(dyn ProcessHandler + 'static)" cannot be known at compilation time
--> src/app.rs:108:14
|
108 | jclient: (jack::AsyncClient<Notifications, dyn jack::ProcessHandler>, jack::Error),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait "Sized" is not implemented for "(dyn ProcessHandler + 'static)"
note: required by a bound in "AsyncClient"
--> /home/catseye/.cargo/registry/src/index.crates.io-6f17d22bba15001f/jack-0.11.4/src/client/async_client.rs:33:27
|
33 | pub struct AsyncClient<N, P> {
| ^ required by this bound in "AsyncClient"
How do I write my interwoven GUI and jack code to keep the (async_)client around so that I can stop it once it is started?