A trait for structs that can be run

I've been thinking about a trait for structs that can be run. For example, a video decoder could be run, launching its own thread.

pub trait Runnable {
    fn run(&mut self) -> Result<(), RunnableError>;
}

This is what I came up with:

impl Runnable for FfmpegSoftwareDecoder {
    fn run(&mut self) -> Result<(), RunnableError> {
        let on_consume = on_consume.clone();
        let on_produce = on_produce.clone();
        //launches the thread
        self.stoppable_thread.run(
            format!("ffmpeg_software_decoder_{}", self.domain.name()).as_str(),
            Box::new(move |should_continue: Arc<AtomicBool>| {
                while should_continue.load(Ordering::Relaxed) {
                    //decodes packets from on_consume and produce to on_produce

however there's a major problem with this approach. I cannot get references to the inner objects of the struct, except if they are Arc, like on_consume and on_produce (Arc<dyn Fn()...> in this example).

Should I do something like this instead:

pub trait Runnable {
    fn run(o: Arc<Mutex<Self>>) -> Result<(), RunnableError>;
}

?
But actually I wanted to implement

pub trait Runnable {
    fn run(o: Arc<Mutex<dyn Decoder>>) -> Result<(), RunnableError>;
}

for the FfmpegSoftwareDecoder

and

pub trait Runnable {
    fn run(o: Arc<Mutex<dyn RtspClient>>) -> Result<(), RunnableError>;
}

for the MyRtspClient, and etc. I think you get the idea.

Remember that Decoder is a trait that FfmpegSoftwareDecoder implements.

use std::sync::{Arc, Mutex};

pub trait Runnable<T> {
    fn run(s: Arc<Mutex<T>>) -> Result<(), ()>;
}

pub trait Decoder: Runnable<dyn Decoder> {

}

something like this I guess. But in this way, it's cyclic, won't compile

   Compiling playground v0.0.1 (/playground)
error[E0391]: cycle detected when computing the super predicates of `Decoder`
 --> src/lib.rs:7:1
  |
7 | pub trait Decoder: Runnable<dyn Decoder> {
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |
note: ...which requires computing the super traits of `Decoder`...
 --> src/lib.rs:7:1
  |
7 | pub trait Decoder: Runnable<dyn Decoder> {
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  = note: ...which again requires computing the super predicates of `Decoder`, completing the cycle
note: cycle used when collecting item types in top-level module
 --> src/lib.rs:7:1
  |
7 | pub trait Decoder: Runnable<dyn Decoder> {
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

I don't understand this, why is it the case? Surely you can reborrow individual fields of a struct behind a &mut reference, even if they are not wrapped in an Arc.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.