use maudio_sys::ffi as sys;
pub type SoundFlagsRaw = sys::ma_sound_flags;
#[repr(transparent)]
#[derive(Debug, PartialEq, Clone, Copy, Hash, Eq)]
pub struct SoundFlags(SoundFlagsRaw);
impl SoundFlags {
pub const NONE: Self = Self(0);
pub const STREAM: Self = Self(sys::ma_sound_flags_MA_SOUND_FLAG_STREAM);
pub const DECODE: Self = Self(sys::ma_sound_flags_MA_SOUND_FLAG_DECODE);
pub const ASYNC: Self = Self(sys::ma_sound_flags_MA_SOUND_FLAG_ASYNC);
pub const WAIT_INIT: Self = Self(sys::ma_sound_flags_MA_SOUND_FLAG_WAIT_INIT);
pub const UNKNOWN_LENGTH: Self = Self(sys::ma_sound_flags_MA_SOUND_FLAG_UNKNOWN_LENGTH);
pub const LOOPING: Self = Self(sys::ma_sound_flags_MA_SOUND_FLAG_LOOPING);
pub const NO_DEFAULT_ATTACHMENT: Self =
Self(sys::ma_sound_flags_MA_SOUND_FLAG_NO_DEFAULT_ATTACHMENT);
pub const NO_PITCH: Self = Self(sys::ma_sound_flags_MA_SOUND_FLAG_NO_PITCH);
pub const NO_SPATIALIZATION: Self = Self(sys::ma_sound_flags_MA_SOUND_FLAG_NO_SPATIALIZATION);
#[inline]
#[allow(clippy::cast_sign_loss)]
#[allow(clippy::useless_conversion)]
#[allow(clippy::unnecessary_cast)]
pub fn bits(self) -> u32 {
self.0 as u32
}
#[inline]
pub const fn set(&mut self, other: Self, enabled: bool) {
if enabled {
self.0 |= other.0;
} else {
self.0 &= !other.0;
}
}
#[inline]
pub const fn from_bits(bits: u32) -> Self {
Self(bits as SoundFlagsRaw)
}
#[inline]
pub const fn contains(self, other: Self) -> bool {
(self.0 & other.0) == other.0
}
#[inline]
pub const fn intersects(self, other: Self) -> bool {
(self.0 & other.0) != 0
}
#[inline]
pub const fn is_none(self) -> bool {
self.0 == 0
}
#[inline]
pub const fn insert(&mut self, other: Self) {
self.0 |= other.0
}
#[inline]
pub const fn remove(&mut self, other: Self) {
self.0 &= !other.0
}
}
impl core::ops::BitOr for SoundFlags {
type Output = Self;
#[inline]
fn bitor(self, rhs: Self) -> Self {
Self(self.0 | rhs.0)
}
}
impl core::ops::BitOrAssign for SoundFlags {
#[inline]
fn bitor_assign(&mut self, rhs: Self) {
self.0 |= rhs.0;
}
}
impl core::ops::BitAnd for SoundFlags {
type Output = Self;
#[inline]
fn bitand(self, rhs: Self) -> Self {
Self(self.0 & rhs.0)
}
}
impl core::ops::BitAndAssign for SoundFlags {
#[inline]
fn bitand_assign(&mut self, rhs: Self) {
self.0 &= rhs.0;
}
}
impl core::ops::BitXor for SoundFlags {
type Output = Self;
#[inline]
fn bitxor(self, rhs: Self) -> Self {
Self(self.0 ^ rhs.0)
}
}
impl core::ops::Not for SoundFlags {
type Output = Self;
#[inline]
fn not(self) -> Self {
Self(!self.0)
}
}
#[cfg(unix)]
impl From<SoundFlags> for u32 {
#[inline]
fn from(v: SoundFlags) -> u32 {
v.0
}
}
#[cfg(windows)]
impl From<SoundFlags> for i32 {
#[inline]
fn from(v: SoundFlags) -> i32 {
v.0
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn build_sound_flags() {
let mut flag = SoundFlags::NONE;
flag.insert(SoundFlags::ASYNC);
assert!(flag == SoundFlags::ASYNC);
flag.remove(SoundFlags::ASYNC);
assert!(flag == SoundFlags::NONE);
flag.insert(SoundFlags::ASYNC);
flag.insert(SoundFlags::LOOPING);
assert!(flag == (SoundFlags::ASYNC | SoundFlags::LOOPING));
assert!(flag.contains(SoundFlags::ASYNC));
assert!(flag.contains(SoundFlags::LOOPING));
assert!(!flag.contains(SoundFlags::DECODE));
flag.remove(SoundFlags::ASYNC);
assert!(flag == SoundFlags::LOOPING);
}
}