1
0
mirror of https://github.com/emilk/egui.git synced 2026-08-31 13:50:04 -04:00

Add features extra_asserts and extra_debug_asserts for more asserts

This replaces all debug_asserts with these opt-in asserts

Related: https://github.com/emilk/egui/issues/395
This commit is contained in:
Emil Ernerfeldt
2021-05-17 22:34:29 +02:00
parent bd5a85808a
commit 6e5b52e3bc
24 changed files with 135 additions and 58 deletions

View File

@@ -31,13 +31,19 @@ default = ["default_fonts", "single_threaded"]
# If you plan on specifying your own fonts you may disable this feature.
default_fonts = ["epaint/default_fonts"]
# Enable additional checks if debug assertions are enabled (debug builds).
extra_debug_asserts = ["epaint/extra_debug_asserts"]
# Always enable additional checks.
extra_asserts = ["epaint/extra_asserts"]
# Add compatability with https://github.com/kvark/mint
mint = ["epaint/mint"]
persistence = ["serde", "epaint/persistence", "ron"]
# Only needed if you plan to use the same egui::Context from multiple threads.
single_threaded = ["epaint/single_threaded"]
multi_threaded = ["epaint/multi_threaded"]
mint = ["epaint/mint"]
[dev-dependencies]
serde_json = "1"

View File

