1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
use crate::TargetBin; use std::ops::Range; impl TargetBin { /// Over time as you use [`TargetBin.push_available_bin_section`] to return remove packed /// rectangles from the [`TargetBin`], you may end up with neighboring bin sections that can /// be combined into a larger bin section. /// /// Combining bin sections in this was is desirable because a larger bin section allows you to /// place larger rectangles that might not fit into the smaller bin sections. /// /// In order to coalesce, or combine a bin section with other bin sections, we need to check /// every other available bin section to see if they are neighbors. /// /// This means that fully coalescing the entire list of available bin sections is O(n^2) time /// complexity, where n is the number of available empty sections. /// /// # Basic Usage /// /// ```ignore /// # use rectangle_pack::TargetBin; /// let target_bin = my_target_bin(); /// /// for idx in 0..target_bin.available_bin_sections().len() { /// let len = target_bin.available_bin_sections().len(); /// target_bin.coalesce_available_sections(idx, 0..len); /// } /// /// # fn my_target_bin () -> TargetBin { /// # TargetBin::new(1, 2, 3) /// # } /// ``` /// /// # Distributing the Workload /// /// It is possible that you are developing an application that can in some cases have a lot of /// heavily fragmented bins that need to be coalesced. If your application has a tight /// performance budget, such as a real time simulation, you may not want to do all of your /// coalescing at once. /// /// This method allows you to split the work over many frames by giving you fine grained control /// over which bin sections is getting coalesced and which other bin sections it gets tested /// against. /// /// So, for example, say you have an application where you want to fully coalesce the entire /// bin every ten seconds, and you are running at 60 frames per second. You would then /// distribute the coalescing work such that it would take 600 calls to compare every bin /// section. /// /// Here's a basic eample of splitting the work. /// /// ```ignore /// # use rectangle_pack::TargetBin; /// let target_bin = my_target_bin(); /// /// let current_frame: usize = get_current_frame() % 600; /// /// for idx in 0..target_bin.available_bin_sections().len() { /// let len = target_bin.available_bin_sections().len(); /// /// let start = len / 600 * current_frame; /// let end = start + len / 600; /// /// target_bin.coalesce_available_sections(idx, start..end); /// } /// /// # fn my_target_bin () -> TargetBin { /// # TargetBin::new(1, 2, 3) /// # } /// # /// # fn get_current_frame () -> usize { /// # 0 /// # } /// ``` /// /// [`TargetBin.push_available_bin_section`]: #method.push_available_bin_section // TODO: Write tests, implement then remove the "ignore" from the examples above. // Tests cases should have a rectangle and then a neighbor (above, below, left, right) and // verify that they get combined, but only if the comparison indices are correct and only if // the neighbor has the same width (uf above/below) or height (if left/right). pub fn coalesce_available_sections(bin_section_index: usize, compare_to_indices: Range<usize>) { unimplemented!() } }