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
+14 -12
View File
@@ -97,27 +97,29 @@ impl ExactSizeIterator for ManiaGradualDifficulty<'_> {
/// Gradually calculate the difficulty attributes of an osu!mania map.
///
/// Check [`ManiaGradualDifficulty`] for more information. This struct does the same
/// but includes an up-front clone 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 ManiaOwnedGradualDifficulty {
hit_objects: Vec<HitObject>,
// Technically only `Beatmap::hit_objects` are required here but storing
// the full map lets us get away with not storing the map in `ManiaOwnedGradualPerformance`.
pub(crate) map: Beatmap,
inner: ManiaGradualDifficultyInner,
}
impl ManiaOwnedGradualDifficulty {
/// Create a new owned difficulty attributes iterator for osu!mania maps.
pub fn new(map: &Beatmap, mods: u32) -> Self {
let map = map.convert_mode(GameMode::Mania);
let is_convert = matches!(map, Cow::Owned(_));
let inner = ManiaGradualDifficultyInner::new(&map, is_convert, mods);
pub fn new(map: Beatmap, mods: u32) -> Self {
let converted_map = map.convert_mode(GameMode::Mania);
let is_convert = matches!(converted_map, Cow::Owned(_));
let inner = ManiaGradualDifficultyInner::new(&converted_map, is_convert, mods);
let hit_objects = match map {
Cow::Owned(map) => map.hit_objects,
Cow::Borrowed(map) => map.hit_objects.clone(),
let map = match converted_map {
Cow::Owned(map) => map,
Cow::Borrowed(_) => map,
};
Self { hit_objects, inner }
Self { map, inner }
}
#[allow(unused)]
@@ -131,7 +133,7 @@ impl Iterator for ManiaOwnedGradualDifficulty {
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.inner.next(&self.hit_objects)
self.inner.next(&self.map.hit_objects)
}
#[inline]
@@ -141,7 +143,7 @@ impl Iterator for ManiaOwnedGradualDifficulty {
#[inline]
fn nth(&mut self, n: usize) -> Option<Self::Item> {
self.inner.nth(n, &self.hit_objects)
self.inner.nth(n, &self.map.hit_objects)
}
}
+53 -1
View File
@@ -2,7 +2,10 @@
use crate::{Beatmap, ManiaPP};
use super::{ManiaGradualDifficulty, ManiaPerformanceAttributes, ManiaScoreState};
use super::{
ManiaGradualDifficulty, ManiaOwnedGradualDifficulty, ManiaPerformanceAttributes,
ManiaScoreState,
};
/// Gradually calculate the performance attributes of an osu!mania map.
///
@@ -124,3 +127,52 @@ impl<'map> ManiaGradualPerformance<'map> {
Some(performance)
}
}
/// Gradually calculate the performance attributes of an osu!mania map.
///
/// Check [`ManiaGradualPerformance`] 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 ManiaOwnedGradualPerformance {
difficulty: ManiaOwnedGradualDifficulty,
mods: u32,
}
impl ManiaOwnedGradualPerformance {
/// Create a new gradual performance calculator for osu!mania maps.
pub fn new(map: Beatmap, mods: u32) -> Self {
let difficulty = ManiaOwnedGradualDifficulty::new(map, mods);
Self { difficulty, mods }
}
/// Process the next hit object and calculate the
/// performance attributes for the resulting score.
pub fn next(&mut self, state: ManiaScoreState) -> Option<ManiaPerformanceAttributes> {
self.nth(state, 0)
}
/// Process all remaining hit objects and calculate the final performance attributes.
pub fn last(&mut self, state: ManiaScoreState) -> Option<ManiaPerformanceAttributes> {
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: ManiaScoreState, n: usize) -> Option<ManiaPerformanceAttributes> {
let difficulty = self.difficulty.nth(n)?;
let performance = ManiaPP::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::{mania_object::ManiaObject, pp::*, score_state::ManiaScoreState};
#[cfg(feature = "gradual")]
pub use self::{
gradual_difficulty::{ManiaGradualDifficulty, ManiaOwnedGradualDifficulty},
gradual_performance::ManiaGradualPerformance,
gradual_performance::{ManiaGradualPerformance, ManiaOwnedGradualPerformance},
};
pub(crate) use self::mania_object::ObjectParameters;