@@ -212,7 +212,7 @@ impl<'open> Window<'open> {
if self.scroll.is_none() {
self.scroll = Some(ScrollArea::auto_sized());
}
debug_assert!(
crate::egui_assert!(
self.scroll.is_some(),
"Window::scroll called multiple times"
);

View File

@@ -70,7 +70,7 @@ impl FrameState {
/// This is the "background" area, what egui doesn't cover with panels (but may cover with windows).
/// This is also the area to which windows are constrained.
pub(crate) fn available_rect(&self) -> Rect {
debug_assert!(
crate::egui_assert!(
self.available_rect.is_finite(),
"Called `available_rect()` before `CtxRef::begin_frame()`"
);
@@ -79,7 +79,7 @@ impl FrameState {
/// Shrink `available_rect`.
pub(crate) fn allocate_left_panel(&mut self, panel_rect: Rect) {
debug_assert!(
crate::egui_assert!(
panel_rect.min.distance(self.available_rect.min) < 0.1,
"Mismatching left panel. You must not create a panel from within another panel."
);
@@ -90,7 +90,7 @@ impl FrameState {
/// Shrink `available_rect`.
pub(crate) fn allocate_top_panel(&mut self, panel_rect: Rect) {
debug_assert!(
crate::egui_assert!(
panel_rect.min.distance(self.available_rect.min) < 0.1,
"Mismatching top panel. You must not create a panel from within another panel."
);

View File

@@ -342,8 +342,8 @@ impl Layout {
/// ## Doing layout
impl Layout {
pub fn align_size_within_rect(&self, size: Vec2, outer: Rect) -> Rect {
debug_assert!(size.x >= 0.0 && size.y >= 0.0);
debug_assert!(!outer.is_negative());
crate::egui_assert!(size.x >= 0.0 && size.y >= 0.0);
crate::egui_assert!(!outer.is_negative());
self.align2().align_size_within_rect(size, outer)
}
@@ -369,7 +369,7 @@ impl Layout {
}
pub(crate) fn region_from_max_rect(&self, max_rect: Rect) -> Region {
debug_assert!(!max_rect.any_nan());
crate::egui_assert!(!max_rect.any_nan());
let mut region = Region {
min_rect: Rect::NOTHING, // temporary
max_rect,
@@ -464,7 +464,7 @@ impl Layout {
/// This is what you then pass to `advance_after_rects`.
/// Use `justify_and_align` to get the inner `widget_rect`.
pub(crate) fn next_frame(&self, region: &Region, child_size: Vec2, spacing: Vec2) -> Rect {
debug_assert!(child_size.x >= 0.0 && child_size.y >= 0.0);
crate::egui_assert!(child_size.x >= 0.0 && child_size.y >= 0.0);
if self.main_wrap {
let available_size = self.available_rect_before_wrap(region).size();
@@ -543,7 +543,7 @@ impl Layout {
}
fn next_frame_ignore_wrap(&self, region: &Region, child_size: Vec2) -> Rect {
debug_assert!(child_size.x >= 0.0 && child_size.y >= 0.0);
crate::egui_assert!(child_size.x >= 0.0 && child_size.y >= 0.0);
let available_rect = self.available_rect_before_wrap_finite(region);
@@ -581,8 +581,8 @@ impl Layout {
/// Apply justify (fill width/height) and/or alignment after calling `next_space`.
pub(crate) fn justify_and_align(&self, frame: Rect, mut child_size: Vec2) -> Rect {
debug_assert!(child_size.x >= 0.0 && child_size.y >= 0.0);
debug_assert!(!frame.is_negative());
crate::egui_assert!(child_size.x >= 0.0 && child_size.y >= 0.0);
crate::egui_assert!(!frame.is_negative());
if self.horizontal_justify() {
child_size.x = child_size.x.at_least(frame.width()); // fill full width
@@ -600,7 +600,7 @@ impl Layout {
) -> Rect {
let frame = self.next_frame_ignore_wrap(region, size);
let rect = self.align_size_within_rect(size, frame);
debug_assert!((rect.size() - size).length() < 1.0);
crate::egui_assert!((rect.size() - size).length() < 1.0);
rect
}

View File

@@ -418,6 +418,22 @@ macro_rules! github_link_file {
// ----------------------------------------------------------------------------
/// An assert that is only active when `egui` is compiled with the `egui_assert` feature
/// or with the `debug_egui_assert` feature in debug builds.
#[macro_export]
macro_rules! egui_assert {
($($arg:tt)*) => {
if cfg!(any(
feature = "extra_asserts",
all(feature = "extra_debug_asserts", debug_assertions),
)) {
assert!($($arg)*);
}
}
}
// ----------------------------------------------------------------------------
/// egui supports around 1216 emojis in total.
/// Here are some of the most useful:
/// ∞⊗⎗⎘⎙⏏⏴⏵⏶⏷

View File

@@ -133,8 +133,8 @@ impl Placer {
/// Apply justify or alignment after calling `next_space`.
pub(crate) fn justify_and_align(&self, rect: Rect, child_size: Vec2) -> Rect {
debug_assert!(!rect.any_nan());
debug_assert!(!child_size.any_nan());
crate::egui_assert!(!rect.any_nan());
crate::egui_assert!(!child_size.any_nan());
if let Some(grid) = &self.grid {
grid.justify_and_align(rect, child_size)
@@ -146,7 +146,7 @@ impl Placer {
/// Advance the cursor by this many points.
/// [`Self::min_rect`] will expand to contain the cursor.
pub(crate) fn advance_cursor(&mut self, amount: f32) {
debug_assert!(
crate::egui_assert!(
self.grid.is_none(),
"You cannot advance the cursor when in a grid layout"
);

View File

@@ -442,8 +442,8 @@ impl Response {
/// For instance `a.union(b).hovered` means "was either a or b hovered?".
pub fn union(&self, other: Self) -> Self {
assert!(self.ctx == other.ctx);
debug_assert_eq!(
self.layer_id, other.layer_id,
crate::egui_assert!(
self.layer_id == other.layer_id,
"It makes no sense to combine Responses from two different layers"
);
Self {

View File

@@ -78,7 +78,7 @@ impl Ui {
/// Create a new `Ui` at a specific region.
pub fn child_ui(&mut self, max_rect: Rect, layout: Layout) -> Self {
debug_assert!(!max_rect.any_nan());
crate::egui_assert!(!max_rect.any_nan());
let next_auto_id_source = Id::new(self.next_auto_id_source).with("child").value();
self.next_auto_id_source = self.next_auto_id_source.wrapping_add(1);
@@ -723,7 +723,7 @@ impl Ui {
layout: Layout,
add_contents: Box<dyn FnOnce(&mut Self) -> R + 'c>,
) -> InnerResponse<R> {
debug_assert!(desired_size.x >= 0.0 && desired_size.y >= 0.0);
crate::egui_assert!(desired_size.x >= 0.0 && desired_size.y >= 0.0);
let item_spacing = self.spacing().item_spacing;
let frame_rect = self.placer.next_space(desired_size, item_spacing);
let child_rect = self.placer.justify_and_align(frame_rect, desired_size);

View File

@@ -104,7 +104,7 @@ where
/// Values must be added with a monotonically increasing time, or at least not decreasing.
pub fn add(&mut self, now: f64, value: T) {
if let Some((last_time, _)) = self.values.back() {
debug_assert!(now >= *last_time, "Time shouldn't move backwards");
crate::egui_assert!(now >= *last_time, "Time shouldn't move backwards");
}
self.total_count += 1;
self.values.push_back((now, value));

View File

@@ -523,7 +523,7 @@ fn value_from_normalized(normalized: f64, range: RangeInclusive<f64>, spec: &Sli
}
}
} else {
debug_assert!(
crate::egui_assert!(
min.is_finite() && max.is_finite(),
"You should use a logarithmic range"
);
@@ -572,7 +572,7 @@ fn normalized_from_value(value: f64, range: RangeInclusive<f64>, spec: &SliderSp
}
}
} else {
debug_assert!(
crate::egui_assert!(
min.is_finite() && max.is_finite(),
"You should use a logarithmic range"
);
@@ -620,6 +620,6 @@ fn logaritmic_zero_cutoff(min: f64, max: f64) -> f64 {
};
let cutoff = min_magnitude / (min_magnitude + max_magnitude);
debug_assert!(0.0 <= cutoff && cutoff <= 1.0);
crate::egui_assert!(0.0 <= cutoff && cutoff <= 1.0);
cutoff
}