fmod/lib.rs
1//! fmod-oxide
2//!
3//! Safe rust bindings to the FMOD sound engine.
4//! This crate tries to be as rusty as possible, without comprimising on any APIs.
5//! Certain APIs, such as loading banks from a pointer, are marked as unsafe, but are still available for use.
6//!
7//! Most documentation is copied directly from the FMOD docs, however some information (such as parameter values) are excluded.
8//! Please refer to the FMOD documentation for more usage information.
9//!
10//! Please see the `fmod-sys` crate (or the [`ffi`] re-export) documentation for more information on the raw bindings,
11//! and where to place the FMOD libraries. This crate does not distribute the FMOD libraries or headers!
12//!
13//! # Basic example
14//! ```ignore
15//! // System creation is unsafe and must be performed prior to any other FMOD operations.
16//! let mut builder = unsafe { fmod::studio::SystemBuilder::new() }?;
17//! let system = builder.build()?;
18//!
19//! // Load a bank
20//! let bank = system.load_bank_file("path/to/bank.bank", fmod::studio::LoadBankFlags::NORMAL)?;
21//! // Query all events in the bank
22//! for event in bank.get_event_list().unwrap() {
23//! println!("Event: {}", event.get_path()?);
24//! }
25//!
26//! // Releasing Systems is unsafe because it cannot be called concurrently, and all FMOD objects are rendered invalid.
27//! unsafe { system.release() };
28//! ```
29//!
30//! # Memory management & Copy types
31//!
32//! All FMOD objects are `Copy`, `Clone`, `Send` and `Sync` because it's possible to have multiple references to the same object. (e.g. loading a bank and then retrieving it by its path)
33//! There are a lot of use-cases where you may want to fetch something (like a bank) and never use it again.
34//! Implementing `Drop` to automatically release things would go against that particular use-case, so this crate opts to have manual `release()` methods instead.
35//!
36//! This crate does not currently guard against use-after-frees, although it's something I have planned.
37//!
38//! # String types
39//! `fmod-oxide` aims to be as zero-cost as possible, and as such, it uses UTF-8 C strings from the `lanyard` crate as its string type.
40//! This means that all FMOD functions take a `&Utf8CStr` instead of a `&str` or `&CStr`.
41//! `&Utf8CStr` is pretty cheap to construct (and can even be done statically with the `c!` macro), so this should not be a problem.
42//!
43//! When FMOD returns a string, it will always return a `Utf8CString` (the owned version of `Utf8CStr`) because it's difficult to encode lifetime requirements of FMOD strings.
44//!
45//! This applies to structs like `fmod::studio::AdvancedSettings` which store C strings.
46//! Converting structs like `AdvancedSettings` to their FFI equivalents is done by reference as to not pass ownership of the string to FMOD.
47//!
48//! # Userdata
49//!
50//! Right now this crate stores userdata in a global slotmap alongside its owner, and every so often will remove userdata with invalid owners.
51//! This solution works best with a mark and sweep GC, which Rust does not have. We could somewhat solve this issue by doing this check in `System::update`.
52//! That would make `System::update` expensive- it would have an additional `O(n)` complexity added to it, which goes against the purpose of this crate.
53//!
54//! It's difficult to associate userdata with an individual system in this system though- so we have to clear the slotmap whenever any system is released.
55//! Releasing a system is performed at the end of execution generally so this probably won't be an issue.
56
57#![warn(rust_2018_idioms, clippy::pedantic)]
58#![allow(
59 clippy::missing_errors_doc,
60 missing_docs, // TODO: disable later
61 clippy::wildcard_imports,
62 clippy::module_name_repetitions,
63 clippy::cast_possible_truncation,
64 clippy::cast_possible_wrap,
65 clippy::cast_sign_loss,
66 clippy::must_use_candidate,
67 clippy::missing_panics_doc // TODO: disable later
68)]
69#![forbid(unsafe_op_in_unsafe_fn)]
70#![doc(html_favicon_url = "https://www.fmod.com/assets/fmod-logo.svg")]
71#![doc(html_logo_url = "https://www.fmod.com/assets/fmod-logo.svg")]
72
73pub use lanyard::*;
74
75#[doc(inline)]
76pub use fmod_sys as ffi;
77pub use fmod_sys::{error_code_to_str, Error, Result};
78
79pub mod core;
80#[doc(inline)]
81pub use core::*;
82
83pub mod studio;
84
85#[doc(hidden)]
86#[cfg(feature = "userdata-abstraction")]
87pub mod userdata;
88#[cfg(feature = "userdata-abstraction")]
89pub use userdata::Userdata;
90
91pub const VERSION: u32 = fmod_sys::FMOD_VERSION;
92pub const MAX_CHANNEL_WIDTH: u32 = fmod_sys::FMOD_MAX_CHANNEL_WIDTH;
93pub const MAX_LISTENERS: u32 = fmod_sys::FMOD_MAX_LISTENERS;
94pub const MAX_SYSTEMS: u32 = fmod_sys::FMOD_MAX_SYSTEMS;
95
96// relatively common bound
97pub trait Shareable: Send + Sync + 'static {}
98impl<T> Shareable for T where T: Send + Sync + 'static {}