#What is the right pattern ?

16 messages · Page 1 of 1 (latest)

clever prairie
#

I am implementing a loop to parse mpsc messages. It looks like this :

pub struct SimConnectHandler {
    rx_to_simconnect: Receiver<ChannelMessage>,
}

impl SimConnectHandler {
    /// Main thread function
    pub fn run(&mut self) {
        loop {
            for msg in self.rx_to_simconnect.try_iter() {
                match msg.message_type {
                    ListOfMessageTypes::SimStart => {
                        self.start();
                    }
                    _ => {}
                }
            }
        }
    }

    fn start(&mut self) {
        // do some stuff
    }
}

I get an error from rustc because self.start() requires a mutable on self while self.tx_to_simconnect.try_iter() already has one on the self object.

The only way forward I found so far is something like this :

pub struct SimConnectHandler {
    rx_to_simconnect: Receiver<ChannelMessage>,
}

impl SimConnectHandler {
    /// Main thread function
    pub fn run(&mut self) {
        loop {
            let messages: Vec<ChannelMessage> = Vec::new();
            for msg in self.rx_to_simconnect.try_iter() {
                messages.push(msg);
             }
            for msg in messages {
                match msg.message_type {
                    ListOfMessageTypes::SimStart => {
                        self.start();
                    }
                    _ => {}
                }
            }
        }
    }

    fn start(&mut self) {
        // do some stuff
    }
}

It works but the pattern with two consecutive loops doesn't feel satisfactory. It looks pretty much like a workaround, not a solution.

Is there a better way to handle such a situation ? Thanks !

deft lodge
#

the first thing is: what is this struct?? it feels like you want just a function, but are forcing it into struct form instead.

#

you could just structure it like this I think ```rs
pub fn connect_sim(rx_to_simconnect: &mut Receiver<ChannelMessage>) {
loop {
let mut messages = Vec::new();
for msg in rx_to_simconnect.try_iter() {
messages.push(msg);
}
for msg in messages {
match msg.message_type {
ListOfMessageTypes::SimStart => {
start(rx_to_simconnect);
}
_ => {}
}
}
}
}

fn start(&mut Receiver<ChannelMessage>) {
// do some stuff
}```

#

second thing is that ListOfMessageTypes feels like a very odd enum name. MessageType would probably be better.

#

or even MsgType if you want it to be more concise

#

ok on the actual topic, it feels very weird that you want a reference into the receiver itself. I would have expected that start( takes a ChannelMessage or &mut ChannelMessage

spiral garnet
#

Usually, when you want to call a function on self while a field is borrowed, you should consider splitting up your structs.

#

So that the borrowed part is in a different substruct as the one you're calling the function on

deft lodge
spiral garnet
deft lodge
#

ok fair

clever prairie
#

Thanks for you answer and comments. Indeed, there will be much more things into this struct, I just gave a simplified version to explain my issue. It will handle the connection to Flight Simulator using SimConnect API. Start is the command to connect to the API.

#

I could put the loop and receiver outside of the struct, if may be a better way a structuring stuff. I am biased by previous language experience to see everything as an object

#

Messages can come from both a CLI inside the app or another thread that receive serial messages from an arduino module.

spiral garnet
# clever prairie Thanks for you answer and comments. Indeed, there will be much more things into ...

Seeing everything as an object isn't necessarily a problem, but sometimes in Rust it's helpful to see everything as more objects.

Imagine this code

for msg in self.rx.to_simconnect.try_iter() {
  ...
  self.foo.start()
}
````rx` and `foo` are disjoint fields in this version, so you can borrow them mutably at the same time.

This also means that now `self` is just a "bag" to contain `rx`, `foo`, and possibly other things together: there are now more substructs