use std::sync::{
atomic::{AtomicBool, Ordering},
Arc,
};
use maudio_sys::ffi as sys;
#[derive(Clone)]
pub struct EndNotifier {
flag: Arc<AtomicBool>,
}
impl EndNotifier {
pub(crate) fn new() -> Self {
Self {
flag: Arc::new(AtomicBool::new(false)),
}
}
#[inline]
pub fn peek(&self) -> bool {
self.flag.load(Ordering::Relaxed)
}
#[inline]
pub fn take(&self) -> bool {
self.flag.swap(false, Ordering::Relaxed)
}
#[inline]
pub fn clear(&self) {
self.flag.store(false, Ordering::Relaxed);
}
pub fn take_with<F: FnOnce()>(&self, f: F) {
if self.take() {
f();
}
}
pub(crate) fn as_user_data_ptr(&self) -> *mut core::ffi::c_void {
std::sync::Arc::as_ptr(&self.flag) as *mut core::ffi::c_void
}
}
pub(crate) unsafe extern "C" fn on_end_callback(
user_data: *mut core::ffi::c_void,
_sound: *mut sys::ma_sound,
) {
if user_data.is_null() {
return;
}
let flag = unsafe { &*(user_data as *const std::sync::atomic::AtomicBool) };
flag.store(true, Ordering::Relaxed);
}