holy shit im actually unit testing

main
aprzn 2 years ago
parent 4f3f94e671
commit a513117cc0

10
Cargo.lock generated

@ -1695,6 +1695,15 @@ version = "1.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66" checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66"
[[package]]
name = "ordered-float"
version = "3.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d84eb1409416d254e4a9c8fa56cc24701755025b458f0fcd8e59e1f5f40c23bf"
dependencies = [
"num-traits",
]
[[package]] [[package]]
name = "owned_ttf_parser" name = "owned_ttf_parser"
version = "0.18.1" version = "0.18.1"
@ -1761,6 +1770,7 @@ dependencies = [
"flate2", "flate2",
"gd_plist", "gd_plist",
"home", "home",
"ordered-float",
"rodio", "rodio",
] ]

@ -13,3 +13,4 @@ base64 = {version = "0.21.0"}
flate2 = {version = "1.0.25"} flate2 = {version = "1.0.25"}
gd_plist = {git = "https://github.com/Syudagye/gd-plist.git", version = "1.4.0"} gd_plist = {git = "https://github.com/Syudagye/gd-plist.git", version = "1.4.0"}
chrono = {version = "0.4.23"} chrono = {version = "0.4.23"}
ordered-float = {version = "3.4.0"}

@ -3,16 +3,21 @@
use chrono::Duration; use chrono::Duration;
use std::collections::BTreeMap; use std::collections::BTreeMap;
use ordered_float::OrderedFloat as Float;
pub type BeatPosition = Float<f32>;
/// Like BPM, but not necessarily represented in terms of minutes /// Like BPM, but not necessarily represented in terms of minutes
/// Only BPM jumps for now; no smooth accel/decel /// Only BPM jumps for now; no smooth accel/decel
pub struct BeatRate { pub struct BeatRate {
initial: StaticBeatRate, initial: StaticBeatRate,
changes: BTreeMap<Duration, StaticBeatRate>, changes: BTreeMap<BeatPosition, StaticBeatRate>,
} }
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)]
pub struct StaticBeatRate(Duration); pub struct StaticBeatRate(Duration);
impl StaticBeatRate { impl StaticBeatRate {
pub fn from_bpm(bpm: f32) -> Self { pub fn from_bpm(bpm: f32) -> Self {
Self(Duration::microseconds(60_000_000 / bpm as i64)) Self(Duration::microseconds(60_000_000 / bpm as i64))
@ -27,3 +32,55 @@ impl From<StaticBeatRate> for BeatRate {
} }
} }
} }
impl BeatRate {
pub fn at_beat(&self, pos: BeatPosition) -> StaticBeatRate {
match self.changes.first_key_value() {
Some((first_change, _)) => {
if &pos < first_change {
self.initial
} else {
*self.changes.iter().rev().find(|&el| el.0 <= &pos).unwrap().1
}
},
None => self.initial,
}
}
pub fn add_change(&mut self, new_pos: BeatPosition, new_rate: StaticBeatRate) {
self.changes.insert(new_pos, new_rate);
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn rate_when_no_changes() {
let rate: BeatRate = StaticBeatRate::from_bpm(100.0).into();
assert_eq!(rate.at_beat(5.0.into()), StaticBeatRate::from_bpm(100.0));
}
#[test]
fn rate_before_changes() {
let mut rate: BeatRate = StaticBeatRate::from_bpm(100.0).into();
rate.add_change(5.0.into(), StaticBeatRate::from_bpm(120.0));
assert_eq!(rate.at_beat(3.0.into()), StaticBeatRate::from_bpm(100.0));
}
#[test]
fn rate_after_change() {
let mut rate: BeatRate = StaticBeatRate::from_bpm(100.0).into();
rate.add_change(5.0.into(), StaticBeatRate::from_bpm(120.0));
rate.add_change(10.0.into(), StaticBeatRate::from_bpm(140.0));
assert_eq!(rate.at_beat(6.0.into()), StaticBeatRate::from_bpm(120.0));
}
#[test]
fn rate_at_change() {
let mut rate: BeatRate = StaticBeatRate::from_bpm(100.0).into();
rate.add_change(5.0.into(), StaticBeatRate::from_bpm(120.0));
rate.add_change(10.0.into(), StaticBeatRate::from_bpm(140.0));
assert_eq!(rate.at_beat(5.0.into()), StaticBeatRate::from_bpm(120.0));
}
}

Loading…
Cancel
Save