use std::{
ops::{Deref, DerefMut},
sync::{Arc, OnceLock, atomic::AtomicU32},
};
use crate::{
cpal_thread::{AtomicLoudnormMode, CpalHandle, PlaybackError},
session::{SessionEventThread, SessionHandle},
};
pub(crate) mod cpal_stream;
pub(crate) struct LocalSessionHandle {
pub session: SessionHandle,
pub loudnorm_mode: Arc<AtomicLoudnormMode>,
pub volume: Arc<AtomicU32>,
}
#[cfg(feature = "plugin-support")]
pub use selene_plugin_sdk::{
self as sdk, Arc as SessionArc, local_session::StableEventListenerDynMut,
};
#[cfg(not(feature = "plugin-support"))]
pub use std::sync::Arc as SessionArc;
static LOCAL_SESSION: OnceLock<SessionArc<LocalSessionHandle>> = OnceLock::new();
pub(crate) fn local_session() -> &'static LocalSessionHandle {
LOCAL_SESSION.get().unwrap()
}
#[cfg(feature = "plugin-support")]
pub(crate) fn plugin_session() -> sdk::local_session::LocalSessionHandle {
LOCAL_SESSION.get().unwrap().clone().into()
}
impl LocalSessionHandle {
pub(crate) fn init() -> Result<(), PlaybackError> {
let cpal_handle = CpalHandle::open()?;
let volume = cpal_handle.volume();
let loudnorm_mode = cpal_handle.loudnorm_mode.clone();
let handle = SessionHandle::open_local(cpal_handle);
let session = Self {
session: handle,
volume,
loudnorm_mode,
};
assert!(LOCAL_SESSION.set(SessionArc::new(session)).is_ok());
Ok(())
}
#[cfg(feature = "plugin-support")]
pub(crate) fn init_with_plugins(
event_callbacks: Vec<sdk::local_session::EventListener>,
) -> Result<(), PlaybackError> {
let cpal_handle = CpalHandle::open()?;
let volume = cpal_handle.volume();
let loudnorm_mode = cpal_handle.loudnorm_mode.clone();
let handle = SessionHandle::open_local_with_plugins(cpal_handle, event_callbacks);
let session = Self {
session: handle,
volume,
loudnorm_mode,
};
assert!(LOCAL_SESSION.set(SessionArc::new(session)).is_ok());
Ok(())
}
}
impl Deref for LocalSessionHandle {
type Target = SessionHandle;
fn deref(&self) -> &Self::Target {
&self.session
}
}
impl DerefMut for LocalSessionHandle {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.session
}
}
lunar_lib::make_runner_event_ext!(SessionEventThread => pub(crate) trait LocalSessionEventExt {
fn volume_changed(&mut self, volume: f32) {
#[cfg(feature = "plugin-support")]
{
if let Some(items) = &mut self.plugin_event_callbacks {
for event_callback in items {
event_callback.volume_changed(volume);
}
}
}
}
});