rectangle_pack/target_bin/
coalesce.rs

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