use alloc::vec::Vec;
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
pub struct TimelineMap {
pub entries: Vec<TimelineEntry>,
}
#[derive(Serialize, Deserialize, Debug, Clone, Copy)]
pub struct TimelineEntry {
pub song: u16,
pub order_idx: u32,
pub pattern_idx: u32,
pub row_idx: u32,
pub loop_iter: u16,
pub tick: u32,
pub speed_at_row: u8,
pub bpm_at_row: u16,
}
impl TimelineMap {
pub fn find_entry(
&self,
song: usize,
pattern_idx: usize,
row_idx: usize,
) -> Option<&TimelineEntry> {
self.entries.iter().find(|e| {
e.song as usize == song
&& e.pattern_idx as usize == pattern_idx
&& e.row_idx as usize == row_idx
&& e.loop_iter == 0
})
}
pub fn entry_at_tick(&self, song: usize, tick: u32) -> Option<&TimelineEntry> {
self.entries
.iter()
.find(|e| e.song as usize == song && e.tick == tick && e.loop_iter == 0)
}
pub fn find_order_entry(&self, song: usize, order_idx: usize) -> Option<&TimelineEntry> {
self.entries.iter().find(|e| {
e.song as usize == song && e.order_idx as usize == order_idx && e.loop_iter == 0
})
}
pub fn find_entry_at_order(
&self,
song: usize,
order_idx: usize,
row_idx: usize,
) -> Option<&TimelineEntry> {
self.entries.iter().find(|e| {
e.song as usize == song
&& e.order_idx as usize == order_idx
&& e.row_idx as usize == row_idx
&& e.loop_iter == 0
})
}
pub fn order_count(&self, song: usize) -> usize {
self.entries
.iter()
.filter(|e| e.song as usize == song && e.loop_iter == 0)
.map(|e| e.order_idx)
.max()
.map(|m| m as usize + 1)
.unwrap_or(0)
}
pub fn row_count_in_pattern(&self, pattern_idx: usize) -> usize {
self.entries
.iter()
.filter(|e| e.pattern_idx as usize == pattern_idx)
.map(|e| e.row_idx)
.max()
.map(|m| m as usize + 1)
.unwrap_or(0)
}
}