fmod/studio/system/
callback.rs1use fmod_sys::*;
8use std::ffi::c_void;
9
10use crate::{FmodResultExt, Result};
11use crate::{
12 panic_wrapper,
13 studio::{Bank, System, SystemCallbackMask},
14};
15
16#[allow(unused_variables)]
22pub trait SystemCallback {
23 fn preupdate(system: System, userdata: *mut c_void) -> Result<()> {
25 Ok(())
26 }
27
28 fn postupdate(system: System, userdata: *mut c_void) -> Result<()> {
30 Ok(())
31 }
32
33 fn bank_unload(system: System, bank: Bank, userdata: *mut c_void) -> Result<()> {
35 Ok(())
36 }
37
38 fn liveupdate_connected(system: System, userdata: *mut c_void) -> Result<()> {
40 Ok(())
41 }
42
43 fn liveupdate_disconnected(system: System, userdata: *mut c_void) -> Result<()> {
45 Ok(())
46 }
47}
48
49unsafe extern "C" fn callback_impl<C: SystemCallback>(
50 system: *mut FMOD_STUDIO_SYSTEM,
51 kind: FMOD_SYSTEM_CALLBACK_TYPE,
52 command_data: *mut c_void,
53 userdata: *mut c_void,
54) -> FMOD_RESULT {
55 panic_wrapper(|| {
56 let system = unsafe { System::from_ffi(system) };
57
58 let result = match kind {
59 FMOD_STUDIO_SYSTEM_CALLBACK_PREUPDATE => C::preupdate(system, userdata),
60 FMOD_STUDIO_SYSTEM_CALLBACK_POSTUPDATE => C::postupdate(system, userdata),
61 FMOD_STUDIO_SYSTEM_CALLBACK_BANK_UNLOAD => {
62 let bank = unsafe { Bank::from_ffi(command_data.cast()) };
63 C::bank_unload(system, bank, userdata)
64 }
65 FMOD_STUDIO_SYSTEM_CALLBACK_LIVEUPDATE_CONNECTED => {
66 C::liveupdate_connected(system, userdata)
67 }
68 FMOD_STUDIO_SYSTEM_CALLBACK_LIVEUPDATE_DISCONNECTED => {
69 C::liveupdate_disconnected(system, userdata)
70 }
71 _ => {
72 eprintln!("warning: unknown event callback type {kind}");
73 return FMOD_RESULT::FMOD_OK;
74 }
75 };
76 FMOD_RESULT::from_result(result)
77 })
78}
79
80impl System {
81 #[allow(clippy::not_unsafe_ptr_arg_deref)] pub fn set_userdata(&self, userdata: *mut c_void) -> Result<()> {
84 unsafe { FMOD_Studio_System_SetUserData(self.inner.as_ptr(), userdata).to_result() }
85 }
86
87 pub fn get_userdata(&self) -> Result<*mut c_void> {
89 let mut userdata = std::ptr::null_mut();
90 unsafe {
91 FMOD_Studio_System_GetUserData(self.inner.as_ptr(), &raw mut userdata).to_result()?;
92 }
93 Ok(userdata)
94 }
95
96 pub fn set_callback<C: SystemCallback>(&self, mask: SystemCallbackMask) -> Result<()> {
98 unsafe {
99 FMOD_Studio_System_SetCallback(
100 self.inner.as_ptr(),
101 Some(callback_impl::<C>),
102 mask.into(),
103 )
104 .to_result()
105 }
106 }
107}