fmod/studio/event_description/
instance.rs

1// Copyright (c) 2024 Melody Madeline 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 fmod_sys::*;
8use std::ffi::c_int;
9
10use crate::studio::{EventDescription, EventInstance};
11
12#[cfg(doc)]
13use crate::studio::Bank;
14use crate::{FmodResultExt, Result};
15
16impl EventDescription {
17    /// Creates a playable instance.
18    ///
19    /// When an event instance is created, any required non-streaming sample data is loaded asynchronously.
20    ///
21    /// Use [`EventDescription::get_sample_loading_state`] to check the loading status.
22    ///
23    /// Sample data can be loaded ahead of time with [`EventDescription::load_sample_data`] or [`Bank::load_sample_data`]. See Sample Data Loading for more information.
24    pub fn create_instance(&self) -> Result<EventInstance> {
25        let mut instance = std::ptr::null_mut();
26        unsafe {
27            FMOD_Studio_EventDescription_CreateInstance(self.inner.as_ptr(), &raw mut instance)
28                .to_result()?;
29            Ok(EventInstance::from_ffi(instance))
30        }
31    }
32
33    /// Retrieves the number of instances.
34    pub fn instance_count(&self) -> Result<c_int> {
35        let mut count = 0;
36        unsafe {
37            FMOD_Studio_EventDescription_GetInstanceCount(self.inner.as_ptr(), &raw mut count)
38                .to_result()?;
39        }
40        Ok(count)
41    }
42
43    /// Retrieves a list of the instances.
44    pub fn get_instance_list(&self) -> Result<Vec<EventInstance>> {
45        let expected_count = self.instance_count()?;
46        let mut count = 0;
47        let mut list = vec![std::ptr::null_mut(); expected_count as usize];
48
49        unsafe {
50            FMOD_Studio_EventDescription_GetInstanceList(
51                self.inner.as_ptr(),
52                // eventinstance is repr transparent and has the same layout as *mut FMOD_STUDIO_EVENTINSTANCE, so this cast is ok
53                list.as_mut_ptr(),
54                list.capacity() as c_int,
55                &raw mut count,
56            )
57            .to_result()?;
58
59            debug_assert_eq!(count, expected_count);
60
61            // *mut FMOD_STUDIO_EVENTINSTANCE is transmutable to EventInstance
62            Ok(std::mem::transmute::<
63                Vec<*mut fmod_sys::FMOD_STUDIO_EVENTINSTANCE>,
64                Vec<EventInstance>,
65            >(list))
66        }
67    }
68
69    /// Retrieves a list of the instances.
70    ///
71    /// Fills in the provided slice instead of allocating a [`Vec`], like [`EventDescription::get_instance_list`] does.
72    /// Any instances not filled in are left as [`None`].
73    ///
74    /// Returns how many instances were fetched.
75    pub fn get_instance_list_into(&self, slice: &mut [Option<EventInstance>]) -> Result<c_int> {
76        let mut count = 0;
77
78        unsafe {
79            FMOD_Studio_EventDescription_GetInstanceList(
80                self.inner.as_ptr(),
81                // Because we use NonNull, Option<EventInstance> has the same layout as *mut FMOD_STUDIO_EVENTINSTANCE, so this is ok!
82                slice.as_mut_ptr().cast(),
83                slice.len() as c_int,
84                &raw mut count,
85            )
86            .to_result()?;
87
88            Ok(count)
89        }
90    }
91
92    /// Releases all instances.
93    ///
94    /// This function immediately stops and releases all instances of the event.
95    pub fn release_all_instances(&self) -> Result<()> {
96        unsafe { FMOD_Studio_EventDescription_ReleaseAllInstances(self.inner.as_ptr()).to_result() }
97    }
98}