diff --git a/src/band.rs b/src/band.rs index 6c621be..388392e 100644 --- a/src/band.rs +++ b/src/band.rs @@ -1,7 +1,7 @@ use petgraph::stable_graph::StableDiGraph; use crate::{ - graph::{DotIndex, Ends, Interior, Label, Tag, TaggedIndex, TaggedWeight}, + graph::{DotIndex, Ends, Interior, Label, Tag, TaggedIndex, Weight}, primitive::Primitive, }; @@ -14,7 +14,7 @@ pub struct Band { impl Band { pub fn from_dot_prev( dot: DotIndex, - graph: &StableDiGraph, + graph: &StableDiGraph, ) -> Option { let mut next_index = dot.tag(); let mut interior = vec![]; @@ -38,7 +38,7 @@ impl Band { pub fn from_dot_next( dot: DotIndex, - graph: &StableDiGraph, + graph: &StableDiGraph, ) -> Option { let mut prev_index = dot.tag(); let mut interior = vec![]; diff --git a/src/bow.rs b/src/bow.rs index 2a6e65f..e0ec157 100644 --- a/src/bow.rs +++ b/src/bow.rs @@ -1,8 +1,6 @@ use petgraph::stable_graph::StableDiGraph; -use crate::graph::{ - BendIndex, DotIndex, Ends, Interior, Label, SegIndex, TaggedIndex, TaggedWeight, -}; +use crate::graph::{BendIndex, DotIndex, Ends, Interior, Label, SegIndex, TaggedIndex, Weight}; use crate::primitive::{Bend, Dot, Seg}; #[derive(Debug, Clone, Copy)] @@ -17,7 +15,7 @@ pub struct Bow { } impl Bow { - pub fn from_bend(index: BendIndex, graph: &StableDiGraph) -> Self { + pub fn from_bend(index: BendIndex, graph: &StableDiGraph) -> Self { let bend = index; let seg1_dot2 = Bend::new(bend, graph).prev().unwrap(); diff --git a/src/graph.rs b/src/graph.rs index a603e3b..4ca5727 100644 --- a/src/graph.rs +++ b/src/graph.rs @@ -1,4 +1,5 @@ use enum_as_inner::EnumAsInner; +use enum_dispatch::enum_dispatch; use petgraph::stable_graph::NodeIndex; use std::marker::PhantomData; @@ -12,8 +13,14 @@ pub trait Ends { fn ends(&self) -> (Start, Stop); } +#[enum_dispatch] +pub trait Retag { + fn retag(&self, index: NodeIndex) -> TaggedIndex; +} + +#[enum_dispatch(Retag)] #[derive(Debug, EnumAsInner, Clone, Copy, PartialEq)] -pub enum TaggedWeight { +pub enum Weight { Dot(DotWeight), Seg(SegWeight), Bend(BendWeight), @@ -25,10 +32,13 @@ pub struct DotWeight { pub circle: Circle, } -#[derive(Debug, Clone, Copy, PartialEq)] -pub struct BendWeight { - pub net: i64, - pub cw: bool, +impl Retag for DotWeight { + fn retag(&self, index: NodeIndex) -> TaggedIndex { + TaggedIndex::Dot(DotIndex { + index, + marker: PhantomData, + }) + } } #[derive(Debug, Clone, Copy, PartialEq)] @@ -37,6 +47,30 @@ pub struct SegWeight { pub width: f64, } +impl Retag for SegWeight { + fn retag(&self, index: NodeIndex) -> TaggedIndex { + TaggedIndex::Seg(SegIndex { + index, + marker: PhantomData, + }) + } +} + +#[derive(Debug, Clone, Copy, PartialEq)] +pub struct BendWeight { + pub net: i64, + pub cw: bool, +} + +impl Retag for BendWeight { + fn retag(&self, index: NodeIndex) -> TaggedIndex { + TaggedIndex::Bend(BendIndex { + index, + marker: PhantomData, + }) + } +} + #[derive(Debug, EnumAsInner, Clone, Copy, PartialEq)] pub enum Label { End, @@ -64,23 +98,6 @@ impl Index { marker: PhantomData, } } - - pub fn retag(&self, weight: &TaggedWeight) -> TaggedIndex { - match weight { - TaggedWeight::Dot(..) => TaggedIndex::Dot(DotIndex { - index: self.index, - marker: PhantomData, - }), - TaggedWeight::Seg(..) => TaggedIndex::Seg(SegIndex { - index: self.index, - marker: PhantomData, - }), - TaggedWeight::Bend(..) => TaggedIndex::Bend(BendIndex { - index: self.index, - marker: PhantomData, - }), - } - } } pub trait Tag { diff --git a/src/layout.rs b/src/layout.rs index 77209aa..c1eaff2 100644 --- a/src/layout.rs +++ b/src/layout.rs @@ -10,8 +10,8 @@ use spade::Triangulation; use crate::band::Band; use crate::bow::Bow; use crate::graph::{ - BendIndex, BendWeight, DotIndex, DotWeight, Index, Interior, Label, SegIndex, SegWeight, Tag, - TaggedIndex, TaggedWeight, + BendIndex, BendWeight, DotIndex, DotWeight, Index, Interior, Label, Retag, SegIndex, SegWeight, + Tag, TaggedIndex, Weight, }; use crate::primitive::Primitive; use crate::segbend::Segbend; @@ -21,7 +21,7 @@ pub type RTreeWrapper = GeomWithData; pub struct Layout { rtree: RTree, - pub graph: StableDiGraph, + pub graph: StableDiGraph, } #[debug_invariant(self.graph.node_count() == self.rtree.size())] @@ -53,13 +53,13 @@ impl Layout { // Unnecessary retag. It should be possible to elide it. let weight = *self.graph.node_weight(index.index).unwrap(); - self.remove_from_rtree(index.retag(&weight)); + self.remove_from_rtree(weight.retag(index.index)); self.graph.remove_node(index.index); } #[debug_ensures(self.graph.node_count() == old(self.graph.node_count() + 1))] pub fn add_dot(&mut self, weight: DotWeight) -> Result { - let dot = DotIndex::new(self.graph.add_node(TaggedWeight::Dot(weight))); + let dot = DotIndex::new(self.graph.add_node(Weight::Dot(weight))); self.insert_into_rtree(dot.tag()); self.fail_and_remove_if_collides_except(dot, &[])?; @@ -75,7 +75,7 @@ impl Layout { to: DotIndex, weight: SegWeight, ) -> Result { - let seg = SegIndex::new(self.graph.add_node(TaggedWeight::Seg(weight))); + let seg = SegIndex::new(self.graph.add_node(Weight::Seg(weight))); self.graph.add_edge(from.index, seg.index, Label::End); self.graph.add_edge(seg.index, to.index, Label::End); @@ -126,7 +126,7 @@ impl Layout { core: DotIndex, weight: BendWeight, ) -> Result { - let bend = BendIndex::new(self.graph.add_node(TaggedWeight::Bend(weight))); + let bend = BendIndex::new(self.graph.add_node(Weight::Bend(weight))); self.graph.add_edge(from.index, bend.index, Label::End); self.graph.add_edge(bend.index, to.index, Label::End); @@ -162,7 +162,7 @@ impl Layout { .first() .unwrap(); - let bend = BendIndex::new(self.graph.add_node(TaggedWeight::Bend(weight))); + let bend = BendIndex::new(self.graph.add_node(Weight::Bend(weight))); self.graph.add_edge(from.index, bend.index, Label::End); self.graph.add_edge(bend.index, to.index, Label::End); @@ -283,11 +283,11 @@ impl Layout { let old_weight = dot_weight; dot_weight.circle.pos = to; - *self.graph.node_weight_mut(dot.index).unwrap() = TaggedWeight::Dot(dot_weight); + *self.graph.node_weight_mut(dot.index).unwrap() = Weight::Dot(dot_weight); if let Some(..) = self.detect_collision_except(dot, &[]) { // Restore original state. - *self.graph.node_weight_mut(dot.index).unwrap() = TaggedWeight::Dot(old_weight); + *self.graph.node_weight_mut(dot.index).unwrap() = Weight::Dot(old_weight); self.insert_into_rtree(dot.tag()); self.primitive(dot) diff --git a/src/primitive.rs b/src/primitive.rs index 68db0e9..8097f03 100644 --- a/src/primitive.rs +++ b/src/primitive.rs @@ -4,27 +4,27 @@ use petgraph::stable_graph::{NodeIndex, StableDiGraph}; use petgraph::Direction::{Incoming, Outgoing}; use crate::graph::{ - BendIndex, BendWeight, DotIndex, DotWeight, Ends, Index, Interior, Label, SegWeight, - TaggedIndex, TaggedWeight, + BendIndex, BendWeight, DotIndex, DotWeight, Ends, Index, Interior, Label, Retag, SegWeight, + TaggedIndex, Weight, }; use crate::math::{self, Circle}; use crate::shape::{BendShape, DotShape, SegShape, Shape, ShapeTrait}; #[derive(Debug)] -pub struct Primitive<'a, Weight> { - pub index: Index, - graph: &'a StableDiGraph, +pub struct Primitive<'a, W> { + pub index: Index, + graph: &'a StableDiGraph, } -impl<'a, Weight> Primitive<'a, Weight> { - pub fn new(index: Index, graph: &'a StableDiGraph) -> Self { +impl<'a, W> Primitive<'a, W> { + pub fn new(index: Index, graph: &'a StableDiGraph) -> Self { Self { index, graph } } pub fn shape(&self) -> Shape { match self.tagged_weight() { - TaggedWeight::Dot(dot) => Shape::Dot(DotShape { c: dot.circle }), - TaggedWeight::Seg(seg) => { + Weight::Dot(dot) => Shape::Dot(DotShape { c: dot.circle }), + Weight::Seg(seg) => { let ends = self.ends(); Shape::Seg(SegShape { from: self.primitive(ends.0).weight().circle.pos, @@ -32,7 +32,7 @@ impl<'a, Weight> Primitive<'a, Weight> { width: seg.width, }) } - TaggedWeight::Bend(bend) => { + Weight::Bend(bend) => { let ends = self.ends(); let mut bend_shape = BendShape { @@ -77,7 +77,7 @@ impl<'a, Weight> Primitive<'a, Weight> { pub fn neighbors(&self) -> impl Iterator + '_ { self.graph .neighbors_undirected(self.index.index) - .map(|index| Index::