fmod/core/system/
general.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_void;
8
9use fmod_sys::*;
10
11use crate::System;
12
13impl System {
14    /// Mutual exclusion function to lock the FMOD DSP engine (which runs asynchronously in another thread), so that it will not execute.
15    ///
16    /// If the FMOD DSP engine is already executing, this function will block until it has completed.
17    ///
18    /// The function may be used to synchronize DSP network operations carried out by the user.
19    ///
20    /// An example of using this function may be for when the user wants to construct a DSP sub-network, without the DSP engine executing in the background while the sub-network is still under construction.
21    ///
22    /// Once the user no longer needs the DSP engine locked, it must be unlocked with [`System::unlock_dsp`].
23    ///
24    /// Note that the DSP engine should not be locked for a significant amount of time, otherwise inconsistency in the audio output may result. (audio skipping / stuttering).
25    pub fn lock_dsp(&self) -> Result<()> {
26        unsafe { FMOD_System_LockDSP(self.inner).to_result() }
27    }
28
29    // TODO add guard and investigate safety
30    /// Mutual exclusion function to unlock the FMOD DSP engine (which runs asynchronously in another thread) and let it continue executing.
31    ///
32    /// The DSP engine must be locked with [`System::lock_dsp`] before this function is called.
33    pub fn unlock_dsp(&self) -> Result<()> {
34        unsafe { FMOD_System_UnlockDSP(self.inner).to_result() }
35    }
36
37    #[allow(clippy::not_unsafe_ptr_arg_deref)] // fmod doesn't dereference the passed in pointer, and the user dereferencing it is unsafe anyway
38    pub fn set_raw_userdata(&self, userdata: *mut c_void) -> Result<()> {
39        unsafe { FMOD_System_SetUserData(self.inner, userdata).to_result() }
40    }
41
42    pub fn get_raw_userdata(&self) -> Result<*mut c_void> {
43        let mut userdata = std::ptr::null_mut();
44        unsafe {
45            FMOD_System_GetUserData(self.inner, &mut userdata).to_result()?;
46        }
47        Ok(userdata)
48    }
49}
50
51#[cfg(feature = "userdata-abstraction")]
52impl System {
53    pub fn set_userdata(&self, userdata: crate::userdata::Userdata) -> Result<()> {
54        use crate::userdata::{insert_userdata, set_userdata};
55
56        let pointer = self.get_raw_userdata()?;
57        if pointer.is_null() {
58            let key = insert_userdata(userdata, *self);
59            self.set_raw_userdata(key.into())?;
60        } else {
61            set_userdata(pointer.into(), userdata);
62        }
63
64        Ok(())
65    }
66
67    pub fn get_userdata(&self) -> Result<Option<crate::userdata::Userdata>> {
68        use crate::userdata::get_userdata;
69
70        let pointer = self.get_raw_userdata()?;
71        Ok(get_userdata(pointer.into()))
72    }
73}