use std::{
ffi::{c_float, c_void},
mem::MaybeUninit,
};
use fmod_sys::*;
use crate::{ReverbProperties, Vector};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[repr(transparent)] pub struct Reverb3D {
pub(crate) inner: *mut FMOD_REVERB3D,
}
unsafe impl Send for Reverb3D {}
unsafe impl Sync for Reverb3D {}
impl From<*mut FMOD_REVERB3D> for Reverb3D {
fn from(value: *mut FMOD_REVERB3D) -> Self {
Reverb3D { inner: value }
}
}
impl From<Reverb3D> for *mut FMOD_REVERB3D {
fn from(value: Reverb3D) -> Self {
value.inner
}
}
impl Reverb3D {
pub fn set_3d_attributes(
&self,
position: Option<Vector>,
min_distance: c_float,
max_distance: c_float,
) -> Result<()> {
let position = position
.as_ref()
.map_or(std::ptr::null(), std::ptr::from_ref)
.cast();
unsafe {
FMOD_Reverb3D_Set3DAttributes(self.inner, position, min_distance, max_distance)
.to_result()
}
}
pub fn get_3d_attributes(&self) -> Result<(Vector, c_float, c_float)> {
let mut position = MaybeUninit::uninit();
let mut min_distance = 0.0;
let mut max_distance = 0.0;
unsafe {
FMOD_Reverb3D_Get3DAttributes(
self.inner,
position.as_mut_ptr(),
&mut min_distance,
&mut max_distance,
)
.to_result()?;
let position = position.assume_init().into();
Ok((position, min_distance, max_distance))
}
}
pub fn set_properties(&self, properties: ReverbProperties) -> Result<()> {
unsafe {
FMOD_Reverb3D_SetProperties(self.inner, std::ptr::from_ref(&properties).cast())
.to_result()
}
}
pub fn get_properties(&self) -> Result<ReverbProperties> {
let mut properties = MaybeUninit::uninit();
unsafe {
FMOD_Reverb3D_GetProperties(self.inner, properties.as_mut_ptr()).to_result()?;
let properties = properties.assume_init().into();
Ok(properties)
}
}
pub fn set_active(&self, active: bool) -> Result<()> {
unsafe { FMOD_Reverb3D_SetActive(self.inner, active.into()).to_result() }
}
pub fn get_active(&self) -> Result<bool> {
let mut active = FMOD_BOOL::FALSE;
unsafe {
FMOD_Reverb3D_GetActive(self.inner, &mut active).to_result()?;
}
Ok(active.into())
}
#[allow(clippy::not_unsafe_ptr_arg_deref)] pub fn set_raw_userdata(&self, userdata: *mut c_void) -> Result<()> {
unsafe { FMOD_Reverb3D_SetUserData(self.inner, userdata).to_result() }
}
pub fn get_raw_userdata(&self) -> Result<*mut c_void> {
let mut userdata = std::ptr::null_mut();
unsafe {
FMOD_Reverb3D_GetUserData(self.inner, &mut userdata).to_result()?;
}
Ok(userdata)
}
pub fn release(&self) -> Result<()> {
#[cfg(feature = "userdata-abstraction")]
let userdata = self.get_raw_userdata()?;
unsafe {
FMOD_Reverb3D_Release(self.inner).to_result()?;
}
#[cfg(feature = "userdata-abstraction")]
if !userdata.is_null() {
crate::userdata::remove_userdata(userdata.into());
self.set_raw_userdata(std::ptr::null_mut())?;
}
Ok(())
}
}
#[cfg(feature = "userdata-abstraction")]
impl Reverb3D {
pub fn set_userdata(&self, userdata: crate::userdata::Userdata) -> Result<()> {
use crate::userdata::{insert_userdata, set_userdata};
let pointer = self.get_raw_userdata()?;
if pointer.is_null() {
let key = insert_userdata(userdata, *self);
self.set_raw_userdata(key.into())?;
} else {
set_userdata(pointer.into(), userdata);
}
Ok(())
}
pub fn get_userdata(&self) -> Result<Option<crate::userdata::Userdata>> {
use crate::userdata::get_userdata;
let pointer = self.get_raw_userdata()?;
Ok(get_userdata(pointer.into()))
}
}