From 403e3e4f986f3a8bd01e9ca0b12e13753219945d Mon Sep 17 00:00:00 2001 From: Mikolaj Wielgus Date: Sat, 21 Oct 2023 04:32:55 +0000 Subject: [PATCH] graph: Remove the `untag` macro To accomplish this, some more methods are moved to traits. --- src/graph.rs | 35 ++++++++++++++++++++++---------- src/layout.rs | 22 +++++++++----------- src/primitive.rs | 53 +++++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 82 insertions(+), 28 deletions(-) diff --git a/src/graph.rs b/src/graph.rs index 2045804..a991e63 100644 --- a/src/graph.rs +++ b/src/graph.rs @@ -21,7 +21,12 @@ pub trait Retag { fn retag(&self, index: NodeIndex) -> Index; } -#[enum_dispatch(Retag)] +#[enum_dispatch] +pub trait GetNet { + fn net(&self) -> i64; +} + +#[enum_dispatch(Retag, GetNet)] #[derive(Debug, EnumAsInner, Clone, Copy, PartialEq)] pub enum Weight { Dot(DotWeight), @@ -44,6 +49,12 @@ impl Retag for DotWeight { } } +impl GetNet for DotWeight { + fn net(&self) -> i64 { + self.net + } +} + #[derive(Debug, Clone, Copy, PartialEq)] pub struct SegWeight { pub net: i64, @@ -59,6 +70,12 @@ impl Retag for SegWeight { } } +impl GetNet for SegWeight { + fn net(&self) -> i64 { + self.net + } +} + #[derive(Debug, Clone, Copy, PartialEq)] pub struct BendWeight { pub net: i64, @@ -74,6 +91,12 @@ impl Retag for BendWeight { } } +impl GetNet for BendWeight { + fn net(&self) -> i64 { + self.net + } +} + #[derive(Debug, EnumAsInner, Clone, Copy, PartialEq)] pub enum Label { End, @@ -120,16 +143,6 @@ impl GetNodeIndex for GenericIndex { } } -macro_rules! untag { - ($index:ident, $expr:expr) => { - match $index { - Index::Dot($index) => $expr, - Index::Seg($index) => $expr, - Index::Bend($index) => $expr, - } - }; -} - pub type DotIndex = GenericIndex; impl MakePrimitive for DotIndex { diff --git a/src/layout.rs b/src/layout.rs index e4f4022..8e86a77 100644 --- a/src/layout.rs +++ b/src/layout.rs @@ -10,9 +10,11 @@ use crate::band::Band; use crate::bow::Bow; use crate::graph::{ BendIndex, BendWeight, DotIndex, DotWeight, GenericIndex, GetNodeIndex, Index, Interior, Label, - Retag, SegIndex, SegWeight, Weight, + MakePrimitive, Retag, SegIndex, SegWeight, Weight, +}; +use crate::primitive::{ + GenericPrimitive, GetConnectable, GetWeight, MakeShape, TaggedPrevTaggedNext, }; -use crate::primitive::{GenericPrimitive, GetWeight, MakeShape, TaggedPrevTaggedNext}; use crate::segbend::Segbend; use crate::shape::{Shape, ShapeTrait}; @@ -262,8 +264,7 @@ impl Layout { } pub fn shapes(&self) -> impl Iterator + '_ { - self.nodes() - .map(|ni| untag!(ni, self.primitive(ni).shape())) + self.nodes().map(|ni| ni.primitive(&self.graph).shape()) } pub fn node_count(&self) -> usize { @@ -324,16 +325,13 @@ impl Layout { } fn detect_collision_except(&self, index: Index, except: &[Index]) -> Option { - let shape = untag!(index, self.primitive(index).shape()); + let shape = index.primitive(&self.graph).shape(); self.rtree .locate_in_envelope_intersecting(&RTreeObject::envelope(&shape)) .filter(|wrapper| { let other_index = wrapper.data; - !untag!( - other_index, - untag!(index, self.primitive(index).connectable(other_index)) - ) + !index.primitive(&self.graph).connectable(other_index) }) .filter(|wrapper| !except.contains(&wrapper.data)) .filter(|wrapper| shape.intersects(wrapper.geom())) @@ -344,14 +342,14 @@ impl Layout { #[debug_ensures(self.graph.node_count() == old(self.graph.node_count()))] #[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count()))] fn insert_into_rtree(&mut self, index: Index) { - let shape = untag!(index, self.primitive(index).shape()); + let shape = index.primitive(&self.graph).shape(); self.rtree.insert(RTreeWrapper::new(shape, index)); } #[debug_ensures(self.graph.node_count() == old(self.graph.node_count()))] #[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count()))] fn remove_from_rtree(&mut self, index: Index) { - let shape = untag!(index, self.primitive(index).shape()); + let shape = index.primitive(&self.graph).shape(); let removed_element = self.rtree.remove(&RTreeWrapper::new(shape, index)); debug_assert!(removed_element.is_some()); } @@ -361,7 +359,7 @@ impl Layout { fn test_envelopes(&self) -> bool { !self.rtree.iter().any(|wrapper| { let index = wrapper.data; - let shape = untag!(index, GenericPrimitive::new(index, &self.graph).shape()); + let shape = index.primitive(&self.graph).shape(); let wrapper = RTreeWrapper::new(shape, index); !self .rtree diff --git a/src/primitive.rs b/src/primitive.rs index 05166b4..e768047 100644 --- a/src/primitive.rs +++ b/src/primitive.rs @@ -5,12 +5,35 @@ use petgraph::stable_graph::{NodeIndex, StableDiGraph}; use petgraph::Direction::{Incoming, Outgoing}; use crate::graph::{ - BendIndex, BendWeight, DotIndex, DotWeight, Ends, GenericIndex, GetNodeIndex, Index, Interior, - Label, Retag, SegWeight, Weight, + BendIndex, BendWeight, DotIndex, DotWeight, Ends, GenericIndex, GetNet, GetNodeIndex, Index, + Interior, Label, MakePrimitive, Retag, SegWeight, Weight, }; use crate::math::{self, Circle}; use crate::shape::{BendShape, DotShape, SegShape, Shape, ShapeTrait}; +#[enum_dispatch] +pub trait GetGraph { + fn graph(&self) -> &StableDiGraph; +} + +#[enum_dispatch] +pub trait GetConnectable: GetNet + GetGraph { + fn connectable(&self, index: Index) -> bool { + let this = self.net(); + let other = index.primitive(self.graph()).net(); + + if this == other { + true + } else if this == -1 || other == -1 { + true + } else if this == -2 || other == -2 { + false + } else { + this == other + } + } +} + #[enum_dispatch] pub trait TaggedPrevTaggedNext { fn tagged_prev(&self) -> Option; @@ -27,7 +50,7 @@ pub trait MakeShape { fn shape(&self) -> Shape; } -#[enum_dispatch(MakeShape, TaggedPrevTaggedNext)] +#[enum_dispatch(GetNet, GetGraph, GetConnectable, TaggedPrevTaggedNext, MakeShape)] pub enum Primitive<'a> { Dot(Dot<'a>), Seg(Seg<'a>), @@ -146,7 +169,7 @@ impl<'a, W> GenericPrimitive<'a, W> { .next() } - pub fn connectable(&self, index: GenericIndex) -> bool { + /*pub fn connectable(&self, index: GenericIndex) -> bool { let this = self.net(&self.index); let other = self.net(&index); @@ -167,7 +190,7 @@ impl<'a, W> GenericPrimitive<'a, W> { Weight::Seg(seg) => seg.net, Weight::Bend(bend) => bend.net, } - } + }*/ pub fn tagged_index(&self) -> Index { self.graph @@ -214,6 +237,26 @@ impl<'a, W> Ends for GenericPrimitive<'a, W> { } } +impl<'a, W> GetGraph for GenericPrimitive<'a, W> { + fn graph(&self) -> &StableDiGraph { + self.graph + } +} + +impl<'a, W: GetNet> GetConnectable for GenericPrimitive<'a, W> where + GenericPrimitive<'a, W>: GetWeight +{ +} + +impl<'a, W: GetNet> GetNet for GenericPrimitive<'a, W> +where + GenericPrimitive<'a, W>: GetWeight, +{ + fn net(&self) -> i64 { + self.weight().net() + } +} + impl<'a, W> TaggedPrevTaggedNext for GenericPrimitive<'a, W> { fn tagged_prev(&self) -> Option { self.prev_node()