rust/lib-hedgewars-engine/src/render/atlas.rs
changeset 14722 c97faf0aef78
parent 14720 b110cbe52e51
child 14723 766ce87dfdfc
equal deleted inserted replaced
14721:f9f71cccb5c3 14722:c97faf0aef78
   172 
   172 
   173     pub fn insert_sprite(&mut self, size: Size) -> bool {
   173     pub fn insert_sprite(&mut self, size: Size) -> bool {
   174         if !self.texture_size.contains(size) {
   174         if !self.texture_size.contains(size) {
   175             false
   175             false
   176         } else {
   176         } else {
   177             if let Some(rect) = self
   177             if let Some(rect) = self.atlases.iter_mut().find_map(|a| a.insert(size)) {
   178                 .atlases
       
   179                 .iter_mut()
       
   180                 .find_map(|a| a.insert(size))
       
   181             {
       
   182 
   178 
   183             } else if !self.repack(size) {
   179             } else if !self.repack(size) {
   184                 let mut atlas = Atlas::new(self.texture_size);
   180                 let mut atlas = Atlas::new(self.texture_size);
   185                 atlas.insert(size);
   181                 atlas.insert(size);
   186                 self.atlases.push(atlas);
   182                 self.atlases.push(atlas);
   215 
   211 
   216 #[cfg(test)]
   212 #[cfg(test)]
   217 mod tests {
   213 mod tests {
   218     use super::Atlas;
   214     use super::Atlas;
   219     use integral_geometry::{Rect, Size};
   215     use integral_geometry::{Rect, Size};
       
   216     use proptest::prelude::*;
   220 
   217 
   221     #[test]
   218     #[test]
   222     fn insert() {
   219     fn insert() {
   223         let atlas_size = Size::square(16);
   220         let atlas_size = Size::square(16);
   224         let mut atlas = Atlas::new(atlas_size);
   221         let mut atlas = Atlas::new(atlas_size);
   225 
   222 
   226         assert_eq!(None, atlas.insert(Size::square(20)));
   223         assert_eq!(None, atlas.insert(Size::square(20)));
   227 
   224 
   228         let rect_size = Size::new(11, 3);
   225         let rect_size = Size::new(11, 3);
   229         let rect = atlas.insert(rect_size).unwrap();
   226         let rect = atlas.insert(rect_size).unwrap();
       
   227         
   230         assert_eq!(rect, Rect::at_origin(rect_size));
   228         assert_eq!(rect, Rect::at_origin(rect_size));
   231         assert_eq!(2, atlas.free_rects.len());
   229         assert_eq!(2, atlas.free_rects.len());
   232     }
   230     }
   233 }
   231 
       
   232     #[derive(Debug, Clone)]
       
   233     struct TestRect(Size);
       
   234     struct TestRectParameters(Size);
       
   235 
       
   236     impl Default for TestRectParameters {
       
   237         fn default() -> Self {
       
   238             Self(Size::square(64))
       
   239         }
       
   240     }
       
   241 
       
   242     impl Arbitrary for TestRect {
       
   243         type Parameters = TestRectParameters;
       
   244 
       
   245         fn arbitrary_with(args: Self::Parameters) -> Self::Strategy {
       
   246             (1..=args.0.width, 1..=args.0.height)
       
   247                 .prop_map(|(w, h)| TestRect(Size::new(w, h)))
       
   248                 .boxed()
       
   249         }
       
   250 
       
   251         type Strategy = BoxedStrategy<TestRect>;
       
   252     }
       
   253 
       
   254     trait HasSize {
       
   255         fn size(&self) -> Size;
       
   256     }
       
   257 
       
   258     impl HasSize for TestRect {
       
   259         fn size(&self) -> Size {
       
   260             self.0
       
   261         }
       
   262     }
       
   263 
       
   264     impl HasSize for Rect {
       
   265         fn size(&self) -> Size {
       
   266             self.size()
       
   267         }
       
   268     }
       
   269 
       
   270     fn sum_area<S: HasSize>(items: &[S]) -> usize {
       
   271         items.iter().map(|s| s.size().area()).sum()
       
   272     }
       
   273 
       
   274     proptest! {
       
   275         #[test]
       
   276         fn prop_insert(rects in Vec::<TestRect>::arbitrary()) {
       
   277             let mut atlas = Atlas::new(Size::square(2048));
       
   278             let inserted: Vec<_> = rects.iter().take_while(|TestRect(size)| atlas.insert(*size).is_some()).cloned().collect();
       
   279 
       
   280             assert_eq!(inserted.len(), atlas.used_rects.len());
       
   281             assert_eq!(sum_area(&inserted), sum_area(&atlas.used_rects));
       
   282         }
       
   283     }
       
   284 }