feat: added owned gradual performance calcs

This commit is contained in:
MaxOhn
2023-11-09 20:18:42 +01:00
parent e70cec0c0d
commit 3b93ec1cea
10 changed files with 246 additions and 22 deletions
+2 -3
View File
@@ -79,11 +79,11 @@ impl Iterator for CatchGradualDifficulty<'_> {
/// Gradually calculate the difficulty attributes of an osu!catch map.
///
/// Check [`CatchGradualDifficulty`] for more information. This struct does the same
/// but includes an up-front allocation to avoid being bound to a lifetime.
/// but takes ownership of [`Beatmap`] to avoid being bound to a lifetime.
#[cfg_attr(docsrs, doc(cfg(feature = "gradual")))]
#[derive(Clone, Debug)]
pub struct CatchOwnedGradualDifficulty {
map: Box<Beatmap>,
pub(crate) map: Beatmap,
inner: CatchGradualDifficultyInner,
}
@@ -91,7 +91,6 @@ impl CatchOwnedGradualDifficulty {
/// Create a new difficulty attributes iterator for osu!catch maps.
pub fn new(map: Beatmap, mods: u32) -> Self {
let inner = CatchGradualDifficultyInner::new(&map, mods);
let map = Box::new(map);
Self { map, inner }
}
+56 -1
View File
@@ -1,6 +1,9 @@
use crate::{Beatmap, CatchPP};
use super::{CatchGradualDifficulty, CatchPerformanceAttributes, CatchScoreState};
use super::{
CatchGradualDifficulty, CatchOwnedGradualDifficulty, CatchPerformanceAttributes,
CatchScoreState,
};
/// Gradually calculate the performance attributes of an osu!catch map.
///
@@ -144,3 +147,55 @@ impl<'map> CatchGradualPerformance<'map> {
Some(performance)
}
}
/// Gradually calculate the performance attributes of an osu!catch map.
///
/// Check [`CatchGradualPerformance`] for more information. This struct does the same
/// but takes ownership of [`Beatmap`] to avoid being bound to a lifetime.
#[cfg_attr(docsrs, doc(cfg(feature = "gradual")))]
#[derive(Clone, Debug)]
pub struct CatchOwnedGradualPerformance {
difficulty: CatchOwnedGradualDifficulty,
mods: u32,
}
impl CatchOwnedGradualPerformance {
/// Create a new gradual performance calculator for osu!standard maps.
pub fn new(map: Beatmap, mods: u32) -> Self {
let difficulty = CatchOwnedGradualDifficulty::new(map, mods);
Self { difficulty, mods }
}
/// Process the next hit object and calculate the
/// performance attributes for the resulting score state.
///
/// Note that neither hits nor misses of tiny droplets require
/// to be processed. Only fruits and droplets do.
pub fn next(&mut self, state: CatchScoreState) -> Option<CatchPerformanceAttributes> {
self.nth(state, 0)
}
/// Process all remaining hit objects and calculate the final performance attributes.
pub fn last(&mut self, state: CatchScoreState) -> Option<CatchPerformanceAttributes> {
self.nth(state, usize::MAX)
}
/// Process everything up the the next `n`th hit object and calculate the performance
/// attributes for the resulting score state.
///
/// Note that the count is zero-indexed, so `n=0` will process 1 object, `n=1` will process 2,
/// and so on.
pub fn nth(&mut self, state: CatchScoreState, n: usize) -> Option<CatchPerformanceAttributes> {
let difficulty = self.difficulty.by_ref().take(n.saturating_add(1)).last()?;
let performance = CatchPP::new(&self.difficulty.map)
.mods(self.mods)
.attributes(difficulty)
.state(state)
.passed_objects(self.difficulty.idx())
.calculate();
Some(performance)
}
}
+1 -1
View File
@@ -18,7 +18,7 @@ pub use self::{catch_object::CatchObject, pp::*, score_state::CatchScoreState};
#[cfg(feature = "gradual")]
pub use self::{
gradual_difficulty::{CatchGradualDifficulty, CatchOwnedGradualDifficulty},
gradual_performance::CatchGradualPerformance,
gradual_performance::{CatchGradualPerformance, CatchOwnedGradualPerformance},
};
pub(crate) use self::fruit_or_juice::{FruitOrJuice, FruitParams};