how top avoid mpsc::channel getting dropped in a continuous loop?

24 Views Asked by At

Help please - I'm trying to get around the problem of mpsc::channel() getting dropped while running a loop. Basically what I'm trying to do is generate signals on the gpio pins of a pi (that's straightforward) but then I need to tell the signals to stop using a gui button. I originally had a loop running in a thread in a closure and every time the loop went back to the beginning ie the function re-called, tx and rx in the mpsc::channel were getting dropped. I was advised to put the channel in a struct which I have tried to do here, but tx/rx is STILL getting dropped so I can't turn off the signal to the gpio pin. Even though I now have the loop running with no thread/closure, I can't get tx to send a message/ rx won't pick up the message so it appears one or other is still getting dropped. Please can someone "in the know" tell me what I'm doing wrong here? All I need in effect is a software "stop switch"!I've tried using Arc/Mutex but same problem. ...

use chrono::Utc;
use iced::pure::widget::{Button, Column, Container, Text};
use iced::pure::Sandbox;
use iced::Settings;
use rust_gpiozero::*;
use std::thread;
use std::thread::sleep;
//use std::io::{self, BufRead};
use std::env;
use std::io;
use std::io::BufRead;
use std::process;
use std::sync::mpsc;
use std::sync::Arc;
use std::sync::Mutex;
//use std::sync::mpsc::{self, TryRecvError};
use std::sync::mpsc::channel;
use std::time::Duration;
use std::sync::atomic::{AtomicBool, Ordering};
//use std::sync::Arc;
fn main() //-> Result<(), iced::Error>
-> Result<(), iced::Error> 
  {
    Block::run(Settings::default())
    //println!("here we go!");
}
//struct Counter {
  //  count: i32 
    
   // }
struct Block {
   pair: (tx, rx)::mpsc::channel(),
   //value: i32,
    }
#[derive(Debug, Clone, Copy)]
enum CounterMessage {
    Flash1,
    Stop,
    }

//impl dyn Sandbox<Message = Type>{
 impl Sandbox for Block {
    type Message =  CounterMessage;
 

    fn new() -> Self {
        //Block { value: 1} }
        Block { pair: channel() } 
    }

    fn title(&self) -> String {
        String::from("RPi gpio gui")
    }
     fn update(&mut self, message: Self::Message) {
        //let (tx, rx) = mpsc::channel::<Block>();
        let (tx, rx) = mpsc::channel();

        //let input = Block{ value: 1 };
        let input = 1;
        //let val = String::from("hi");
        match message {
            CounterMessage::Flash1 => {               
                    loop {
                    //let message1a = rx.lock().unwrap().recv.unwrap();    >
                    let led = LED::new(17);
                    led.on();
                    sleep(Duration::from_millis(500));
                    led.off();
                    sleep(Duration::from_millis(500));
                    //let block = rx.try_recv().unwrap();
                    let block = rx.try_recv();

                    //match rx.recv()
                    match rx.try_recv(){  
                      Ok (_) => {println!("got the message");
                        break;}     
                      Err (_) => {continue} } } }                          
             CounterMessage::Stop => {
              //let input = Block{ value: 1 };
              tx.send(input).unwrap();
              println!("Stop detected");
              }            
              } }   // println!("stop button pressed");
                 
    fn view(&self) -> iced::pure::Element<Self::Message> {
        let flash1 = Button::new("FLASH1").on_press(CounterMessage::Flash1);
        let stop = Button::new("STOP FLASH!").on_press(CounterMessage::Stop);
        //let flash2 = Button::new("FLASH2").on_press(CounterMessage2::Flash2);
        //let stop2 = Button::new("STOP FLASH2").on_press(CounterMessage2::Stop2);

        let col = Column::new()
            .push(flash1)
            .push(stop);
            //.push(flash2)
            //.push(stop2);
 
        Container::new(col)
            .center_x()
            .center_y()
            .width(iced::Length::Fill)
           .height(iced::Length::Fill)
            .into()
    }
}

...

0

There are 0 best solutions below