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]]
|
||||
name = "lowfi"
|
||||
version = "2.0.0"
|
||||
version = "2.0.1"
|
||||
dependencies = [
|
||||
"arc-swap",
|
||||
"bytes",
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "lowfi"
|
||||
version = "2.0.0"
|
||||
version = "2.0.1"
|
||||
rust-version = "1.83.0"
|
||||
edition = "2021"
|
||||
description = "An extremely simple lofi player."
|
||||
|
||||
@ -130,11 +130,15 @@ async fn main() -> eyre::Result<()> {
|
||||
|
||||
let stream = audio::stream()?;
|
||||
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
|
||||
.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())?;
|
||||
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
|
||||
//! subject to change.
|
||||
|
||||
use futures_util::TryFutureExt;
|
||||
use std::future::Future;
|
||||
use tokio::{select, sync::mpsc, task::JoinSet};
|
||||
use futures_util::{FutureExt, TryFutureExt};
|
||||
use std::{future::Future, pin::Pin, task::Poll};
|
||||
use tokio::{sync::mpsc, task::JoinHandle};
|
||||
|
||||
/// Handles all of the processes within lowfi.
|
||||
/// This entails initializing/closing tasks, and handling any potential errors that arise.
|
||||
pub struct Tasks {
|
||||
/// The [`JoinSet`], which contains all of the task handles.
|
||||
pub set: JoinSet<crate::Result<()>>,
|
||||
/// A simple [`Vec`] of [`JoinHandle`]s.
|
||||
pub handles: Vec<JoinHandle<crate::Result<()>>>,
|
||||
|
||||
/// A sender, which is kept for convenience to be used when
|
||||
/// initializing various other tasks.
|
||||
@ -20,45 +20,39 @@ pub struct Tasks {
|
||||
|
||||
impl Tasks {
|
||||
/// 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 {
|
||||
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>(
|
||||
&mut self,
|
||||
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`].
|
||||
pub fn tx(&self) -> mpsc::Sender<crate::Message> {
|
||||
self.tx.clone()
|
||||
}
|
||||
}
|
||||
|
||||
/// Actively polls all of the handles previously added.
|
||||
///
|
||||
/// An additional `runner` is for the main player future, which
|
||||
/// can't be added as a "task" because it shares data with the
|
||||
/// main thread.
|
||||
///
|
||||
/// This either returns when the runner completes, or if an error occurs
|
||||
/// in any of the internally held tasks.
|
||||
pub async fn wait(
|
||||
&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(()),
|
||||
impl Future for Tasks {
|
||||
type Output = crate::Result<()>;
|
||||
|
||||
fn poll(self: Pin<&mut Self>, cx: &mut std::task::Context<'_>) -> Poll<Self::Output> {
|
||||
for handle in &mut self.get_mut().handles {
|
||||
match handle.poll_unpin(cx) {
|
||||
Poll::Ready(Ok(x)) => return Poll::Ready(x),
|
||||
Poll::Ready(Err(x)) => return Poll::Ready(Err(crate::Error::JoinError(x))),
|
||||
Poll::Pending => (),
|
||||
}
|
||||
}
|
||||
|
||||
Poll::Pending
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user