1use std::{ffi::c_float, mem::MaybeUninit, ptr::NonNull};
8
9use fmod_sys::*;
10use lanyard::Utf8CString;
11
12use crate::Guid;
13use crate::{FmodResultExt, Result};
14
15use super::get_string_out_size;
16
17#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19#[repr(transparent)] pub struct Vca {
21 pub(crate) inner: NonNull<FMOD_STUDIO_VCA>,
22}
23
24#[cfg(not(feature = "thread-unsafe"))]
25unsafe impl Send for Vca {}
26#[cfg(not(feature = "thread-unsafe"))]
27unsafe impl Sync for Vca {}
28
29impl Vca {
30 pub unsafe fn from_ffi(value: *mut FMOD_STUDIO_VCA) -> Self {
38 let inner = NonNull::new(value).unwrap();
39 Vca { inner }
40 }
41
42 pub fn as_ptr(self) -> *mut FMOD_STUDIO_VCA {
44 self.inner.as_ptr()
45 }
46}
47
48impl From<Vca> for *mut FMOD_STUDIO_VCA {
49 fn from(value: Vca) -> Self {
50 value.inner.as_ptr()
51 }
52}
53
54impl Vca {
55 pub fn set_volume(&self, volume: c_float) -> Result<()> {
59 unsafe { FMOD_Studio_VCA_SetVolume(self.inner.as_ptr(), volume).to_result() }
60 }
61
62 pub fn get_volume(&self) -> Result<(c_float, c_float)> {
67 let mut volume = 0.0;
68 let mut final_volume = 0.0;
69 unsafe {
70 FMOD_Studio_VCA_GetVolume(self.inner.as_ptr(), &raw mut volume, &raw mut final_volume)
71 .to_result()?;
72 }
73 Ok((volume, final_volume))
74 }
75}
76
77impl Vca {
78 pub fn get_id(&self) -> Result<Guid> {
80 let mut guid = MaybeUninit::zeroed();
81 unsafe {
82 FMOD_Studio_VCA_GetID(self.inner.as_ptr(), guid.as_mut_ptr()).to_result()?;
83
84 let guid = guid.assume_init().into();
85
86 Ok(guid)
87 }
88 }
89
90 pub fn get_path(&self) -> Result<Utf8CString> {
94 get_string_out_size(|path, size, ret| unsafe {
95 FMOD_Studio_VCA_GetPath(self.inner.as_ptr(), path, size, ret)
96 })
97 }
98
99 pub fn is_valid(&self) -> bool {
101 unsafe { FMOD_Studio_VCA_IsValid(self.inner.as_ptr()).into() }
102 }
103}