mirror of
https://github.com/talwat/lowfi
synced 2026-01-09 15:33:20 +00:00
chore: use a plain future impl instead of a joinset
This commit is contained in:
parent
7e1a97fa7b
commit
9bffe77b2f
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -1350,7 +1350,7 @@ checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lowfi"
|
name = "lowfi"
|
||||||
version = "2.0.0"
|
version = "2.0.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arc-swap",
|
"arc-swap",
|
||||||
"bytes",
|
"bytes",
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "lowfi"
|
name = "lowfi"
|
||||||
version = "2.0.0"
|
version = "2.0.1"
|
||||||
rust-version = "1.83.0"
|
rust-version = "1.83.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
description = "An extremely simple lofi player."
|
description = "An extremely simple lofi player."
|
||||||
|
|||||||
@ -130,11 +130,15 @@ async fn main() -> eyre::Result<()> {
|
|||||||
|
|
||||||
let stream = audio::stream()?;
|
let stream = audio::stream()?;
|
||||||
let environment = ui::Environment::ready(&args)?;
|
let environment = ui::Environment::ready(&args)?;
|
||||||
let (mut player, mut tasks) = Player::init(args, stream.mixer())
|
let (mut player, tasks) = Player::init(args, stream.mixer())
|
||||||
.await
|
.await
|
||||||
.inspect_err(|_| environment.cleanup(false).unwrap())?;
|
.inspect_err(|_| environment.cleanup(false).unwrap())?;
|
||||||
|
|
||||||
let result = tasks.wait(player.run()).await;
|
let result = tokio::select! {
|
||||||
|
r = player.run() => r,
|
||||||
|
r = tasks => r,
|
||||||
|
};
|
||||||
|
|
||||||
environment.cleanup(result.is_ok())?;
|
environment.cleanup(result.is_ok())?;
|
||||||
player.close().await?;
|
player.close().await?;
|
||||||
|
|
||||||
|
|||||||
48
src/tasks.rs
48
src/tasks.rs
@ -3,15 +3,15 @@
|
|||||||
//! This file aims to abstract a lot of potentially annoying Rust async logic, which may be
|
//! This file aims to abstract a lot of potentially annoying Rust async logic, which may be
|
||||||
//! subject to change.
|
//! subject to change.
|
||||||
|
|
||||||
use futures_util::TryFutureExt;
|
use futures_util::{FutureExt, TryFutureExt};
|
||||||
use std::future::Future;
|
use std::{future::Future, pin::Pin, task::Poll};
|
||||||
use tokio::{select, sync::mpsc, task::JoinSet};
|
use tokio::{sync::mpsc, task::JoinHandle};
|
||||||
|
|
||||||
/// Handles all of the processes within lowfi.
|
/// Handles all of the processes within lowfi.
|
||||||
/// This entails initializing/closing tasks, and handling any potential errors that arise.
|
/// This entails initializing/closing tasks, and handling any potential errors that arise.
|
||||||
pub struct Tasks {
|
pub struct Tasks {
|
||||||
/// The [`JoinSet`], which contains all of the task handles.
|
/// A simple [`Vec`] of [`JoinHandle`]s.
|
||||||
pub set: JoinSet<crate::Result<()>>,
|
pub handles: Vec<JoinHandle<crate::Result<()>>>,
|
||||||
|
|
||||||
/// A sender, which is kept for convenience to be used when
|
/// A sender, which is kept for convenience to be used when
|
||||||
/// initializing various other tasks.
|
/// initializing various other tasks.
|
||||||
@ -20,45 +20,39 @@ pub struct Tasks {
|
|||||||
|
|
||||||
impl Tasks {
|
impl Tasks {
|
||||||
/// Creates a new task manager.
|
/// Creates a new task manager.
|
||||||
pub fn new(tx: mpsc::Sender<crate::Message>) -> Self {
|
pub const fn new(tx: mpsc::Sender<crate::Message>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
tx,
|
tx,
|
||||||
set: JoinSet::new(),
|
handles: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Processes a task, and adds it to the internal [`JoinSet`].
|
/// Processes a task, and adds it to the internal buffer.
|
||||||
pub fn spawn<E: Into<crate::Error> + Send + Sync + 'static>(
|
pub fn spawn<E: Into<crate::Error> + Send + Sync + 'static>(
|
||||||
&mut self,
|
&mut self,
|
||||||
future: impl Future<Output = Result<(), E>> + Send + 'static,
|
future: impl Future<Output = Result<(), E>> + Send + 'static,
|
||||||
) {
|
) {
|
||||||
self.set.spawn(future.map_err(Into::into));
|
self.handles.push(tokio::spawn(future.map_err(Into::into)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets a copy of the internal [`mpsc::Sender`].
|
/// Gets a copy of the internal [`mpsc::Sender`].
|
||||||
pub fn tx(&self) -> mpsc::Sender<crate::Message> {
|
pub fn tx(&self) -> mpsc::Sender<crate::Message> {
|
||||||
self.tx.clone()
|
self.tx.clone()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Actively polls all of the handles previously added.
|
impl Future for Tasks {
|
||||||
///
|
type Output = crate::Result<()>;
|
||||||
/// An additional `runner` is for the main player future, which
|
|
||||||
/// can't be added as a "task" because it shares data with the
|
fn poll(self: Pin<&mut Self>, cx: &mut std::task::Context<'_>) -> Poll<Self::Output> {
|
||||||
/// main thread.
|
for handle in &mut self.get_mut().handles {
|
||||||
///
|
match handle.poll_unpin(cx) {
|
||||||
/// This either returns when the runner completes, or if an error occurs
|
Poll::Ready(Ok(x)) => return Poll::Ready(x),
|
||||||
/// in any of the internally held tasks.
|
Poll::Ready(Err(x)) => return Poll::Ready(Err(crate::Error::JoinError(x))),
|
||||||
pub async fn wait(
|
Poll::Pending => (),
|
||||||
&mut self,
|
|
||||||
runner: impl Future<Output = Result<(), crate::Error>> + std::marker::Send,
|
|
||||||
) -> crate::Result<()> {
|
|
||||||
select! {
|
|
||||||
result = runner => result,
|
|
||||||
Some(result) = self.set.join_next() => match result {
|
|
||||||
Ok(res) => res,
|
|
||||||
Err(e) if !e.is_cancelled() => Err(crate::Error::JoinError(e)),
|
|
||||||
Err(_) => Ok(()),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Poll::Pending
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user