use super::midi::Event;
use std::boxed::Box;
const MIDI_QUEUE_SIZE: usize = 4096;
const MIDI_QUEUE_MASK: usize = 0xfff;
#[derive(Debug)]
pub struct MidiQueue {
items: Box<[Option<Event>; MIDI_QUEUE_SIZE]>,
given: usize,
taken: usize,
}
impl MidiQueue {
pub fn new() -> MidiQueue {
const INIT: Option<Event> = None;
MidiQueue {
items: Box::new([INIT; MIDI_QUEUE_SIZE]),
given: 0,
taken: 0,
}
}
pub fn push(&mut self, value: Event) -> bool {
let (given, taken) = (self.given, self.taken);
if given.wrapping_sub(taken) >= MIDI_QUEUE_SIZE {
return false;
}
let slot = given & MIDI_QUEUE_MASK;
self.items[slot] = Some(value);
self.given = given.wrapping_add(1);
true
}
pub fn peek(&self) -> Option<&Event> {
let (given, taken) = (self.given, self.taken);
if given == taken {
return None;
}
let slot = taken & MIDI_QUEUE_MASK;
self.items[slot].as_ref()
}
pub fn pop(&mut self) -> Option<Event> {
let (given, taken) = (self.given, self.taken);
if given == taken {
return None;
}
let slot = taken & MIDI_QUEUE_MASK;
let value = self.items[slot].take();
self.taken = taken.wrapping_add(1);
value
}
}