use super::{Envelope, EnvelopeIteratorItem};
use crate::event::event_queue::{AlwaysRemoveOld, EventQueue};
use crate::event::Timed;
pub struct StairCaseEnvelopeIterator<'a, T>
where
T: Copy,
{
envelope: &'a StairCaseEnvelope<T>,
index: usize,
ttl: usize,
current_value: T,
}
impl<'a, T> StairCaseEnvelopeIterator<'a, T>
where
T: Copy + 'a,
{
fn new(envelope: &'a StairCaseEnvelope<T>) -> Self {
Self {
envelope,
index: 0,
ttl: envelope
.event_queue
.first()
.map(|x| x.time_in_frames as usize)
.unwrap_or(usize::max_value()),
current_value: envelope.initial_value,
}
}
}
impl<'a, T> Iterator for StairCaseEnvelopeIterator<'a, T>
where
T: Copy + 'a,
{
type Item = EnvelopeIteratorItem<T>;
fn next(&mut self) -> Option<Self::Item> {
let has_updated;
if self.ttl == 0 {
has_updated = true;
self.current_value = self.envelope.event_queue[self.index].event;
self.index += 1;
self.ttl = if self.index < self.envelope.event_queue.len() {
(self.envelope.event_queue[self.index].time_in_frames
- self.envelope.event_queue[self.index - 1].time_in_frames)
as usize
} else {
usize::max_value()
};
} else {
has_updated = false;
}
self.ttl -= 1;
Some(EnvelopeIteratorItem {
item: self.current_value,
has_updated,
})
}
}
#[test]
fn staircase_envelope_iterator_next_called_with_empty_staircase_initial_value_returned() {
let se = StairCaseEnvelope {
initial_value: 4,
event_queue: EventQueue::from_vec(vec![]),
};
let mut iterator = se.iter();
assert_eq!(iterator.next().map(|x| x.item), Some(4));
}
#[test]
fn staircase_envelope_iterator_next_called_with_nonempty_staircase_initial_value_returned() {
let se = StairCaseEnvelope {
initial_value: 1,
event_queue: EventQueue::from_vec(vec![
Timed::new(2, 4),
Timed::new(3, 9),
Timed::new(5, 25),
]),
};
let iterator = se.iter();
assert_eq!(
iterator.take(7).map(|x| x.item).collect::<Vec<_>>(),
vec![1, 1, 4, 9, 9, 25, 25]
);
}
pub struct StairCaseEnvelope<T>
where
T: Copy,
{
initial_value: T,
event_queue: EventQueue<T>,
}
impl<'a, T> Envelope<'a, T> for StairCaseEnvelope<T>
where
T: Copy + 'a,
{
type Iter = StairCaseEnvelopeIterator<'a, T>;
type EventType = Timed<T>;
fn iter(&'a self) -> Self::Iter {
StairCaseEnvelopeIterator::new(self)
}
fn insert_event(&mut self, new_event: Timed<T>) {
self.event_queue.queue_event(new_event, AlwaysRemoveOld);
}
fn forget_past(&mut self, number_of_frames_to_forget: u32) {
if let Some(ref event) = self.event_queue.get_last_before(number_of_frames_to_forget) {
self.initial_value = event.event;
}
self.event_queue.forget_before(number_of_frames_to_forget);
self.event_queue.shift_time(number_of_frames_to_forget);
}
}