diff options
author | Jovansonlee Cesar <ivanceras@gmail.com> | 2022-09-23 19:37:51 +0800 |
---|---|---|
committer | Jovansonlee Cesar <ivanceras@gmail.com> | 2022-09-23 19:37:51 +0800 |
commit | 13c4eb0a0146a00f0dd766bf4c78ca7be93b0c41 (patch) | |
tree | 3599ae52513a03eee5af00379c6dac75679762cd | |
parent | edce73dc082ee718786b5fa8d7076dfc85e51685 (diff) |
refactor: convert group_recursive into using Merge trait
-rw-r--r-- | packages/svgbob/src/buffer/cell_buffer.rs | 2 | ||||
-rw-r--r-- | packages/svgbob/src/buffer/cell_buffer/contacts.rs | 43 | ||||
-rw-r--r-- | packages/svgbob/src/buffer/cell_buffer/span.rs | 53 | ||||
-rw-r--r-- | packages/svgbob/src/buffer/cell_buffer/span/test_span.rs | 10 | ||||
-rw-r--r-- | packages/svgbob/src/buffer/fragment_buffer/fragment/text.rs | 6 | ||||
-rw-r--r-- | packages/svgbob/src/map/circle_map.rs | 3 | ||||
-rw-r--r-- | packages/svgbob/src/map/circle_map/test_circle_map.rs | 2 |
7 files changed, 46 insertions, 73 deletions
diff --git a/packages/svgbob/src/buffer/cell_buffer.rs b/packages/svgbob/src/buffer/cell_buffer.rs index 5d3f57f..ee0e3f8 100644 --- a/packages/svgbob/src/buffer/cell_buffer.rs +++ b/packages/svgbob/src/buffer/cell_buffer.rs @@ -95,7 +95,7 @@ impl CellBuffer { .group_adjacents() .into_iter() .map(|span| { - let contacts = span.get_contacts(); + let contacts: Vec<Contacts> = span.clone().into(); if contacts.is_empty() { (vec![span], vec![]) } else { diff --git a/packages/svgbob/src/buffer/cell_buffer/contacts.rs b/packages/svgbob/src/buffer/cell_buffer/contacts.rs index 559e8ac..b9345de 100644 --- a/packages/svgbob/src/buffer/cell_buffer/contacts.rs +++ b/packages/svgbob/src/buffer/cell_buffer/contacts.rs @@ -2,6 +2,7 @@ use super::endorse; use crate::buffer::fragment_buffer::FragmentSpan; use crate::buffer::Span; use crate::buffer::{fragment::Fragment, Cell}; +use crate::Merge; use std::fmt; /// Contains a group of fragments that are touching each other @@ -72,36 +73,6 @@ impl Contacts { } } - pub(crate) fn group_recursive(groups: Vec<Contacts>) -> Vec<Contacts> { - let original_len = groups.len(); - let grouped = Self::second_pass_groupable(groups); - // continue calling group recursive until the original len - // has not decreased - if grouped.len() < original_len { - Self::group_recursive(grouped) - } else { - grouped - } - } - - fn second_pass_groupable(groups: Vec<Contacts>) -> Vec<Contacts> { - let mut new_groups: Vec<Contacts> = vec![]; - for group in groups.into_iter() { - let is_grouped = new_groups.iter_mut().any(|new_group| { - if new_group.is_contacting(&group) { - new_group.as_mut().extend_from_slice(group.as_ref()); - true - } else { - false - } - }); - if !is_grouped { - new_groups.push(group); - } - } - new_groups - } - /// First phase of endorsing to shapes, in this case, rects and rounded_rects /// /// This function is calling on endorse methods that is applicable @@ -144,6 +115,18 @@ impl Contacts { } } +impl Merge for Contacts { + fn merge(&self, other: &Self) -> Option<Self> { + if self.is_contacting(&other) { + let mut fragment_spans: Vec<FragmentSpan> = self.0.clone(); + fragment_spans.extend_from_slice(&other.0); + Some(Contacts(fragment_spans)) + } else { + None + } + } +} + impl fmt::Display for Contacts { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { for frag in self.as_ref().iter() { diff --git a/packages/svgbob/src/buffer/cell_buffer/span.rs b/packages/svgbob/src/buffer/cell_buffer/span.rs index dae311d..3415abc 100644 --- a/packages/svgbob/src/buffer/cell_buffer/span.rs +++ b/packages/svgbob/src/buffer/cell_buffer/span.rs @@ -116,36 +116,6 @@ impl Span { } } - /// Grouping cell by adjacents are not enough - /// - /// grouping them together when they are actually connected - /// is the most approprivate way of grouping - /// Span just provides an optimization of the number - /// of elements to be checked. - /// Only elements on the same span are checked to see if they - /// belong on the same group - /// - pub(crate) fn get_contacts(&self) -> Vec<Contacts> { - let fb: FragmentBuffer = self.clone().into(); - - let mut groups: Vec<Contacts> = vec![]; - let merged_fragments = fb.merge_fragment_spans(); - for fragment in merged_fragments.into_iter() { - let belongs_to_group = groups.iter_mut().rev().any(|group| { - if group.is_contacting_frag(&fragment) { - group.as_mut().push(fragment.clone()); - true - } else { - false - } - }); - if !belongs_to_group { - groups.push(Contacts::new(fragment)) - } - } - Contacts::group_recursive(groups) - } - /// convert this span into fragments applying endorsement /// of group into fragments /// @@ -178,7 +148,7 @@ impl Span { self }; - let groups: Vec<Contacts> = un_endorsed_span.get_contacts(); + let groups: Vec<Contacts> = un_endorsed_span.into(); let (rect_fragments, un_endorsed) = Contacts::endorse_rects(groups); fragments.extend(rect_fragments); @@ -284,6 +254,27 @@ impl<'p> From<Span> for PropertyBuffer<'p> { } } +/// Grouping cell by adjacents are not enough +/// +/// grouping them together when they are actually connected +/// is the most approprivate way of grouping +/// Span just provides an optimization of the number +/// of elements to be checked. +/// Only elements on the same span are checked to see if they +/// belong on the same group +/// +impl From<Span> for Vec<Contacts> { + fn from(span: Span) -> Vec<Contacts> { + let fb = FragmentBuffer::from(span); + let merged_fragments: Vec<FragmentSpan> = fb.merge_fragment_spans(); + let contacts: Vec<Contacts> = merged_fragments + .into_iter() + .map(|frag| Contacts::new(frag)) + .collect(); + Contacts::merge_recursive(contacts) + } +} + /// First we crate a property buffer based on the cell,char content of this span /// and then based on the property, we extract the accurate fragments /// diff --git a/packages/svgbob/src/buffer/cell_buffer/span/test_span.rs b/packages/svgbob/src/buffer/cell_buffer/span/test_span.rs index 26e88d4..76aa776 100644 --- a/packages/svgbob/src/buffer/cell_buffer/span/test_span.rs +++ b/packages/svgbob/src/buffer/cell_buffer/span/test_span.rs @@ -58,7 +58,7 @@ fn test_1span_1group() { let span = adjacents.remove(0); let (top_left, _) = span.bounds().unwrap(); assert_eq!(top_left, Cell::new(0, 1)); - let groups: Vec<Contacts> = span.localize().get_contacts(); + let groups: Vec<Contacts> = span.localize().into(); for (i, group) in groups.iter().enumerate() { println!("group {} is: \n{}", i, group); } @@ -97,8 +97,8 @@ fn test_2spans_1group_for_each_span() { let (bound2, _) = span2.bounds().unwrap(); assert_eq!(bound1, Cell::new(0, 1)); assert_eq!(bound2, Cell::new(0, 5)); - let groups1: Vec<Contacts> = span1.localize().get_contacts(); - let groups2: Vec<Contacts> = span2.localize().get_contacts(); + let groups1: Vec<Contacts> = span1.localize().into(); + let groups2: Vec<Contacts> = span2.localize().into(); assert_eq!(groups1.len(), 1); assert_eq!(groups2.len(), 1); @@ -143,7 +143,7 @@ fn test_1spans_2group_for_each_span() { let span1 = spans.remove(0); let (bound1, _) = span1.bounds().unwrap(); assert_eq!(bound1, Cell::new(0, 1)); - let groups: Vec<Contacts> = span1.localize().get_contacts(); + let groups: Vec<Contacts> = span1.localize().into(); assert_eq!(groups.len(), 2); let rect1 = groups[0].endorse_rect().unwrap(); @@ -332,7 +332,7 @@ fn test_absolute_positions() { let (top_left1, _br) = span1.bounds().unwrap(); assert_eq!(top_left1, Cell::new(8, 5)); - let groups1 = span1.localize().get_contacts(); + let groups1: Vec<Contacts> = span1.localize().into(); let since = groups1[11].as_ref()[0].fragment.as_cell_text().unwrap(); assert_eq!(since.content, "since"); assert_eq!(since.start, Cell::new(20, 1)); diff --git a/packages/svgbob/src/buffer/fragment_buffer/fragment/text.rs b/packages/svgbob/src/buffer/fragment_buffer/fragment/text.rs index c750e07..f02faf5 100644 --- a/packages/svgbob/src/buffer/fragment_buffer/fragment/text.rs +++ b/packages/svgbob/src/buffer/fragment_buffer/fragment/text.rs @@ -263,7 +263,7 @@ mod tests { let mut spans: Vec<Span> = cell_buffer.group_adjacents(); assert_eq!(spans.len(), 1); let span1 = spans.remove(0); - let groups = span1.localize().get_contacts(); + let groups: Vec<Contacts> = span1.localize().into(); for (i, group) in groups.iter().enumerate() { println!("group{}\n{}", i, group); } @@ -309,8 +309,8 @@ mod tests { let cell_buffer = CellBuffer::from(art); let mut spans: Vec<Span> = cell_buffer.group_adjacents(); assert_eq!(spans.len(), 2); - let groups2 = spans.remove(1).localize().get_contacts(); - let groups1 = spans.remove(0).localize().get_contacts(); + let groups2: Vec<Contacts> = spans.remove(1).localize().into(); + let groups1: Vec<Contacts> = spans.remove(0).localize().into(); println!("span1 groups:"); for (i, group1) in groups1.iter().enumerate() { println!("\tgroup {} {}", i, group1); diff --git a/packages/svgbob/src/map/circle_map.rs b/packages/svgbob/src/map/circle_map.rs index 27190ee..b42191b 100644 --- a/packages/svgbob/src/map/circle_map.rs +++ b/packages/svgbob/src/map/circle_map.rs @@ -739,8 +739,7 @@ impl PartialOrd for DiameterArc { } fn circle_art_to_group(art: &str) -> Vec<Contacts> { - let span1 = circle_art_to_span(art); - span1.get_contacts() + circle_art_to_span(art).into() } fn circle_art_to_span(art: &str) -> Span { diff --git a/packages/svgbob/src/map/circle_map/test_circle_map.rs b/packages/svgbob/src/map/circle_map/test_circle_map.rs index f2e449e..388f794 100644 --- a/packages/svgbob/src/map/circle_map/test_circle_map.rs +++ b/packages/svgbob/src/map/circle_map/test_circle_map.rs @@ -18,7 +18,7 @@ fn test_circle1() { let mut spans: Vec<Span> = cell_buffer.group_adjacents(); assert_eq!(spans.len(), 1); let span1 = spans.remove(0); - let groups = span1.get_contacts(); + let groups: Vec<Contacts> = span1.into(); for (i, group) in groups.iter().enumerate() { println!("group{}\n{}", i, group); } |