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}