use std::sync::Arc;
use tokio::sync::{RwLock, mpsc};
use crate::event::SessionEvent;
use crate::msg::QueueRendererState;
#[derive(Debug, Clone)]
pub enum SessionCommand {
ReportState(QueueRendererState),
ReportVolume(u32),
ReportVolumeMuted(bool),
ReportMaxAudioQuality(i32),
ReportFileAudioQuality(u32),
}
pub(crate) type SharedCommandTx = Arc<RwLock<Option<mpsc::Sender<SessionCommand>>>>;
pub struct DeviceSession {
events: mpsc::Receiver<SessionEvent>,
command_tx: SharedCommandTx,
}
impl DeviceSession {
pub(crate) fn new(events: mpsc::Receiver<SessionEvent>, command_tx: SharedCommandTx) -> Self {
Self { events, command_tx }
}
pub async fn recv(&mut self) -> Option<SessionEvent> {
self.events.recv().await
}
async fn send_command(&self, cmd: SessionCommand) -> crate::Result<()> {
let guard = self.command_tx.read().await;
match &*guard {
Some(tx) => tx
.send(cmd)
.await
.map_err(|_| crate::Error::Session("Session closed".to_string())),
None => Err(crate::Error::Session("Not connected".to_string())),
}
}
pub async fn report_state(&self, state: QueueRendererState) -> crate::Result<()> {
self.send_command(SessionCommand::ReportState(state)).await
}
pub async fn report_volume(&self, volume: u32) -> crate::Result<()> {
self.send_command(SessionCommand::ReportVolume(volume))
.await
}
pub async fn report_muted(&self, muted: bool) -> crate::Result<()> {
self.send_command(SessionCommand::ReportVolumeMuted(muted))
.await
}
pub async fn report_max_audio_quality(&self, quality: i32) -> crate::Result<()> {
self.send_command(SessionCommand::ReportMaxAudioQuality(quality))
.await
}
pub async fn report_file_audio_quality(&self, sample_rate_hz: u32) -> crate::Result<()> {
self.send_command(SessionCommand::ReportFileAudioQuality(sample_rate_hz))
.await
}
}