use std::ffi::{c_int, c_void};
use fmod_sys::*;
use crate::studio::{AdvancedSettings, InitFlags, System};
use crate::{FmodResultExt, Result};
#[must_use]
#[derive(Debug)]
pub struct SystemBuilder {
system: *mut FMOD_STUDIO_SYSTEM,
core_builder: crate::SystemBuilder,
sync_update: bool,
}
#[cfg(not(feature = "thread-unsafe"))]
unsafe impl Send for SystemBuilder {}
#[cfg(not(feature = "thread-unsafe"))]
unsafe impl Sync for SystemBuilder {}
impl SystemBuilder {
pub unsafe fn new() -> Result<Self> {
let mut system = std::ptr::null_mut();
unsafe { FMOD_Studio_System_Create(&raw mut system, FMOD_VERSION).to_result()? };
let mut core_system = std::ptr::null_mut();
unsafe { FMOD_Studio_System_GetCoreSystem(system, &raw mut core_system).to_result()? };
Ok(SystemBuilder {
system,
core_builder: crate::SystemBuilder {
system: core_system,
thread_unsafe: false,
},
sync_update: false,
})
}
#[cfg(not(feature = "thread-unsafe"))]
pub unsafe fn synchronous_update(&mut self) {
self.sync_update = true;
}
#[cfg(feature = "thread-unsafe")]
pub fn synchronous_update(&mut self) {
self.sync_update = true;
}
pub fn settings(&mut self, settings: &AdvancedSettings) -> Result<&mut Self> {
let mut settings = settings.into();
unsafe {
FMOD_Studio_System_SetAdvancedSettings(self.system, &raw mut settings).to_result()
}?;
Ok(self)
}
pub fn build(
self,
max_channels: c_int,
studio_flags: InitFlags,
flags: crate::InitFlags,
) -> Result<System> {
unsafe {
self.build_with_extra_driver_data(
max_channels,
studio_flags,
flags,
std::ptr::null_mut(),
)
}
}
pub fn core_builder(&mut self) -> &mut crate::SystemBuilder {
&mut self.core_builder
}
pub unsafe fn build_with_extra_driver_data(
self,
max_channels: c_int,
mut studio_flags: InitFlags,
flags: crate::InitFlags,
driver_data: *mut c_void,
) -> Result<System> {
if self.sync_update {
studio_flags.insert(InitFlags::SYNCHRONOUS_UPDATE);
} else {
#[cfg(not(feature = "thread-unsafe"))]
studio_flags.remove(InitFlags::SYNCHRONOUS_UPDATE);
}
unsafe {
FMOD_Studio_System_Initialize(
self.system,
max_channels,
studio_flags.bits(),
flags.bits(),
driver_data,
)
.to_result()?;
Ok(System::from_ffi(self.system))
}
}
}