# HG changeset patch # User alfadur # Date 1553718418 -10800 # Node ID 75ff5c6430045dc9010fc9b9b20534a66d46460e # Parent 19d30d96d7d63d0e22ef2de104f340dda4c71b66 actually atlas tests were also broken diff -r 19d30d96d7d6 -r 75ff5c643004 rust/integral-geometry/src/lib.rs --- a/rust/integral-geometry/src/lib.rs Wed Mar 27 22:10:46 2019 +0300 +++ b/rust/integral-geometry/src/lib.rs Wed Mar 27 23:26:58 2019 +0300 @@ -434,7 +434,7 @@ #[inline] pub fn intersects(&self, other: &Rect) -> bool { - self.left() <= self.right() + self.left() <= other.right() && self.right() >= other.left() && self.top() <= other.bottom() && self.bottom() >= other.top() diff -r 19d30d96d7d6 -r 75ff5c643004 rust/lib-hedgewars-engine/Cargo.toml --- a/rust/lib-hedgewars-engine/Cargo.toml Wed Mar 27 22:10:46 2019 +0300 +++ b/rust/lib-hedgewars-engine/Cargo.toml Wed Mar 27 23:26:58 2019 +0300 @@ -7,6 +7,7 @@ [dependencies] gl = "0.11" netbuf = "0.4" +itertools = "0.8" fpnum = { path = "../fpnum" } land2d = { path = "../land2d" } diff -r 19d30d96d7d6 -r 75ff5c643004 rust/lib-hedgewars-engine/src/render/atlas.rs --- a/rust/lib-hedgewars-engine/src/render/atlas.rs Wed Mar 27 22:10:46 2019 +0300 +++ b/rust/lib-hedgewars-engine/src/render/atlas.rs Wed Mar 27 23:26:58 2019 +0300 @@ -29,6 +29,40 @@ } } +#[derive(PartialEq, Eq)] +pub struct UsedSpace { + used_area: usize, + total_area: usize, +} + +impl UsedSpace { + const fn new(used_area: usize, total_area: usize) -> Self { + Self { + used_area, + total_area, + } + } + + const fn used(&self) -> usize { + self.used_area + } + + const fn total(&self) -> usize { + self.total_area + } +} + +impl std::fmt::Debug for UsedSpace { + fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> { + write!( + f, + "{:.2}%", + self.used() as f32 / self.total() as f32 / 100.0 + )?; + Ok(()) + } +} + pub struct Atlas { size: Size, free_rects: Vec, @@ -48,6 +82,11 @@ self.size } + pub fn used_space(&self) -> UsedSpace { + let used = self.used_rects.iter().map(|r| r.size().area()).sum(); + UsedSpace::new(used, self.size.area()) + } + fn find_position(&self, size: Size) -> Option<(Rect, Fit)> { let mut best_rect = Rect::EMPTY; let mut best_fit = Fit::new(); @@ -213,6 +252,7 @@ mod tests { use super::Atlas; use integral_geometry::{Rect, Size}; + use itertools::Itertools as _; use proptest::prelude::*; #[test] @@ -278,13 +318,32 @@ let mut atlas = Atlas::new(container.size()); let inserted: Vec<_> = rects.iter().filter_map(|TestRect(size)| atlas.insert(*size)).collect(); - let mut inserted_pairs = inserted.iter().zip(&inserted); + let mut inserted_pairs = inserted.iter().cartesian_product(inserted.iter()); assert!(inserted.iter().all(|r| container.contains_rect(r))); - assert!(inserted_pairs.all(|(r1, r2)| r1 == r2 || r1 != r2 && r1.intersects(r2))); + assert!(inserted_pairs.all(|(r1, r2)| r1 == r2 || r1 != r2 && !r1.intersects(r2))); - assert(inserted.len(), rects.len()); + assert_eq!(inserted.len(), rects.len()); assert_eq!(sum_area(&inserted), sum_area(&rects)); } } + + proptest! { + #[test] + fn prop_insert_set(rects in Vec::::arbitrary()) { + let container = Rect::at_origin(Size::square(2048)); + let mut atlas = Atlas::new(container.size()); + let mut set_atlas = Atlas::new(container.size()); + + let inserted: Vec<_> = rects.iter().filter_map(|TestRect(size)| atlas.insert(*size)).collect(); + let set_inserted: Vec<_> = set_atlas.insert_set(rects.iter().map(|TestRect(size)| *size)); + + let mut set_inserted_pairs = set_inserted.iter().cartesian_product(set_inserted.iter()); + + assert!(set_inserted_pairs.all(|(r1, r2)| r1 == r2 || r1 != r2 && !r1.intersects(r2))); + assert!(set_atlas.used_space().used() <= atlas.used_space().used()); + + assert_eq!(sum_area(&set_inserted), sum_area(&inserted)); + } + } }