reduce Difficulty struct size
This commit is contained in:
@@ -35,7 +35,7 @@ impl<M> ConvertedDifficulty<M> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Cast from generic mode `M` to `N`.
|
/// Cast from generic mode `M` to `N`.
|
||||||
pub fn cast<N: IGameMode>(self) -> ConvertedDifficulty<N> {
|
pub const fn cast<N: IGameMode>(self) -> ConvertedDifficulty<N> {
|
||||||
ConvertedDifficulty {
|
ConvertedDifficulty {
|
||||||
inner: self.inner,
|
inner: self.inner,
|
||||||
_mode: PhantomData,
|
_mode: PhantomData,
|
||||||
@@ -108,12 +108,11 @@ impl<M> AsRef<Difficulty> for ConvertedDifficulty<M> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<M> Copy for ConvertedDifficulty<M> {}
|
||||||
|
|
||||||
impl<M> Clone for ConvertedDifficulty<M> {
|
impl<M> Clone for ConvertedDifficulty<M> {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
Self {
|
*self
|
||||||
inner: self.inner.clone(),
|
|
||||||
_mode: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+25
-16
@@ -1,4 +1,4 @@
|
|||||||
use std::borrow::Cow;
|
use std::{borrow::Cow, num::NonZeroU32};
|
||||||
|
|
||||||
use rosu_map::section::general::GameMode;
|
use rosu_map::section::general::GameMode;
|
||||||
|
|
||||||
@@ -23,12 +23,20 @@ pub mod skills;
|
|||||||
use crate::{model::mode::IGameMode, util::mods::Mods};
|
use crate::{model::mode::IGameMode, util::mods::Mods};
|
||||||
|
|
||||||
/// Difficulty calculator on maps of any mode.
|
/// Difficulty calculator on maps of any mode.
|
||||||
#[derive(Clone, Debug, Default, PartialEq)]
|
#[derive(Copy, Clone, Debug, Default, PartialEq)]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub struct Difficulty {
|
pub struct Difficulty {
|
||||||
mods: u32,
|
mods: u32,
|
||||||
passed_objects: Option<u32>,
|
passed_objects: Option<u32>,
|
||||||
clock_rate: Option<f64>,
|
/// Clock rate will be clamped internally between 0.01 and 100.0.
|
||||||
|
///
|
||||||
|
/// Since its minimum value is 0.01, its bits are never zero.
|
||||||
|
/// Additionally, values between 0.01 and 100 are represented sufficiently
|
||||||
|
/// precise with 32 bits.
|
||||||
|
///
|
||||||
|
/// This allows for an optimization to reduce the struct size by storing its
|
||||||
|
/// bits as a [`NonZeroU32`].
|
||||||
|
clock_rate: Option<NonZeroU32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Difficulty {
|
impl Difficulty {
|
||||||
@@ -41,17 +49,9 @@ impl Difficulty {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Use this [`&Difficulty`] as a calculator for a specific [`IGameMode`].
|
/// Use this [`Difficulty`] as a calculator for a specific [`IGameMode`].
|
||||||
///
|
pub const fn with_mode<M: IGameMode>(self) -> ConvertedDifficulty<M> {
|
||||||
/// [`&Difficulty`]: Difficulty
|
ConvertedDifficulty::from_difficulty(self)
|
||||||
pub const fn with_mode<M: IGameMode>(&self) -> ConvertedDifficulty<M> {
|
|
||||||
let this = Self {
|
|
||||||
mods: self.mods,
|
|
||||||
passed_objects: self.passed_objects,
|
|
||||||
clock_rate: self.clock_rate,
|
|
||||||
};
|
|
||||||
|
|
||||||
ConvertedDifficulty::from_difficulty(this)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Specify mods through their bit values.
|
/// Specify mods through their bit values.
|
||||||
@@ -74,8 +74,14 @@ impl Difficulty {
|
|||||||
/// If none is specified, it will take the clock rate based on the mods
|
/// If none is specified, it will take the clock rate based on the mods
|
||||||
/// i.e. 1.5 for DT, 0.75 for HT and 1.0 otherwise.
|
/// i.e. 1.5 for DT, 0.75 for HT and 1.0 otherwise.
|
||||||
pub fn clock_rate(self, clock_rate: f64) -> Self {
|
pub fn clock_rate(self, clock_rate: f64) -> Self {
|
||||||
|
let clock_rate = (clock_rate as f32).clamp(0.01, 100.0).to_bits();
|
||||||
|
|
||||||
|
// SAFETY: The minimum value is 0.01 so its bits can never be fully
|
||||||
|
// zero.
|
||||||
|
let non_zero = unsafe { NonZeroU32::new_unchecked(clock_rate) };
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
clock_rate: Some(clock_rate.clamp(0.01, 100.0)),
|
clock_rate: Some(non_zero),
|
||||||
..self
|
..self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -130,7 +136,10 @@ impl Difficulty {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_clock_rate(&self) -> f64 {
|
pub(crate) fn get_clock_rate(&self) -> f64 {
|
||||||
self.clock_rate.unwrap_or_else(|| self.mods.clock_rate())
|
self.clock_rate
|
||||||
|
.map(NonZeroU32::get)
|
||||||
|
.map(u64::from)
|
||||||
|
.map_or_else(|| self.mods.clock_rate(), f64::from_bits)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_passed_objects(&self) -> usize {
|
pub(crate) fn get_passed_objects(&self) -> usize {
|
||||||
|
|||||||
Reference in New Issue
Block a user