Merge branch 'rewrite' of https://github.com/MaxOhn/rosu-pp into rewrite

This commit is contained in:
MaxOhn
2024-02-14 15:28:02 +01:00
12 changed files with 185 additions and 206 deletions
+1 -1
View File
@@ -43,7 +43,7 @@ impl DifficultyAttributes {
}
/// Returns a builder for performance calculation.
pub fn pp<'a>(self) -> Performance<'a> {
pub fn performance<'a>(self) -> Performance<'a> {
self.into()
}
}
+4 -4
View File
@@ -275,10 +275,10 @@ impl<A: AttributeProvider> From<A> for Performance<'_> {
fn from(attrs: A) -> Self {
fn inner(attrs: DifficultyAttributes) -> Performance<'static> {
match attrs {
DifficultyAttributes::Osu(attrs) => Performance::Osu(attrs.pp()),
DifficultyAttributes::Taiko(attrs) => Performance::Taiko(attrs.pp()),
DifficultyAttributes::Catch(attrs) => Performance::Catch(attrs.pp()),
DifficultyAttributes::Mania(attrs) => Performance::Mania(attrs.pp()),
DifficultyAttributes::Osu(attrs) => Performance::Osu(attrs.performance()),
DifficultyAttributes::Taiko(attrs) => Performance::Taiko(attrs.performance()),
DifficultyAttributes::Catch(attrs) => Performance::Catch(attrs.performance()),
DifficultyAttributes::Mania(attrs) => Performance::Mania(attrs.performance()),
}
}
+1 -1
View File
@@ -33,7 +33,7 @@ impl CatchDifficultyAttributes {
}
/// Returns a builder for performance calculation.
pub fn pp<'a>(self) -> CatchPerformance<'a> {
pub fn performance<'a>(self) -> CatchPerformance<'a> {
self.into()
}
}
+91 -1
View File
@@ -1,4 +1,94 @@
#![deny(rustdoc::broken_intra_doc_links)]
//! Library to calculate difficulty and performance attributes for all [osu!] gamemodes.
//!
//! ## Description
//!
//! A large part of `rosu-pp` is a port of [osu!lazer]'s difficulty and performance calculation
//! with emphasis on a precise translation to Rust for the most accurate results.
//!
//! Another important factor is the calculation speed. Optimizations and an accurate translation
//! unfortunately don't always go hand-in-hand. Nonetheless, performance improvements are still
//! snuck in wherever possible, providing a significantly faster runtime than the native C# code.
//!
//! TODO: values to compare
//!
//! Additionally, `rosu-pp` allows previous values to be re-used so that they don't need to be
//! calculated again. For example, a beatmap needs to be decoded only once and can then be used
//! for any amount of attribute calculations. Similarly, previous attributes can be re-used for
//! later calculations (with some limitations, see the [example](#usage)).
//!
//! Last commits of the ported code:
//! - [osu!lazer] : `7342fb7f51b34533a42bffda89c3d6c569cc69ce` (2022-10-11)
//! - [osu!tools] : `146d5916937161ef65906aa97f85d367035f3712` (2022-10-08)
//!
//! News posts of the latest gamemode updates:
//! - osu: <https://osu.ppy.sh/home/news/2022-09-30-changes-to-osu-sr-and-pp>
//! - taiko: <https://osu.ppy.sh/home/news/2022-09-28-changes-to-osu-taiko-sr-and-pp>
//! - catch: <https://osu.ppy.sh/home/news/2020-05-14-osucatch-scoring-updates>
//! - mania: <https://osu.ppy.sh/home/news/2022-10-09-changes-to-osu-mania-sr-and-pp>
//!
//! ## Usage
//!
//! ```
//! // Decode the map
//! let map = rosu_pp::Beatmap::from_path("./resources/2785319.osu").unwrap();
//!
//! // Calculate difficulty attributes
//! let diff_attrs = map.difficulty()
//! .mods(8 + 16) // HDHR
//! .calculate();
//!
//! let stars = diff_attrs.stars();
//!
//! // Calculate performance attributes
//! let perf_attrs = map.performance()
//! // To speed up the calculation, we can use the previous attributes.
//! // **Note** that this should only be done if the map, mode, mods,
//! // clock rate, and amount of passed objects stay the same.
//! // Otherwise, the final attributes will be incorrect.
//! .attributes(diff_attrs)
//! .mods(24) // HDHR, must be the same as before
//! .combo(789)
//! .accuracy(99.2)
//! .misses(2)
//! .calculate();
//!
//! let pp = perf_attrs.pp();
//!
//! // Again, we re-use the previous attributes for maximum efficiency.
//! // This time we do it directly instead of through the map.
//! let max_pp = perf_attrs.performance()
//! .mods(24) // Still the same
//! .calculate()
//! .pp();
//!
//! println!("Stars: {stars} | PP: {pp}/{max_pp}");
//! ```
//!
//! ## Gradual calculation
//!
//! TODO
//!
//! ## Features
//!
//! | Flag | Description | Dependencies
//! | --------- | ----------- | ------------
//! | `default` | No features |
//! | `tracing` | Any error encountered during beatmap decoding will be logged through `tracing::error`. If this feature is not enabled, errors will be ignored. | [`tracing`]
//!
//! ## Bindings
//!
//! Using `rosu-pp` from other languages than Rust:
//! - JavaScript: [rosu-pp-js]
//! - Python: [rosu-pp-py]
//!
//! [osu!]: https://osu.ppy.sh/home
//! [osu!lazer]: https://github.com/ppy/osu
//! [osu!tools]: https://github.com/ppy/osu-tools
//! [`tracing`]: https://docs.rs/tracing
//! [rosu-pp-js]: https://github.com/MaxOhn/rosu-pp-js
//! [rosu-pp-py]: https://github.com/MaxOhn/rosu-pp-py
#![deny(rustdoc::broken_intra_doc_links, rustdoc::missing_crate_level_docs)]
#![warn(clippy::missing_const_for_fn, clippy::pedantic)]
#![allow(
clippy::missing_errors_doc,
+1 -1
View File
@@ -36,7 +36,7 @@ impl ManiaDifficultyAttributes {
}
/// Returns a builder for performance calculation.
pub fn pp<'a>(self) -> ManiaPerformance<'a> {
pub fn performance<'a>(self) -> ManiaPerformance<'a> {
self.into()
}
}
+2 -9
View File
@@ -1,10 +1,7 @@
use std::borrow::Cow;
use rosu_map::{
section::{
general::GameMode,
hit_objects::{BorrowedCurve, CurveBuffers},
},
section::{general::GameMode, hit_objects::CurveBuffers},
util::Pos,
};
@@ -107,11 +104,7 @@ fn convert(map: &mut Beatmap) {
last_values.pattern = new_pattern;
}
HitObjectKind::Slider(ref slider) => {
let curve = BorrowedCurve::new(
&slider.control_points,
slider.expected_dist,
&mut curve_bufs,
);
let curve = slider.curve(&mut curve_bufs);
let mut gen = DistanceObjectPatternGenerator::new(
&mut random,
+12
View File
@@ -5,6 +5,8 @@ use rosu_map::{
LATEST_FORMAT_VERSION,
};
use crate::{Performance, Difficulty};
pub use self::{
attributes::{BeatmapAttributes, BeatmapAttributesBuilder, HitWindows},
converted::Converted,
@@ -68,6 +70,16 @@ impl Beatmap {
rosu_map::from_bytes(bytes)
}
/// Create a new difficulty calculator for this [`Beatmap`].
pub fn difficulty(&self) -> Difficulty<'_> {
Difficulty::new(self)
}
/// Create a new performance calculator for this [`Beatmap`].
pub fn performance(&self) -> Performance<'_> {
Performance::new(self)
}
/// Finds the [`TimingPoint`] that is active at the given time.
pub(crate) fn timing_point_at(&self, time: f64) -> Option<&TimingPoint> {
timing_point_at(&self.timing_points, time)
+1 -1
View File
@@ -3,7 +3,7 @@ use std::cmp::Ordering;
use rosu_map::section::hit_objects::{BorrowedCurve, CurveBuffers};
pub use rosu_map::{
section::hit_objects::{hit_samples::HitSoundType, PathControlPoint},
section::hit_objects::{hit_samples::HitSoundType, PathControlPoint, PathType, SplineType},
util::Pos,
};
+1 -1
View File
@@ -43,7 +43,7 @@ impl OsuDifficultyAttributes {
}
/// Returns a builder for performance calculation.
pub fn pp<'a>(self) -> OsuPerformance<'a> {
pub fn performance<'a>(self) -> OsuPerformance<'a> {
self.into()
}
}
+2 -4
View File
@@ -1,7 +1,5 @@
use rosu_map::{
section::hit_objects::{
BorrowedCurve, CurveBuffers, SliderEvent, SliderEventType, SliderEventsIter,
},
section::hit_objects::{CurveBuffers, SliderEvent, SliderEventType, SliderEventsIter},
util::Pos,
};
@@ -183,7 +181,7 @@ impl OsuSlider {
|point| (point.slider_velocity, point.generate_ticks),
);
let path = BorrowedCurve::new(&slider.control_points, slider.expected_dist, curve_bufs);
let path = slider.curve(curve_bufs);
let span_count = slider.span_count() as f64;
+1 -1
View File
@@ -37,7 +37,7 @@ impl TaikoDifficultyAttributes {
}
/// Returns a builder for performance calculation.
pub fn pp<'a>(self) -> TaikoPerformance<'a> {
pub fn performance<'a>(self) -> TaikoPerformance<'a> {
self.into()
}
}