1use std::{
8 ffi::{c_float, c_void},
9 mem::MaybeUninit,
10};
11
12use fmod_sys::*;
13
14use crate::{ReverbProperties, Vector};
15
16#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
17#[repr(transparent)] pub struct Reverb3D {
19 pub(crate) inner: *mut FMOD_REVERB3D,
20}
21
22unsafe impl Send for Reverb3D {}
23unsafe impl Sync for Reverb3D {}
24
25impl From<*mut FMOD_REVERB3D> for Reverb3D {
26 fn from(value: *mut FMOD_REVERB3D) -> Self {
27 Reverb3D { inner: value }
28 }
29}
30
31impl From<Reverb3D> for *mut FMOD_REVERB3D {
32 fn from(value: Reverb3D) -> Self {
33 value.inner
34 }
35}
36
37impl Reverb3D {
38 pub fn set_3d_attributes(
46 &self,
47 position: Option<Vector>,
48 min_distance: c_float,
49 max_distance: c_float,
50 ) -> Result<()> {
51 let position = position
52 .as_ref()
53 .map_or(std::ptr::null(), std::ptr::from_ref)
54 .cast();
55 unsafe {
56 FMOD_Reverb3D_Set3DAttributes(self.inner, position, min_distance, max_distance)
57 .to_result()
58 }
59 }
60
61 pub fn get_3d_attributes(&self) -> Result<(Vector, c_float, c_float)> {
65 let mut position = MaybeUninit::uninit();
66 let mut min_distance = 0.0;
67 let mut max_distance = 0.0;
68 unsafe {
69 FMOD_Reverb3D_Get3DAttributes(
70 self.inner,
71 position.as_mut_ptr(),
72 &mut min_distance,
73 &mut max_distance,
74 )
75 .to_result()?;
76 let position = position.assume_init().into();
77 Ok((position, min_distance, max_distance))
78 }
79 }
80
81 pub fn set_properties(&self, properties: ReverbProperties) -> Result<()> {
85 unsafe {
86 FMOD_Reverb3D_SetProperties(self.inner, std::ptr::from_ref(&properties).cast())
87 .to_result()
88 }
89 }
90
91 pub fn get_properties(&self) -> Result<ReverbProperties> {
95 let mut properties = MaybeUninit::uninit();
96 unsafe {
97 FMOD_Reverb3D_GetProperties(self.inner, properties.as_mut_ptr()).to_result()?;
98 let properties = properties.assume_init().into();
99 Ok(properties)
100 }
101 }
102
103 pub fn set_active(&self, active: bool) -> Result<()> {
107 unsafe { FMOD_Reverb3D_SetActive(self.inner, active.into()).to_result() }
108 }
109
110 pub fn get_active(&self) -> Result<bool> {
114 let mut active = FMOD_BOOL::FALSE;
115 unsafe {
116 FMOD_Reverb3D_GetActive(self.inner, &mut active).to_result()?;
117 }
118 Ok(active.into())
119 }
120
121 #[allow(clippy::not_unsafe_ptr_arg_deref)] pub fn set_raw_userdata(&self, userdata: *mut c_void) -> Result<()> {
123 unsafe { FMOD_Reverb3D_SetUserData(self.inner, userdata).to_result() }
124 }
125
126 pub fn get_raw_userdata(&self) -> Result<*mut c_void> {
127 let mut userdata = std::ptr::null_mut();
128 unsafe {
129 FMOD_Reverb3D_GetUserData(self.inner, &mut userdata).to_result()?;
130 }
131 Ok(userdata)
132 }
133
134 pub fn release(&self) -> Result<()> {
139 #[cfg(feature = "userdata-abstraction")]
141 let userdata = self.get_raw_userdata()?;
142
143 unsafe {
144 FMOD_Reverb3D_Release(self.inner).to_result()?;
145 }
146
147 #[cfg(feature = "userdata-abstraction")]
149 if !userdata.is_null() {
150 crate::userdata::remove_userdata(userdata.into());
151 self.set_raw_userdata(std::ptr::null_mut())?;
152 }
153
154 Ok(())
155 }
156}
157
158#[cfg(feature = "userdata-abstraction")]
159impl Reverb3D {
160 pub fn set_userdata(&self, userdata: crate::userdata::Userdata) -> Result<()> {
161 use crate::userdata::{insert_userdata, set_userdata};
162
163 let pointer = self.get_raw_userdata()?;
164 if pointer.is_null() {
165 let key = insert_userdata(userdata, *self);
166 self.set_raw_userdata(key.into())?;
167 } else {
168 set_userdata(pointer.into(), userdata);
169 }
170
171 Ok(())
172 }
173
174 pub fn get_userdata(&self) -> Result<Option<crate::userdata::Userdata>> {
175 use crate::userdata::get_userdata;
176
177 let pointer = self.get_raw_userdata()?;
178 Ok(get_userdata(pointer.into()))
179 }
180}