rust-jack icon indicating copy to clipboard operation
rust-jack copied to clipboard

Keeping activate_async result in a struct

Open phstrauss opened this issue 6 days ago • 0 comments

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?

phstrauss avatar Jul 01 '24 17:07 phstrauss