use crate::rhythm::TrackId;
use std::collections::HashMap;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum GroupId {
Main,
Named(u64),
}
pub trait NoteGroup {
fn main_group() -> Self;
fn tempo_track_id(&self) -> TrackId;
fn scroll_track_id(&self) -> TrackId;
}
#[derive(Debug, Clone)]
pub struct NoteGroups<G> {
main: G,
named: HashMap<u64, G>,
}
impl<G: NoteGroup> NoteGroups<G> {
pub fn new() -> Self {
Self {
named: Default::default(),
main: G::main_group(),
}
}
pub fn with_groups(main: G, groups: impl Iterator<Item = (u64, G)>) -> Self {
let named = groups.into_iter().collect();
Self { named, main }
}
pub fn groups(&self) -> impl Iterator<Item = (GroupId, &G)> {
std::iter::chain(
std::iter::once((GroupId::Main, &self.main)),
self.named.iter().map(|(gid, g)| (GroupId::Named(*gid), g)),
)
}
pub fn add_group(&mut self, id: u64, group: G) {
if self.named.contains_key(&id) {
return;
}
self.named.insert(id, group);
}
pub fn remove_group(&mut self, id: u64) -> Option<G> {
self.named.remove(&id)
}
pub fn insert_or_replace_group(&mut self, id: GroupId, group: G) -> Option<G> {
match id {
GroupId::Named(id) => self.named.insert(id, group),
GroupId::Main => Some(std::mem::replace(&mut self.main, group)),
}
}
pub fn get_group_mut(&mut self, id: GroupId) -> Option<&mut G> {
match id {
GroupId::Named(id) => self.named.get_mut(&id),
GroupId::Main => Some(&mut self.main),
}
}
pub fn get_group(&self, id: GroupId) -> Option<&G> {
match id {
GroupId::Named(id) => self.named.get(&id),
GroupId::Main => Some(&self.main),
}
}
pub fn get_group_or_main_mut(&mut self, id: GroupId) -> &mut G {
match id {
GroupId::Named(id) => self.named.get_mut(&id).unwrap_or(&mut self.main),
GroupId::Main => &mut self.main,
}
}
pub fn get_group_or_main(&self, id: GroupId) -> &G {
match id {
GroupId::Named(id) => self.named.get(&id).unwrap_or(&self.main),
GroupId::Main => &self.main,
}
}
pub fn main_group(&self) -> &G {
&self.main
}
pub fn main_group_mut(&mut self) -> &mut G {
&mut self.main
}
}
impl<G: Default + NoteGroup> Default for NoteGroups<G> {
fn default() -> Self {
Self::new()
}
}