use crate::notes::{Interval, NoteMut, NoteRef};
use crate::rhythm::ClockTime;
impl<Note: super::LongNoteData> super::LongNoteTypeStorage<Note> {
pub fn all_notes_ref(&self) -> impl Iterator<Item = NoteRef<'_, Note>> {
self.time_sorted_groups
.iter()
.flat_map(|group| (0..group.note_id.len()).map(move |index| group.state_at(index)))
}
pub fn all_notes_mut(&mut self, mut f: impl FnMut(NoteMut<'_, Note>)) {
for group_index in 0..self.time_sorted_groups.len() {
for index in 0..self.time_sorted_groups[group_index].note_id.len() {
let id = self.time_sorted_groups[group_index].note_id[index];
self.mutate_at(self.note_id_lookup[&id], &mut f);
}
}
}
pub fn set_note_state(&mut self, id: u64, note_state: Note::RuntimeData) {
let Some(&loc) = self.note_id_lookup.get(&id) else {
return;
};
super::edit::soa_set_element(
&mut self.time_sorted_groups[loc.group_index].runtime_data,
loc.index_in_time_sorted_group,
note_state.clone(),
);
super::edit::soa_set_element(
&mut self.scroll_sorted_groups[loc.group_index].runtime_data,
loc.index_in_scroll_sorted_group,
note_state,
);
}
pub fn query_notes(&self, ids: impl Iterator<Item = u64>) -> impl Iterator<Item = (u64, Note)> {
ids.flat_map(|id| self.note_id_lookup.get(&id))
.map(|&i| self.note_at(i))
}
pub fn query_notes_ref<'a>(
&'a self,
ids: impl Iterator<Item = u64>,
) -> impl Iterator<Item = NoteRef<'a, Note>> {
ids.flat_map(|id| self.note_id_lookup.get(&id))
.map(|&i| self.note_state_at(i))
}
pub fn query_notes_mut(
&mut self,
ids: impl Iterator<Item = u64>,
mut f: impl FnMut(NoteMut<'_, Note>),
) {
for id in ids {
let Some(&i) = self.note_id_lookup.get(&id) else {
continue;
};
self.mutate_at(i, &mut f);
}
}
pub fn notes_overlapping_range(
&self,
range: Interval<ClockTime>,
) -> impl Iterator<Item = (u64, Note)> {
self.range_locations(range).map(|i| self.note_at(i))
}
pub fn notes_ref_overlapping_range<'a>(
&'a self,
range: Interval<ClockTime>,
) -> impl Iterator<Item = NoteRef<'a, Note>> {
self.range_locations(range).map(|i| self.note_state_at(i))
}
pub fn notes_mut_overlapping_range(
&mut self,
range: Interval<ClockTime>,
mut f: impl FnMut(NoteMut<'_, Note>),
) {
let locations: Vec<_> = self.range_locations(range).collect();
for i in locations {
self.mutate_at(i, &mut f);
}
}
fn note_at(&self, i: super::NoteLocation) -> (u64, Note) {
let state = self.note_state_at(i);
(
state.id,
Note::reconstruct(
state.start_time,
state.duration,
state.value_data,
state.group_id,
),
)
}
fn note_state_at(&self, loc: super::NoteLocation) -> NoteRef<'_, Note> {
self.time_sorted_groups[loc.group_index].state_at(loc.index_in_time_sorted_group)
}
fn range_locations(
&self,
range: Interval<ClockTime>,
) -> impl Iterator<Item = super::NoteLocation> + '_ {
self.time_sorted_groups.iter().flat_map(move |group| {
group
.query_time_intersecting(range)
.map(|i| self.note_id_lookup[&group.note_id[i]])
})
}
fn mutate_at(&mut self, loc: super::NoteLocation, f: &mut impl FnMut(NoteMut<'_, Note>)) {
let group = &mut self.time_sorted_groups[loc.group_index];
let i = loc.index_in_time_sorted_group;
f(group.state_mut_at(i));
let runtime = group.runtime_data.swap_remove(i);
super::edit::soa_set_element(
&mut self.scroll_sorted_groups[loc.group_index].runtime_data,
loc.index_in_scroll_sorted_group,
runtime.clone(),
);
group.runtime_data.push(runtime);
let last = group.runtime_data.len() - 1;
group.runtime_data.swap(i, last);
}
}
impl<Note: super::LongNoteData> super::TimeIndexedLongNoteGroup<Note> {
fn state_at(&self, i: usize) -> NoteRef<'_, Note> {
let id = self.note_id[i];
let start_time = self.start_time[i];
let duration = self.duration[i];
let clock_time = self.clock_time[i];
let value_data = self.value_data.get(i).expect("index should be valid");
let runtime_data = self.runtime_data.get(i).expect("index should be valid");
let group_id = self.group_id.clone();
NoteRef {
id,
start_time,
duration,
clock_time,
group_id,
value_data,
runtime_data,
}
}
fn state_mut_at(&mut self, i: usize) -> NoteMut<'_, Note> {
let id = self.note_id[i];
let start_time = self.start_time[i];
let duration = self.duration[i];
let clock_time = self.clock_time[i];
let group_id = self.group_id.clone();
let value_data = self.value_data.get(i).expect("index should be valid");
let runtime_data = self.runtime_data.get_mut(i).expect("index should be valid");
NoteMut {
id,
start_time,
duration,
clock_time,
group_id,
value_data,
runtime_data,
}
}
}