osu & fruits: refactored ControlPointIter & added unit test

This commit is contained in:
MaxOhn
2021-01-22 15:42:48 +01:00
parent 89d5f7362c
commit adade9a84a
12 changed files with 167 additions and 231 deletions
@@ -1,74 +0,0 @@
use crate::{Beatmap, DifficultyPoint, TimingPoint};
use std::slice::Iter;
macro_rules! next_tuple {
($iter:expr, ($first:ident, $second:ident)) => {
$iter.next().map(|e| (e.$first, e.$second))
};
}
pub(crate) struct ControlPointIter<'p> {
timing_points: Iter<'p, TimingPoint>,
difficulty_points: Iter<'p, DifficultyPoint>,
next_timing: Option<(f32, f32)>,
next_difficulty: Option<(f32, f32)>,
}
impl<'p> ControlPointIter<'p> {
#[inline]
pub(crate) fn new(map: &'p Beatmap) -> Self {
let mut timing_points = map.timing_points.iter();
let mut difficulty_points = map.difficulty_points.iter();
Self {
next_timing: next_tuple!(timing_points, (time, beat_len)),
next_difficulty: next_tuple!(difficulty_points, (time, speed_multiplier)),
timing_points,
difficulty_points,
}
}
}
pub(crate) enum ControlPoint {
Timing { time: f32, beat_len: f32 },
Difficulty { time: f32, speed_mult: f32 },
}
impl ControlPoint {
#[inline]
pub(crate) fn time(&self) -> f32 {
match self {
Self::Timing { time, .. } => *time,
Self::Difficulty { time, .. } => *time,
}
}
}
impl<'p> Iterator for ControlPointIter<'p> {
type Item = ControlPoint;
fn next(&mut self) -> Option<Self::Item> {
match (self.next_timing, self.next_difficulty) {
(Some((time, beat_len)), Some((d, _))) if time <= d => {
self.next_timing = next_tuple!(self.timing_points, (time, beat_len));
Some(ControlPoint::Timing { time, beat_len })
}
(_, Some((time, speed_mult))) => {
self.next_difficulty =
next_tuple!(self.difficulty_points, (time, speed_multiplier));
Some(ControlPoint::Difficulty { time, speed_mult })
}
(Some((time, beat_len)), None) => {
self.next_timing = next_tuple!(self.timing_points, (time, beat_len));
Some(ControlPoint::Timing { time, beat_len })
}
(None, None) => None,
}
}
}
-1
View File
@@ -6,7 +6,6 @@
use super::super::DifficultyAttributes;
mod control_point_iter;
mod difficulty_object;
mod osu_object;
mod skill;
+1 -2
View File
@@ -1,5 +1,4 @@
use super::control_point_iter::{ControlPoint, ControlPointIter};
use crate::Beatmap;
use crate::{Beatmap, ControlPoint, ControlPointIter};
pub(crate) struct SliderState<'p> {
control_points: ControlPointIter<'p>,
@@ -1,67 +0,0 @@
use crate::{Beatmap, DifficultyPoint, TimingPoint};
use std::slice::Iter;
macro_rules! next_tuple {
($iter:expr, ($first:ident, $second:ident)) => {
$iter.next().map(|e| (e.$first, e.$second))
};
}
pub(crate) struct ControlPointIter<'p> {
timing_points: Iter<'p, TimingPoint>,
difficulty_points: Iter<'p, DifficultyPoint>,
next_timing: Option<f32>,
next_difficulty: Option<(f32, f32)>,
}
impl<'p> ControlPointIter<'p> {
#[inline]
pub(crate) fn new(map: &'p Beatmap) -> Self {
let mut timing_points = map.timing_points.iter();
let mut difficulty_points = map.difficulty_points.iter();
Self {
next_timing: timing_points.next().map(|t| t.time),
next_difficulty: next_tuple!(difficulty_points, (time, speed_multiplier)),
timing_points,
difficulty_points,
}
}
}
pub(crate) enum ControlPoint {
Timing { time: f32 },
Difficulty { time: f32, speed_multiplier: f32 },
}
impl<'p> Iterator for ControlPointIter<'p> {
type Item = ControlPoint;
fn next(&mut self) -> Option<Self::Item> {
match (self.next_timing, self.next_difficulty) {
(Some(time), Some((d, _))) if time <= d => {
self.next_timing = self.timing_points.next().map(|t| t.time);
Some(ControlPoint::Timing { time })
}
(_, Some((time, speed_multiplier))) => {
self.next_difficulty =
next_tuple!(self.difficulty_points, (time, speed_multiplier));
Some(ControlPoint::Difficulty {
time,
speed_multiplier,
})
}
(Some(time), _) => {
self.next_timing = self.timing_points.next().map(|t| t.time);
Some(ControlPoint::Timing { time })
}
(None, None) => None,
}
}
}
@@ -6,7 +6,7 @@
use super::super::DifficultyAttributes;
mod control_point_iter;
// mod control_point_iter;
mod difficulty_object;
mod skill;
mod skill_kind;
@@ -1,6 +1,4 @@
use super::control_point_iter::{ControlPoint, ControlPointIter};
use crate::Beatmap;
use crate::{Beatmap, ControlPoint, ControlPointIter};
pub(crate) struct SliderState<'p> {
control_points: ControlPointIter<'p>,
@@ -35,12 +33,9 @@ impl<'p> SliderState<'p> {
self.next_time = time;
self.prev_sv = 1.0;
}
Some(ControlPoint::Difficulty {
time,
speed_multiplier,
}) => {
Some(ControlPoint::Difficulty { time, speed_mult }) => {
self.next_time = time;
self.prev_sv = speed_multiplier;
self.prev_sv = speed_mult;
}
None => break,
}