use soa_rs::{SoaClone, Soars};
use crate::math::Easing;
use crate::notes::long::LongNoteData;
use crate::notes::short::ShortNoteData;
use crate::notes::{GroupId, Interval, NoteGroup, NoteGroups};
use crate::rhythm::{
ClockTime, ScrollSpeedChangeEvent, ScrollSpeedTrack, ScrollSpeedTracks, Tempo,
TempoChangeEvent, TempoTrack, TempoTracks, Time, TrackId,
};
#[derive(Debug, Clone, PartialEq)]
pub(crate) struct TestShort {
pub(crate) time: Time,
pub(crate) gr_id: GroupId,
pub(crate) pos: f32,
}
#[derive(Debug, Clone, PartialEq)]
pub(crate) struct TestLong {
pub(crate) time: Interval<Time>,
pub(crate) gr_id: GroupId,
pub(crate) pos: f32,
}
#[derive(Clone, Copy, Soars, SoaClone)]
pub(crate) struct NoteData(pub(crate) f32);
#[derive(Debug, PartialEq, Clone, Copy, Soars, SoaClone, Default)]
pub(crate) struct NoteRuntime(pub(crate) f32);
impl ShortNoteData for TestShort {
type ValueData = NoteData;
type RuntimeData = NoteRuntime;
fn time(&self) -> Time {
self.time
}
fn group_id(&self) -> GroupId {
self.gr_id
}
fn value_data(&self) -> Self::ValueData {
NoteData(self.pos)
}
fn reconstruct<'a>(
time: Time,
data: <Self::ValueData as soa_rs::Soars>::Ref<'a>,
gr_id: GroupId,
) -> Self {
Self {
time,
gr_id,
pos: *data.0,
}
}
}
impl LongNoteData for TestLong {
type ValueData = NoteData;
type RuntimeData = NoteRuntime;
fn start_time(&self) -> Time {
self.time.start()
}
fn duration(&self) -> Time {
generativity::make_guard!(guard);
let (start, end) = self
.time
.start()
.prove_same_unit(self.time.end(), guard)
.expect("test interval endpoints use the same time unit");
(end - start).as_time()
}
fn group_id(&self) -> GroupId {
self.gr_id
}
fn value_data(&self) -> Self::ValueData {
NoteData(self.pos)
}
fn reconstruct<'a>(
start_time: Time,
duration: Time,
data: <Self::ValueData as soa_rs::Soars>::Ref<'a>,
gr_id: GroupId,
) -> Self {
generativity::make_guard!(guard);
let (start, duration) = start_time
.prove_same_unit(duration, guard)
.expect("test note timing uses the same time unit");
let time = Interval::try_new(start_time, (start + duration).as_time()).unwrap();
Self {
time,
gr_id,
pos: *data.0,
}
}
}
#[derive(Debug, Clone)]
pub(crate) struct TestGroup {
tempo_track_id: TrackId,
scroll_track_id: TrackId,
}
impl NoteGroup for TestGroup {
fn main_group() -> Self {
Self {
tempo_track_id: TrackId::Main,
scroll_track_id: TrackId::Main,
}
}
fn tempo_track_id(&self) -> TrackId {
self.tempo_track_id
}
fn scroll_track_id(&self) -> TrackId {
self.scroll_track_id
}
}
#[derive(Debug, Clone)]
pub(crate) struct World {
pub(crate) named_count: usize,
pub(crate) note_groups: NoteGroups<TestGroup>,
pub(crate) tempo_tracks: TempoTracks,
pub(crate) scroll_tracks: ScrollSpeedTracks,
}
fn test_tempo_track(bpm: f64) -> TempoTrack {
TempoTrack::with_events(vec![TempoChangeEvent {
time: Time::Clock(ClockTime::ZERO),
tempo: Tempo::from_bpm(bpm).unwrap(),
ease: Easing::InConst,
}])
.unwrap()
}
impl World {
pub(crate) fn new(named_count: usize) -> Self {
let tempo_tracks = TempoTracks::with_tracks(
test_tempo_track(60.0),
(0..named_count).map(|i| (i as u64, test_tempo_track(60.0 + 10.0 * i as f64))),
);
let scroll_tracks = ScrollSpeedTracks::with_tracks(
ScrollSpeedTrack::new(TrackId::Main),
(0..named_count).map(|i| {
(
i as u64,
ScrollSpeedTrack::with_events(
TrackId::Named(i as u64),
vec![
ScrollSpeedChangeEvent::new(
Time::Clock(ClockTime::ZERO),
1.0 + i as f64,
Easing::InConst,
)
.unwrap(),
],
&tempo_tracks,
),
)
}),
);
let note_groups = NoteGroups::with_groups(
TestGroup::main_group(),
(0..named_count).map(|i| {
(
i as u64,
TestGroup {
tempo_track_id: TrackId::Named(i as u64),
scroll_track_id: TrackId::Named(i as u64),
},
)
}),
);
Self {
named_count,
note_groups,
tempo_tracks,
scroll_tracks,
}
}
}
pub(crate) fn short_data(pos: f32) -> TestShort {
TestShort {
time: Time::Clock(ClockTime::ZERO),
gr_id: GroupId::Main,
pos,
}
}
pub(crate) fn long_data(pos: f32) -> TestLong {
TestLong {
time: Interval::try_new(
Time::Clock(ClockTime::ZERO),
Time::Clock(ClockTime::from_milis(1000.0).unwrap()),
)
.expect("test endpoints use the same time unit"),
gr_id: GroupId::Main,
pos,
}
}