1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/// Timing-related info about this control point.
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct TimingPoint {
    pub time: f64,
    pub beat_len: f64,
}

impl TimingPoint {
    pub const DEFAULT_BEAT_LEN: f64 =
        rosu_map::section::timing_points::TimingPoint::DEFAULT_BEAT_LEN;

    pub fn new(time: f64, beat_len: f64) -> Self {
        Self {
            time,
            beat_len: beat_len.clamp(6.0, 60_000.0),
        }
    }
}

impl Default for TimingPoint {
    fn default() -> Self {
        Self {
            time: 0.0,
            beat_len: Self::DEFAULT_BEAT_LEN,
        }
    }
}

pub fn timing_point_at(points: &[TimingPoint], time: f64) -> Option<&TimingPoint> {
    let i = points
        .binary_search_by(|probe| probe.time.total_cmp(&time))
        .unwrap_or_else(|i| i.saturating_sub(1));

    points.get(i)
}