Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add emath::OrderedFloat (moved from epaint::util::OrderedFloat) #4389

Merged
merged 2 commits into from
Apr 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/ecolor/src/rgba.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ impl std::ops::IndexMut<usize> for Rgba {
}
}

/// Deterministically hash an `f32`, treating all NANs as equal, and ignoring the sign of zero.
#[inline]
pub(crate) fn f32_hash<H: std::hash::Hasher>(state: &mut H, f: f32) {
if f == 0.0 {
Expand Down
1 change: 1 addition & 0 deletions crates/egui/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ unity = ["epaint/unity"]


[dependencies]
emath = { workspace = true, default-features = false }
epaint = { workspace = true, default-features = false }

ahash.workspace = true
Expand Down
20 changes: 9 additions & 11 deletions crates/egui/src/load.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,23 +55,21 @@
mod bytes_loader;
mod texture_loader;

use std::borrow::Cow;
use std::fmt::Debug;
use std::ops::Deref;
use std::{fmt::Display, sync::Arc};
use std::{
borrow::Cow,
fmt::{Debug, Display},
ops::Deref,
sync::Arc,
};

use ahash::HashMap;

use epaint::mutex::Mutex;
use epaint::util::FloatOrd;
use epaint::util::OrderedFloat;
use epaint::TextureHandle;
use epaint::{textures::TextureOptions, ColorImage, TextureId, Vec2};
use emath::{Float, OrderedFloat};
use epaint::{mutex::Mutex, textures::TextureOptions, ColorImage, TextureHandle, TextureId, Vec2};

use crate::Context;

pub use self::bytes_loader::DefaultBytesLoader;
pub use self::texture_loader::DefaultTextureLoader;
pub use self::{bytes_loader::DefaultBytesLoader, texture_loader::DefaultTextureLoader};

/// Represents a failed attempt at loading an image.
#[derive(Clone, Debug)]
Expand Down
8 changes: 4 additions & 4 deletions crates/egui/src/widgets/image.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use std::borrow::Cow;

use crate::load::TextureLoadResult;
use emath::{Float as _, Rot2};
use epaint::RectShape;

use crate::{
load::{Bytes, SizeHint, SizedTexture, TexturePoll},
load::{Bytes, SizeHint, SizedTexture, TextureLoadResult, TexturePoll},
*,
};
use emath::Rot2;
use epaint::{util::FloatOrd, RectShape};

/// A widget which displays an image.
///
Expand Down
2 changes: 1 addition & 1 deletion crates/egui_plot/src/items/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

use std::ops::RangeInclusive;

use epaint::{emath::Rot2, util::FloatOrd, Mesh};
use epaint::{emath::Rot2, Mesh};

use crate::*;

Expand Down
3 changes: 2 additions & 1 deletion crates/egui_plot/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ use std::{cmp::Ordering, ops::RangeInclusive, sync::Arc};

use egui::ahash::HashMap;
use egui::*;
use epaint::{util::FloatOrd, Hsva};
use emath::Float as _;
use epaint::Hsva;

pub use crate::{
axis::{Axis, AxisHints, HPlacement, Placement, VPlacement},
Expand Down
4 changes: 3 additions & 1 deletion crates/emath/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ use std::ops::{Add, Div, Mul, RangeInclusive, Sub};
pub mod align;
mod history;
mod numeric;
mod ordered_float;
mod pos2;
mod range;
mod rect;
Expand All @@ -40,10 +41,11 @@ mod ts_transform;
mod vec2;
mod vec2b;

pub use {
pub use self::{
align::{Align, Align2},
history::History,
numeric::*,
ordered_float::*,
pos2::*,
range::Rangef,
rect::*,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@ use std::hash::{Hash, Hasher};
/// Wraps a floating-point value to add total order and hash.
/// Possible types for `T` are `f32` and `f64`.
///
/// See also [`FloatOrd`].
/// All NaNs are considered equal to each other.
/// The size of zero is ignored.
///
/// See also [`Float`].
#[derive(Clone, Copy)]
pub struct OrderedFloat<T>(T);
pub struct OrderedFloat<T>(pub T);

impl<T: Float + Copy> OrderedFloat<T> {
#[inline]
Expand Down Expand Up @@ -68,44 +71,34 @@ impl<T> From<T> for OrderedFloat<T> {
///
/// Example with `f64`:
/// ```
/// use epaint::util::FloatOrd;
/// use emath::Float as _;
///
/// let array = [1.0, 2.5, 2.0];
/// let max = array.iter().max_by_key(|val| val.ord());
///
/// assert_eq!(max, Some(&2.5));
/// ```
pub trait FloatOrd {
pub trait Float: PartialOrd + PartialEq + private::FloatImpl {
/// Type to provide total order, useful as key in sorted contexts.
fn ord(self) -> OrderedFloat<Self>
where
Self: Sized;
}

impl FloatOrd for f32 {
impl Float for f32 {
#[inline]
fn ord(self) -> OrderedFloat<Self> {
OrderedFloat(self)
}
}

impl FloatOrd for f64 {
impl Float for f64 {
#[inline]
fn ord(self) -> OrderedFloat<Self> {
OrderedFloat(self)
}
}

// ----------------------------------------------------------------------------

/// Internal abstraction over floating point types
#[doc(hidden)]
pub trait Float: PartialOrd + PartialEq + private::FloatImpl {}

impl Float for f32 {}

impl Float for f64 {}

// Keep this trait in private module, to avoid exposing its methods as extensions in user code
mod private {
use super::*;
Expand All @@ -124,7 +117,13 @@ mod private {

#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
crate::f32_hash(state, *self);
if *self == 0.0 {
state.write_u8(0);
} else if self.is_nan() {
state.write_u8(1);
} else {
self.to_bits().hash(state);
}
}
}

Expand All @@ -136,7 +135,13 @@ mod private {

#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
crate::f64_hash(state, *self);
if *self == 0.0 {
state.write_u8(0);
} else if self.is_nan() {
state.write_u8(1);
} else {
self.to_bits().hash(state);
}
}
}
}
26 changes: 0 additions & 26 deletions crates/epaint/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,32 +152,6 @@ macro_rules! epaint_assert {
}
}

// ----------------------------------------------------------------------------

#[inline(always)]
pub(crate) fn f32_hash<H: std::hash::Hasher>(state: &mut H, f: f32) {
if f == 0.0 {
state.write_u8(0);
} else if f.is_nan() {
state.write_u8(1);
} else {
use std::hash::Hash;
f.to_bits().hash(state);
}
}

#[inline(always)]
pub(crate) fn f64_hash<H: std::hash::Hasher>(state: &mut H, f: f64) {
if f == 0.0 {
state.write_u8(0);
} else if f.is_nan() {
state.write_u8(1);
} else {
use std::hash::Hash;
f.to_bits().hash(state);
}
}

// ---------------------------------------------------------------------------

/// Was epaint compiled with the `rayon` feature?
Expand Down
2 changes: 1 addition & 1 deletion crates/epaint/src/stroke.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ impl std::hash::Hash for Stroke {
#[inline(always)]
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
let Self { width, color } = *self;
crate::f32_hash(state, width);
emath::OrderedFloat(width).hash(state);
color.hash(state);
}
}
23 changes: 4 additions & 19 deletions crates/epaint/src/text/fonts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::{
},
TextureAtlas,
};
use emath::NumExt as _;
use emath::{NumExt as _, OrderedFloat};

// ----------------------------------------------------------------------------

Expand Down Expand Up @@ -56,7 +56,7 @@ impl std::hash::Hash for FontId {
#[inline(always)]
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
let Self { size, family } = self;
crate::f32_hash(state, *size);
emath::OrderedFloat(*size).hash(state);
family.hash(state);
}
}
Expand Down Expand Up @@ -567,21 +567,6 @@ impl FontsAndCache {

// ----------------------------------------------------------------------------

#[derive(Clone, Copy, Debug, PartialEq)]
struct HashableF32(f32);

#[allow(clippy::derived_hash_with_manual_eq)]
impl std::hash::Hash for HashableF32 {
#[inline(always)]
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
crate::f32_hash(state, self.0);
}
}

impl Eq for HashableF32 {}

// ----------------------------------------------------------------------------

/// The collection of fonts used by `epaint`.
///
/// Required in order to paint text.
Expand All @@ -591,7 +576,7 @@ pub struct FontsImpl {
definitions: FontDefinitions,
atlas: Arc<Mutex<TextureAtlas>>,
font_impl_cache: FontImplCache,
sized_family: ahash::HashMap<(HashableF32, FontFamily), Font>,
sized_family: ahash::HashMap<(OrderedFloat<f32>, FontFamily), Font>,
}

impl FontsImpl {
Expand Down Expand Up @@ -641,7 +626,7 @@ impl FontsImpl {
let FontId { size, family } = font_id;

self.sized_family
.entry((HashableF32(*size), family.clone()))
.entry((OrderedFloat(*size), family.clone()))
.or_insert_with(|| {
let fonts = &self.definitions.families.get(family);
let fonts = fonts
Expand Down
10 changes: 5 additions & 5 deletions crates/epaint/src/text/text_layout_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ impl std::hash::Hash for LayoutJob {
text.hash(state);
sections.hash(state);
wrap.hash(state);
crate::f32_hash(state, *first_row_min_height);
emath::OrderedFloat(*first_row_min_height).hash(state);
break_on_newline.hash(state);
halign.hash(state);
justify.hash(state);
Expand Down Expand Up @@ -214,7 +214,7 @@ impl std::hash::Hash for LayoutSection {
byte_range,
format,
} = self;
crate::f32_hash(state, *leading_space);
OrderedFloat(*leading_space).hash(state);
byte_range.hash(state);
format.hash(state);
}
Expand Down Expand Up @@ -293,9 +293,9 @@ impl std::hash::Hash for TextFormat {
valign,
} = self;
font_id.hash(state);
crate::f32_hash(state, *extra_letter_spacing);
emath::OrderedFloat(*extra_letter_spacing).hash(state);
if let Some(line_height) = *line_height {
crate::f32_hash(state, line_height);
emath::OrderedFloat(line_height).hash(state);
}
color.hash(state);
background.hash(state);
Expand Down Expand Up @@ -375,7 +375,7 @@ impl std::hash::Hash for TextWrapping {
break_anywhere,
overflow_character,
} = self;
crate::f32_hash(state, *max_width);
emath::OrderedFloat(*max_width).hash(state);
max_rows.hash(state);
break_anywhere.hash(state);
overflow_character.hash(state);
Expand Down
5 changes: 2 additions & 3 deletions crates/epaint/src/util/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
mod ordered_float;

pub use ordered_float::*;
#[deprecated = "Use emath::OrderedFloat instead"]
pub use emath::OrderedFloat;

/// Hash the given value with a predictable hasher.
#[inline]
Expand Down
Loading