lowfi/src/audio/waiter.rs
Tal 02a4e688bd chore: update dependencies
for some reason, rodio decided it would be a great idea to change all of
the core terminology to be less technical. this is frankly strange, but
it's best not to use an outdated version of the dependency.

rodio is for some reason switching to a "breaking change every single
update" versioning model. why? i have frankly no idea, semver exists for
a reason and they decided just not to use it. 0.x.x is stupid, and
people should realize semver exists for a reason. to the total of zero
people who will read this, thanks for reading my short rant.
2026-03-05 20:34:45 +01:00

53 lines
1.4 KiB
Rust

use std::{sync::Arc, time::Duration};
use tokio::{
sync::{mpsc, Notify},
time,
};
/// Background loop that waits for the sink to drain and then attempts
/// to send a `Message::Next` to the provided channel.
async fn waiter(
sink: Arc<rodio::Player>,
tx: mpsc::Sender<crate::Message>,
notify: Arc<Notify>,
) -> crate::Result<()> {
loop {
notify.notified().await;
while !sink.empty() {
time::sleep(Duration::from_millis(16)).await;
}
if tx.try_send(crate::Message::Next).is_err() {
break Ok(());
}
}
}
/// Lightweight helper that waits for the current sink to drain and then
/// notifies the player to advance to the next track.
pub struct Handle {
/// Notification primitive used to wake the waiter.
notify: Arc<Notify>,
}
impl Handle {
/// Notify the waiter that playback state may have changed and it should
/// re-check the sink emptiness condition.
pub fn notify(&self) {
self.notify.notify_one();
}
}
impl crate::Tasks {
/// Create a new `Handle` which watches the provided `sink` and sends
/// `Message::Next` down `tx` when the sink becomes empty.
pub fn waiter(&mut self, sink: Arc<rodio::Player>) -> Handle {
let notify = Arc::new(Notify::new());
self.spawn(waiter(sink, self.tx(), notify.clone()));
Handle { notify }
}
}