use crate::wasapi::Error;
use std::marker;
use std::ops;
use std::slice;
use windows_sys::Windows::Win32::CoreAudio as core;
pub struct BufferMut<'a, T> {
pub(super) tag: ste::Tag,
pub(super) render_client: &'a mut core::IAudioRenderClient,
pub(super) data: *mut T,
pub(super) frames: u32,
pub(super) len: usize,
pub(super) in_use: bool,
pub(super) _marker: marker::PhantomData<&'a mut [T]>,
}
impl<'a, T> BufferMut<'a, T> {
pub fn release(mut self) -> Result<(), Error> {
self.tag.ensure_on_thread();
if std::mem::take(&mut self.in_use) {
unsafe {
self.render_client.ReleaseBuffer(self.frames, 0).ok()?;
}
}
Ok(())
}
}
impl<'a, T> Drop for BufferMut<'a, T> {
fn drop(&mut self) {
self.tag.ensure_on_thread();
if std::mem::take(&mut self.in_use) {
unsafe {
self.render_client
.ReleaseBuffer(self.frames, 0)
.ok()
.unwrap();
}
}
}
}
impl<'a, T> ops::Deref for BufferMut<'a, T> {
type Target = [T];
fn deref(&self) -> &Self::Target {
self.tag.ensure_on_thread();
debug_assert!(self.in_use);
unsafe { slice::from_raw_parts(self.data, self.len) }
}
}
impl<'a, T> ops::DerefMut for BufferMut<'a, T> {
fn deref_mut(&mut self) -> &mut Self::Target {
self.tag.ensure_on_thread();
debug_assert!(self.in_use);
unsafe { slice::from_raw_parts_mut(self.data, self.len) }
}
}
unsafe impl<T> Send for BufferMut<'_, T> {}