use std::marker::PhantomData;
use super::Channel;
use crate::{bind, mixer::device::MixDevice};
pub struct ChannelGroup<'device> {
group_id: i32,
len: usize,
_phantom: PhantomData<&'device MixDevice<'device>>,
}
impl<'device> ChannelGroup<'device> {
pub fn new(_device: &'device MixDevice<'device>, len: usize) -> Self {
assert!(1 <= len);
let prev_len = unsafe { bind::Mix_AllocateChannels(-1) };
let new_len = prev_len
+ <usize as TryInto<std::os::raw::c_int>>::try_into(len)
.expect("channel length overflow");
let allocated = unsafe { bind::Mix_AllocateChannels(new_len) };
let _ = unsafe { bind::Mix_GroupChannels(prev_len, allocated - 1, prev_len) };
Self {
group_id: prev_len,
len,
_phantom: PhantomData,
}
}
pub fn partition(self, left_len: usize) -> (Self, Self) {
assert!(left_len <= self.len);
self.halt_all();
(
Self {
group_id: self.group_id,
len: left_len,
_phantom: PhantomData,
},
Self {
group_id: left_len as _,
len: self.len - left_len,
_phantom: PhantomData,
},
)
}
#[allow(clippy::unnecessary_cast)]
pub fn first_free(&self) -> Option<Channel> {
let channel = unsafe { bind::Mix_GroupAvailable(self.group_id) as i32 };
(0 <= channel).then(|| Channel(channel, PhantomData))
}
pub fn oldest_playing(&self) -> Option<Channel> {
let oldest = unsafe { bind::Mix_GroupOldest(self.group_id) as _ };
(0 <= oldest).then(|| Channel(oldest, PhantomData))
}
pub fn newest_playing(&self) -> Option<Channel> {
let newest = unsafe { bind::Mix_GroupNewer(self.group_id) as _ };
(0 <= newest).then(|| Channel(newest, PhantomData))
}
pub fn halt_all(&self) {
let _ = unsafe { bind::Mix_HaltGroup(self.group_id) };
}
pub fn fade_out_all(&self, fade_out: u32) -> usize {
unsafe { bind::Mix_FadeOutChannel(self.group_id, fade_out as _) as _ }
}
pub fn len(&self) -> usize {
self.len
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
}