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}