fmod/studio/system/
builder.rs

1// Copyright (c) 2024 Lily Lyons
2//
3// This Source Code Form is subject to the terms of the Mozilla Public
4// License, v. 2.0. If a copy of the MPL was not distributed with this
5// file, You can obtain one at https://mozilla.org/MPL/2.0/.
6
7use std::ffi::{c_int, c_void};
8
9use fmod_sys::*;
10
11use crate::studio::{AdvancedSettings, InitFlags, System};
12
13/// A builder for creating and initializing a [`System`].
14///
15/// Handles setting values that can only be set before initialization for you.
16#[must_use]
17pub struct SystemBuilder {
18    system: *mut FMOD_STUDIO_SYSTEM,
19    core_builder: crate::SystemBuilder,
20}
21
22unsafe impl Send for SystemBuilder {}
23unsafe impl Sync for SystemBuilder {}
24
25impl SystemBuilder {
26    /// Creates a new [`SystemBuilder`].
27    ///
28    /// # Safety
29    ///
30    /// Calling either of this function concurrently with any FMOD Studio API function (including this function) may cause undefined behavior.
31    /// External synchronization must be used if calls to [`SystemBuilder::new`] or [`System::release`] could overlap other FMOD Studio API calls.
32    /// All other FMOD Studio API functions are thread safe and may be called freely from any thread unless otherwise documented.
33    pub unsafe fn new() -> Result<Self> {
34        let mut system = std::ptr::null_mut();
35        unsafe { FMOD_Studio_System_Create(&mut system, FMOD_VERSION).to_result()? };
36
37        let mut core_system = std::ptr::null_mut();
38        unsafe { FMOD_Studio_System_GetCoreSystem(system, &mut core_system).to_result()? };
39
40        Ok(SystemBuilder {
41            system,
42            core_builder: crate::SystemBuilder {
43                system: core_system,
44            },
45        })
46    }
47
48    pub fn settings(&mut self, settings: &AdvancedSettings) -> Result<&mut Self> {
49        let mut settings = settings.into();
50        // this function expects a pointer. maybe this is incorrect?
51        unsafe { FMOD_Studio_System_SetAdvancedSettings(self.system, &mut settings).to_result() }?;
52        Ok(self)
53    }
54
55    pub fn build(
56        self,
57        max_channels: c_int,
58        studio_flags: InitFlags,
59        flags: crate::InitFlags,
60    ) -> Result<System> {
61        unsafe {
62            // we don't need
63            self.build_with_extra_driver_data(
64                max_channels,
65                studio_flags,
66                flags,
67                std::ptr::null_mut(),
68            )
69        }
70    }
71
72    pub fn core_builder(&mut self) -> &mut crate::SystemBuilder {
73        &mut self.core_builder
74    }
75
76    /// # Safety
77    ///
78    /// See the FMOD docs explaining driver data for more safety information.
79    pub unsafe fn build_with_extra_driver_data(
80        self,
81        max_channels: c_int,
82        studio_flags: InitFlags,
83        flags: crate::InitFlags,
84        driver_data: *mut c_void,
85    ) -> Result<System> {
86        unsafe {
87            FMOD_Studio_System_Initialize(
88                self.system,
89                max_channels,
90                studio_flags.bits(),
91                flags.bits(),
92                driver_data,
93            )
94            .to_result()?;
95        }
96        Ok(System { inner: self.system })
97    }
98}