simplify audio locking with local refcell rather than thread local
This commit is contained in:
22
src/main.rs
22
src/main.rs
@@ -19,10 +19,6 @@ const HUE_KEY: &str = include_str!("../hue.key");
|
|||||||
const BUTTON_PIN: u8 = 26;
|
const BUTTON_PIN: u8 = 26;
|
||||||
const CHANNEL_VEC_SIZE: usize = 32;
|
const CHANNEL_VEC_SIZE: usize = 32;
|
||||||
|
|
||||||
thread_local! {
|
|
||||||
static AUDIO_CHILD: RefCell<Option<process::Child>> = RefCell::new(None);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tokio::main(basic_scheduler)]
|
#[tokio::main(basic_scheduler)]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
pretty_env_logger::init_timed();
|
pretty_env_logger::init_timed();
|
||||||
@@ -36,13 +32,15 @@ async fn main() {
|
|||||||
pin.set_async_interrupt(Trigger::FallingEdge, move |_| button_pressed(&clients))
|
pin.set_async_interrupt(Trigger::FallingEdge, move |_| button_pressed(&clients))
|
||||||
.expect("set interrupt");
|
.expect("set interrupt");
|
||||||
|
|
||||||
let reqwest = &reqwest::Client::new();
|
|
||||||
let (tx, rx) = mpsc::channel(1);
|
let (tx, rx) = mpsc::channel(1);
|
||||||
events_clients.lock().unwrap().push(tx);
|
events_clients.lock().unwrap().push(tx);
|
||||||
|
|
||||||
|
let reqwest = &reqwest::Client::new();
|
||||||
|
let audio_child = &RefCell::new(None);
|
||||||
let hue_busy = &Cell::new(false);
|
let hue_busy = &Cell::new(false);
|
||||||
let pushes = rx.for_each_concurrent(2, |()| async move {
|
let pushes = rx.for_each_concurrent(2, |()| async move {
|
||||||
if !audio_busy() {
|
if !audio_busy(&audio_child) {
|
||||||
play_chime()
|
play_chime(&audio_child)
|
||||||
} else { debug!("doorbell still ringing, not playing new chime"); }
|
} else { debug!("doorbell still ringing, not playing new chime"); }
|
||||||
|
|
||||||
if !hue_busy.replace(true) {
|
if !hue_busy.replace(true) {
|
||||||
@@ -107,25 +105,23 @@ async fn warp(clients: Arc<Mutex<SmallVec<[mpsc::Sender<()>; CHANNEL_VEC_SIZE]>>
|
|||||||
warp::serve(routes).run(([0, 0, 0, 0], 8060)).await;
|
warp::serve(routes).run(([0, 0, 0, 0], 8060)).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn audio_busy() -> bool {
|
fn audio_busy(audio_child: &RefCell<Option<process::Child>>) -> bool {
|
||||||
AUDIO_CHILD.with(|cell| {
|
if let Some(ref mut audio_child) = *audio_child.borrow_mut() {
|
||||||
if let Some(ref mut audio_child) = *cell.borrow_mut() {
|
|
||||||
if let Ok(None) = audio_child.try_wait() {
|
if let Ok(None) = audio_child.try_wait() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
false
|
false
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn play_chime() {
|
fn play_chime(audio_child: &RefCell<Option<process::Child>>) {
|
||||||
trace!("Playing doorbell chime");
|
trace!("Playing doorbell chime");
|
||||||
match process::Command::new("mplayer")
|
match process::Command::new("mplayer")
|
||||||
.arg(OUTDOOR_CHIME_FILE)
|
.arg(OUTDOOR_CHIME_FILE)
|
||||||
.stdout(process::Stdio::null())
|
.stdout(process::Stdio::null())
|
||||||
.stderr(process::Stdio::null())
|
.stderr(process::Stdio::null())
|
||||||
.spawn() {
|
.spawn() {
|
||||||
Ok(child) => { AUDIO_CHILD.with(|cell| cell.replace(Some(child))); },
|
Ok(child) => { audio_child.replace(Some(child)); },
|
||||||
Err(err) => error!("Error playing outdoor chime: {}", err)
|
Err(err) => error!("Error playing outdoor chime: {}", err)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user