use crate::{FmodResultExt, Result};
use fmod_sys::*;
use std::ffi::{c_char, c_int, c_uint, c_void};
#[derive(PartialEq, Eq, Debug)]
pub enum MemoryType {
Pool(&'static mut [u8]),
Callback {
alloc: unsafe extern "C" fn(
size: c_uint,
type_: FMOD_MEMORY_TYPE,
sourcestr: *const c_char,
) -> *mut c_void,
realloc: FMOD_MEMORY_REALLOC_CALLBACK,
free: unsafe extern "C" fn(
ptr: *mut c_void,
type_: FMOD_MEMORY_TYPE,
sourcestr: *const c_char,
),
},
}
bitflags::bitflags! {
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct MemoryFlags: FMOD_MEMORY_TYPE {
const NORMAL = FMOD_MEMORY_NORMAL;
const STREAM_FILE = FMOD_MEMORY_STREAM_FILE;
const STREAM_DECODE = FMOD_MEMORY_STREAM_DECODE;
const SAMPLEDATA = FMOD_MEMORY_SAMPLEDATA;
#[deprecated]
const DSP_BUFFER = FMOD_MEMORY_DSP_BUFFER;
const PLUGIN = FMOD_MEMORY_PLUGIN;
const PERSISTENT = FMOD_MEMORY_PERSISTENT;
const ALL = FMOD_MEMORY_ALL;
}
}
impl From<FMOD_MEMORY_TYPE> for MemoryFlags {
fn from(value: FMOD_MEMORY_TYPE) -> Self {
MemoryFlags::from_bits_truncate(value)
}
}
impl From<MemoryFlags> for FMOD_MEMORY_TYPE {
fn from(value: MemoryFlags) -> Self {
value.bits()
}
}
pub unsafe fn initialize(memory_type: MemoryType, flags: MemoryFlags) -> Result<()> {
match memory_type {
MemoryType::Pool(pool) => unsafe {
FMOD_Memory_Initialize(
pool.as_mut_ptr().cast(),
pool.len() as c_int,
None,
None,
None,
flags.into(),
)
.to_result()
},
MemoryType::Callback {
alloc,
realloc,
free,
} => unsafe {
FMOD_Memory_Initialize(
std::ptr::null_mut(),
0,
Some(alloc),
realloc,
Some(free),
flags.into(),
)
.to_result()
},
}
}
pub fn get_stats(blocking: bool) -> Result<(c_int, c_int)> {
let mut current = 0;
let mut max = 0;
unsafe {
FMOD_Memory_GetStats(&raw mut current, &raw mut max, blocking.into()).to_result()?;
}
Ok((current, max))
}