mirror of
https://github.com/danbulant/cushy
synced 2026-07-07 12:10:44 +00:00
parent
15960da098
commit
0fb93c7be8
2 changed files with 80 additions and 5 deletions
|
|
@ -30,6 +30,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
incorrectly.
|
incorrectly.
|
||||||
- A potential edge case where a `DynamicReader` would not return after being
|
- A potential edge case where a `DynamicReader` would not return after being
|
||||||
disconnected has been removed.
|
disconnected has been removed.
|
||||||
|
- [#120][120]: Dividing a `ZeroToOne` now properly checks for `NaN` and `0.`.
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
|
|
@ -71,6 +72,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
basis using `RunningWindow::kludgine_id()` as the key.
|
basis using `RunningWindow::kludgine_id()` as the key.
|
||||||
|
|
||||||
[99]: https://github.com/khonsulabs/cushy/issues/99
|
[99]: https://github.com/khonsulabs/cushy/issues/99
|
||||||
|
[120]: https://github.com/khonsulabs/cushy/issues/120
|
||||||
|
|
||||||
## v0.2.0
|
## v0.2.0
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1146,6 +1146,21 @@ impl ZeroToOne {
|
||||||
pub fn one_minus(self) -> Self {
|
pub fn one_minus(self) -> Self {
|
||||||
Self(1. - self.0)
|
Self(1. - self.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn checked_div<Float: PossiblyNaN>(&mut self, rhs: Float) {
|
||||||
|
let rhs = rhs.into();
|
||||||
|
if Float::CAN_BE_NAN {
|
||||||
|
assert!(!rhs.is_nan());
|
||||||
|
}
|
||||||
|
if rhs > 0. {
|
||||||
|
self.0 /= rhs;
|
||||||
|
} else if *self > 0. {
|
||||||
|
// The limit of f(x) -> x/0 is infinity, but the highest value we
|
||||||
|
// can represent is 1.0.
|
||||||
|
*self = Self::ONE;
|
||||||
|
}
|
||||||
|
// If both lhs and rhs are 0, this is a noop.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Zero for ZeroToOne {
|
impl Zero for ZeroToOne {
|
||||||
|
|
@ -1171,12 +1186,28 @@ impl FromStr for ZeroToOne {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<f32> for ZeroToOne {
|
impl From<f32> for ZeroToOne {
|
||||||
|
/// Returns a `ZeroToOne` clamped between 0.0 and 1.0.
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// This function panics if `value` is not a number.
|
||||||
fn from(value: f32) -> Self {
|
fn from(value: f32) -> Self {
|
||||||
Self::new(value)
|
Self::new(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<ZeroToOne> for f32 {
|
||||||
|
fn from(value: ZeroToOne) -> Self {
|
||||||
|
value.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<f64> for ZeroToOne {
|
impl From<f64> for ZeroToOne {
|
||||||
|
/// Returns a `ZeroToOne` clamped between 0.0 and 1.0.
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// This function panics if `value` is not a number.
|
||||||
fn from(value: f64) -> Self {
|
fn from(value: f64) -> Self {
|
||||||
Self::new(value.cast())
|
Self::new(value.cast())
|
||||||
}
|
}
|
||||||
|
|
@ -1258,25 +1289,55 @@ impl MulAssign for ZeroToOne {
|
||||||
impl Div for ZeroToOne {
|
impl Div for ZeroToOne {
|
||||||
type Output = Self;
|
type Output = Self;
|
||||||
|
|
||||||
fn div(self, rhs: Self) -> Self::Output {
|
fn div(mut self, rhs: Self) -> Self::Output {
|
||||||
self / rhs.0
|
self /= rhs;
|
||||||
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DivAssign for ZeroToOne {
|
impl DivAssign for ZeroToOne {
|
||||||
fn div_assign(&mut self, rhs: Self) {
|
fn div_assign(&mut self, rhs: Self) {
|
||||||
self.0 /= rhs.0;
|
self.checked_div(rhs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Div<f32> for ZeroToOne {
|
impl Div<f32> for ZeroToOne {
|
||||||
type Output = Self;
|
type Output = Self;
|
||||||
|
|
||||||
fn div(self, rhs: f32) -> Self::Output {
|
/// Divides `self` by `rhs`.
|
||||||
Self(self.0 / rhs)
|
///
|
||||||
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// This function panics if `rhs` is not a number.
|
||||||
|
fn div(mut self, rhs: f32) -> Self::Output {
|
||||||
|
self /= rhs;
|
||||||
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl DivAssign<f32> for ZeroToOne {
|
||||||
|
/// Divides `self` by `rhs`.
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// This function panics if `rhs` is not a number.
|
||||||
|
fn div_assign(&mut self, rhs: f32) {
|
||||||
|
self.checked_div(rhs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
trait PossiblyNaN: Into<f32> {
|
||||||
|
const CAN_BE_NAN: bool;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PossiblyNaN for ZeroToOne {
|
||||||
|
const CAN_BE_NAN: bool = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PossiblyNaN for f32 {
|
||||||
|
const CAN_BE_NAN: bool = true;
|
||||||
|
}
|
||||||
|
|
||||||
impl Ranged for ZeroToOne {
|
impl Ranged for ZeroToOne {
|
||||||
const MAX: Self = Self::ONE;
|
const MAX: Self = Self::ONE;
|
||||||
const MIN: Self = Self::ZERO;
|
const MIN: Self = Self::ZERO;
|
||||||
|
|
@ -1305,6 +1366,18 @@ impl From<ZeroToOne> for Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn zero_to_one_div() {
|
||||||
|
std::panic::catch_unwind(|| ZeroToOne::ONE / f32::NAN).expect_err("div by nan");
|
||||||
|
let mut value = ZeroToOne::ONE;
|
||||||
|
std::panic::catch_unwind(move || value /= f32::NAN).expect_err("div by nan");
|
||||||
|
|
||||||
|
assert_eq!(ZeroToOne::ZERO / ZeroToOne::ZERO, ZeroToOne::ZERO);
|
||||||
|
assert_eq!(ZeroToOne::new(0.5) / ZeroToOne::ZERO, ZeroToOne::ONE);
|
||||||
|
assert_eq!(ZeroToOne::ZERO / 0., ZeroToOne::ZERO);
|
||||||
|
assert_eq!(ZeroToOne::new(0.5) / 0., ZeroToOne::ONE);
|
||||||
|
}
|
||||||
|
|
||||||
/// An easing function for customizing animations.
|
/// An easing function for customizing animations.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum EasingFunction {
|
pub enum EasingFunction {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue