added a bunch of documentation
This commit is contained in:
@@ -3,10 +3,15 @@ use crate::Mods;
|
||||
/// Summary struct for a [`Beatmap`](crate::Beatmap)'s attributes.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct BeatmapAttributes {
|
||||
/// The approach rate.
|
||||
pub ar: f64,
|
||||
/// The overall difficulty.
|
||||
pub od: f64,
|
||||
/// The circle size.
|
||||
pub cs: f64,
|
||||
/// The health drain rate
|
||||
pub hp: f64,
|
||||
/// The clock rate with respect to mods.
|
||||
pub clock_rate: f64,
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,9 @@ use std::cmp::Ordering;
|
||||
/// New rhythm speed change.
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
pub struct TimingPoint {
|
||||
/// The beat length for this timing section
|
||||
pub beat_len: f64,
|
||||
/// The start time of this timing section
|
||||
pub time: f64,
|
||||
}
|
||||
|
||||
@@ -16,7 +18,9 @@ impl PartialOrd for TimingPoint {
|
||||
/// [`TimingPoint`](crate::parse::TimingPoint) that depends on a previous one.
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
pub struct DifficultyPoint {
|
||||
/// The start time for the current speed multiplier
|
||||
pub time: f64,
|
||||
/// The speed multiplier until the next timing point
|
||||
pub speed_multiplier: f64,
|
||||
}
|
||||
|
||||
|
||||
@@ -20,17 +20,29 @@ pub type ParseResult<T> = Result<T, ParseError>;
|
||||
#[derive(Debug)]
|
||||
#[allow(clippy::upper_case_acronyms)]
|
||||
pub enum ParseError {
|
||||
/// Some IO operation failed.
|
||||
IOError(IOError),
|
||||
/// The initial data of an `.osu` file was incorrect.
|
||||
IncorrectFileHeader,
|
||||
/// Line in `.osu` was unexpectedly not of the form `key:value`.
|
||||
BadLine,
|
||||
/// Line in `.osu` that contains a slider was not in the proper format.
|
||||
InvalidCurvePoints,
|
||||
/// Expected an integer, got something else.
|
||||
InvalidInteger,
|
||||
/// Expected a decimal number, got something else.
|
||||
InvalidFloatingPoint,
|
||||
/// Failed to parse game mode.
|
||||
InvalidMode,
|
||||
/// Failed to parse the path type of a slider.
|
||||
InvalidPathType,
|
||||
/// Failed to parse timing point.
|
||||
InvalidTimingSignature,
|
||||
/// Expected an additional field.
|
||||
MissingField(&'static str),
|
||||
/// Reject maps with too many repeat points.
|
||||
TooManyRepeats,
|
||||
/// Failed to recognized specified type for hitobjects.
|
||||
UnknownHitObjectKind,
|
||||
|
||||
#[cfg(not(all(
|
||||
@@ -39,6 +51,7 @@ pub enum ParseError {
|
||||
feature = "fruits",
|
||||
feature = "mania"
|
||||
)))]
|
||||
/// Tried to parse a map with a game mode who's feature was not enabled
|
||||
UnincludedMode(GameMode),
|
||||
}
|
||||
|
||||
|
||||
@@ -6,13 +6,18 @@ use std::cmp::Ordering;
|
||||
/// Each mode will handle them differently.
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct HitObject {
|
||||
/// The position of the object.
|
||||
pub pos: Pos2,
|
||||
/// The start time of the object.
|
||||
pub start_time: f64,
|
||||
/// The type of the object.
|
||||
pub kind: HitObjectKind,
|
||||
/// The hitsound of the object. Used as color in osu!taiko.
|
||||
pub sound: u8,
|
||||
}
|
||||
|
||||
impl HitObject {
|
||||
/// The end time of the object.
|
||||
#[inline]
|
||||
pub fn end_time(&self) -> f64 {
|
||||
match &self.kind {
|
||||
@@ -24,16 +29,19 @@ impl HitObject {
|
||||
}
|
||||
}
|
||||
|
||||
/// If the object is a circle.
|
||||
#[inline]
|
||||
pub fn is_circle(&self) -> bool {
|
||||
matches!(self.kind, HitObjectKind::Circle { .. })
|
||||
}
|
||||
|
||||
/// If the object is a slider.
|
||||
#[inline]
|
||||
pub fn is_slider(&self) -> bool {
|
||||
matches!(self.kind, HitObjectKind::Slider { .. })
|
||||
}
|
||||
|
||||
/// If the object is a spinner.
|
||||
#[inline]
|
||||
pub fn is_spinner(&self) -> bool {
|
||||
matches!(self.kind, HitObjectKind::Spinner { .. })
|
||||
@@ -41,6 +49,7 @@ impl HitObject {
|
||||
}
|
||||
|
||||
impl PartialOrd for HitObject {
|
||||
#[inline]
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||
self.start_time.partial_cmp(&other.start_time)
|
||||
}
|
||||
@@ -49,23 +58,36 @@ impl PartialOrd for HitObject {
|
||||
/// Further data related to specific object types.
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum HitObjectKind {
|
||||
/// A circle object.
|
||||
Circle,
|
||||
#[cfg(feature = "sliders")]
|
||||
/// A full slider object.
|
||||
Slider {
|
||||
/// Total length of the slider in pixels.
|
||||
pixel_len: f64,
|
||||
/// The amount of repeat points of the slider.
|
||||
repeats: usize,
|
||||
/// The control points of the slider.
|
||||
control_points: Vec<super::PathControlPoint>,
|
||||
},
|
||||
#[cfg(not(feature = "sliders"))]
|
||||
/// A partial slider object.
|
||||
Slider {
|
||||
/// Total length of the slider in pixels.
|
||||
pixel_len: f64,
|
||||
/// The amount of spans of the slider.
|
||||
span_count: usize,
|
||||
/// The position of the last control point.
|
||||
last_control_point: Pos2,
|
||||
},
|
||||
/// A spinner object.
|
||||
Spinner {
|
||||
/// The end time of the spinner.
|
||||
end_time: f64,
|
||||
},
|
||||
/// A hold note object for osu!mania.
|
||||
Hold {
|
||||
/// The end time of the hold object.
|
||||
end_time: f64,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
/// Abstract type to define hitsounds.
|
||||
#[allow(missing_docs)]
|
||||
pub trait HitSound {
|
||||
const HITSOUND_WHISTLE: u8 = 1 << 1;
|
||||
const HITSOUND_FINISH: u8 = 1 << 2;
|
||||
|
||||
@@ -751,9 +751,13 @@ macro_rules! from_path {
|
||||
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
|
||||
#[allow(clippy::upper_case_acronyms)]
|
||||
pub enum GameMode {
|
||||
/// osu!standard
|
||||
STD = 0,
|
||||
/// osu!taiko
|
||||
TKO = 1,
|
||||
/// osu!ctb
|
||||
CTB = 2,
|
||||
/// osu!mania
|
||||
MNA = 3,
|
||||
}
|
||||
|
||||
@@ -768,28 +772,44 @@ impl Default for GameMode {
|
||||
/// for difficulty and pp calculation
|
||||
#[derive(Clone, Default, Debug)]
|
||||
pub struct Beatmap {
|
||||
/// The game mode.
|
||||
pub mode: GameMode,
|
||||
/// The version of the .osu file.
|
||||
pub version: u8,
|
||||
|
||||
/// The amount of circles.
|
||||
pub n_circles: u32,
|
||||
/// The amount of sliders.
|
||||
pub n_sliders: u32,
|
||||
/// The amount of spinners.
|
||||
pub n_spinners: u32,
|
||||
|
||||
/// The approach rate.
|
||||
pub ar: f32,
|
||||
/// The overall difficulty.
|
||||
pub od: f32,
|
||||
/// The circle size.
|
||||
pub cs: f32,
|
||||
/// The health drain rate.
|
||||
pub hp: f32,
|
||||
/// Base slider velocity in pixels per beat
|
||||
pub slider_mult: f64,
|
||||
/// Amount of slider ticks per beat.
|
||||
pub tick_rate: f64,
|
||||
/// All hitobjects of the beatmap.
|
||||
pub hit_objects: Vec<HitObject>,
|
||||
|
||||
#[cfg(any(feature = "osu", feature = "fruits"))]
|
||||
/// Timing points that indicate a new timing section.
|
||||
pub timing_points: Vec<TimingPoint>,
|
||||
|
||||
#[cfg(any(feature = "osu", feature = "fruits"))]
|
||||
/// Timing point for the current timing section.
|
||||
pub difficulty_points: Vec<DifficultyPoint>,
|
||||
|
||||
#[cfg(feature = "osu")]
|
||||
/// The stack leniency that is used to calculate
|
||||
/// the stack offset for stacked positions.
|
||||
pub stack_leniency: f32,
|
||||
}
|
||||
|
||||
@@ -803,6 +823,7 @@ impl Beatmap {
|
||||
// const COMBO_OFFSET_FLAG: u8 = (1 << 4) | (1 << 5) | (1 << 6);
|
||||
const HOLD_FLAG: u8 = 1 << 7;
|
||||
|
||||
/// Extract a beatmap's attributes into their own type.
|
||||
#[inline]
|
||||
pub fn attributes(&self) -> BeatmapAttributes {
|
||||
BeatmapAttributes::new(self.ar, self.od, self.cs, self.hp)
|
||||
@@ -922,7 +943,10 @@ mod osu_fruits {
|
||||
/// Control point for slider curve calculation
|
||||
#[derive(Copy, Clone, Debug, Default, PartialEq)]
|
||||
pub struct PathControlPoint {
|
||||
/// Control point position.
|
||||
pub pos: Pos2,
|
||||
/// Path type of the control point.
|
||||
/// Only present for the first element of each segment.
|
||||
pub kind: Option<PathType>,
|
||||
}
|
||||
|
||||
@@ -934,6 +958,7 @@ mod osu_fruits {
|
||||
}
|
||||
|
||||
/// The type of curve of a slider.
|
||||
#[allow(missing_docs)]
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
pub enum PathType {
|
||||
Catmull = 0,
|
||||
|
||||
@@ -4,41 +4,50 @@ use std::ops;
|
||||
/// Simple (x, y) coordinate / vector
|
||||
#[derive(Clone, Copy, Default, PartialEq)]
|
||||
pub struct Pos2 {
|
||||
/// Position on the x-axis.
|
||||
pub x: f32,
|
||||
/// Position on the y-axis.
|
||||
pub y: f32,
|
||||
}
|
||||
|
||||
impl Pos2 {
|
||||
/// Return the null vector.
|
||||
#[inline]
|
||||
pub fn zero() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
/// Return a position with both coordinates on the given value.
|
||||
#[inline]
|
||||
pub fn new(value: f32) -> Self {
|
||||
Self { x: value, y: value }
|
||||
}
|
||||
|
||||
/// Return the position's length squared.
|
||||
#[inline]
|
||||
pub fn length_squared(&self) -> f32 {
|
||||
self.dot(*self)
|
||||
}
|
||||
|
||||
/// Return the position's length.
|
||||
#[inline]
|
||||
pub fn length(&self) -> f32 {
|
||||
self.x.hypot(self.y)
|
||||
}
|
||||
|
||||
/// Return the dot product.
|
||||
#[inline]
|
||||
pub fn dot(&self, other: Self) -> f32 {
|
||||
self.x.mul_add(other.x, self.y * other.y)
|
||||
}
|
||||
|
||||
/// Return the distance to another position.
|
||||
#[inline]
|
||||
pub fn distance(&self, other: Self) -> f32 {
|
||||
(*self - other).length()
|
||||
}
|
||||
|
||||
/// Normalize the coordinates with respect to the vector's length.
|
||||
#[inline]
|
||||
pub fn normalize(self) -> Pos2 {
|
||||
self / self.length()
|
||||
|
||||
Reference in New Issue
Block a user