use std::collections::VecDeque;
use gled_protocol::midi::MidiMonitorEvent;
use crate::input::event::InputEvent;
pub(crate) type InputLog = EventLog<InputEvent>;
pub(crate) type MidiLog = EventLog<MidiMonitorEvent>;
pub(crate) type LearnLog = EventLog<[u8; 3]>;
const KEPT: usize = 64;
#[derive(Debug, Clone)]
pub(crate) struct EventLog<T> {
next: u64,
events: VecDeque<(u64, T)>,
}
impl<T> Default for EventLog<T> {
fn default() -> Self {
Self {
next: 0,
events: VecDeque::new(),
}
}
}
impl<T: Clone> EventLog<T> {
pub(crate) fn push(&mut self, event: T) {
self.events.push_back((self.next, event));
self.next += 1;
while self.events.len() > KEPT {
self.events.pop_front();
}
}
pub(crate) fn next(&self) -> u64 {
self.next
}
pub(crate) fn since(&self, from: u64) -> Vec<T> {
self.events
.iter()
.filter(|(number, _)| *number >= from)
.map(|(_, event)| event.clone())
.collect()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::input::key_code::KeyCode;
#[test]
fn keeps_the_newest_events_by_number() {
let mut log = InputLog::default();
for _ in 0..(KEPT + 6) {
log.push(InputEvent::Key(KeyCode::A));
}
log.push(InputEvent::Key(KeyCode::B));
assert_eq!(log.next(), KEPT as u64 + 7);
assert_eq!(log.since(log.next() - 1), vec![InputEvent::Key(KeyCode::B)]);
assert_eq!(log.since(0).len(), KEPT);
}
}