mirror of https://codeberg.org/topola/topola.git
graph: Remove the `untag` macro
To accomplish this, some more methods are moved to traits.
This commit is contained in:
parent
4549de098c
commit
403e3e4f98
35
src/graph.rs
35
src/graph.rs
|
|
@ -21,7 +21,12 @@ pub trait Retag {
|
||||||
fn retag(&self, index: NodeIndex<usize>) -> Index;
|
fn retag(&self, index: NodeIndex<usize>) -> Index;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[enum_dispatch(Retag)]
|
#[enum_dispatch]
|
||||||
|
pub trait GetNet {
|
||||||
|
fn net(&self) -> i64;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[enum_dispatch(Retag, GetNet)]
|
||||||
#[derive(Debug, EnumAsInner, Clone, Copy, PartialEq)]
|
#[derive(Debug, EnumAsInner, Clone, Copy, PartialEq)]
|
||||||
pub enum Weight {
|
pub enum Weight {
|
||||||
Dot(DotWeight),
|
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)]
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
pub struct SegWeight {
|
pub struct SegWeight {
|
||||||
pub net: i64,
|
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)]
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
pub struct BendWeight {
|
pub struct BendWeight {
|
||||||
pub net: i64,
|
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)]
|
#[derive(Debug, EnumAsInner, Clone, Copy, PartialEq)]
|
||||||
pub enum Label {
|
pub enum Label {
|
||||||
End,
|
End,
|
||||||
|
|
@ -120,16 +143,6 @@ impl<W> GetNodeIndex for GenericIndex<W> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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<DotWeight>;
|
pub type DotIndex = GenericIndex<DotWeight>;
|
||||||
|
|
||||||
impl MakePrimitive for DotIndex {
|
impl MakePrimitive for DotIndex {
|
||||||
|
|
|
||||||
|
|
@ -10,9 +10,11 @@ use crate::band::Band;
|
||||||
use crate::bow::Bow;
|
use crate::bow::Bow;
|
||||||
use crate::graph::{
|
use crate::graph::{
|
||||||
BendIndex, BendWeight, DotIndex, DotWeight, GenericIndex, GetNodeIndex, Index, Interior, Label,
|
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::segbend::Segbend;
|
||||||
use crate::shape::{Shape, ShapeTrait};
|
use crate::shape::{Shape, ShapeTrait};
|
||||||
|
|
||||||
|
|
@ -262,8 +264,7 @@ impl Layout {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn shapes(&self) -> impl Iterator<Item = Shape> + '_ {
|
pub fn shapes(&self) -> impl Iterator<Item = Shape> + '_ {
|
||||||
self.nodes()
|
self.nodes().map(|ni| ni.primitive(&self.graph).shape())
|
||||||
.map(|ni| untag!(ni, self.primitive(ni).shape()))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn node_count(&self) -> usize {
|
pub fn node_count(&self) -> usize {
|
||||||
|
|
@ -324,16 +325,13 @@ impl Layout {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn detect_collision_except(&self, index: Index, except: &[Index]) -> Option<Index> {
|
fn detect_collision_except(&self, index: Index, except: &[Index]) -> Option<Index> {
|
||||||
let shape = untag!(index, self.primitive(index).shape());
|
let shape = index.primitive(&self.graph).shape();
|
||||||
|
|
||||||
self.rtree
|
self.rtree
|
||||||
.locate_in_envelope_intersecting(&RTreeObject::envelope(&shape))
|
.locate_in_envelope_intersecting(&RTreeObject::envelope(&shape))
|
||||||
.filter(|wrapper| {
|
.filter(|wrapper| {
|
||||||
let other_index = wrapper.data;
|
let other_index = wrapper.data;
|
||||||
!untag!(
|
!index.primitive(&self.graph).connectable(other_index)
|
||||||
other_index,
|
|
||||||
untag!(index, self.primitive(index).connectable(other_index))
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
.filter(|wrapper| !except.contains(&wrapper.data))
|
.filter(|wrapper| !except.contains(&wrapper.data))
|
||||||
.filter(|wrapper| shape.intersects(wrapper.geom()))
|
.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.node_count() == old(self.graph.node_count()))]
|
||||||
#[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count()))]
|
#[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count()))]
|
||||||
fn insert_into_rtree(&mut self, index: Index) {
|
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));
|
self.rtree.insert(RTreeWrapper::new(shape, index));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[debug_ensures(self.graph.node_count() == old(self.graph.node_count()))]
|
#[debug_ensures(self.graph.node_count() == old(self.graph.node_count()))]
|
||||||
#[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count()))]
|
#[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count()))]
|
||||||
fn remove_from_rtree(&mut self, index: Index) {
|
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));
|
let removed_element = self.rtree.remove(&RTreeWrapper::new(shape, index));
|
||||||
debug_assert!(removed_element.is_some());
|
debug_assert!(removed_element.is_some());
|
||||||
}
|
}
|
||||||
|
|
@ -361,7 +359,7 @@ impl Layout {
|
||||||
fn test_envelopes(&self) -> bool {
|
fn test_envelopes(&self) -> bool {
|
||||||
!self.rtree.iter().any(|wrapper| {
|
!self.rtree.iter().any(|wrapper| {
|
||||||
let index = wrapper.data;
|
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);
|
let wrapper = RTreeWrapper::new(shape, index);
|
||||||
!self
|
!self
|
||||||
.rtree
|
.rtree
|
||||||
|
|
|
||||||
|
|
@ -5,12 +5,35 @@ use petgraph::stable_graph::{NodeIndex, StableDiGraph};
|
||||||
use petgraph::Direction::{Incoming, Outgoing};
|
use petgraph::Direction::{Incoming, Outgoing};
|
||||||
|
|
||||||
use crate::graph::{
|
use crate::graph::{
|
||||||
BendIndex, BendWeight, DotIndex, DotWeight, Ends, GenericIndex, GetNodeIndex, Index, Interior,
|
BendIndex, BendWeight, DotIndex, DotWeight, Ends, GenericIndex, GetNet, GetNodeIndex, Index,
|
||||||
Label, Retag, SegWeight, Weight,
|
Interior, Label, MakePrimitive, Retag, SegWeight, Weight,
|
||||||
};
|
};
|
||||||
use crate::math::{self, Circle};
|
use crate::math::{self, Circle};
|
||||||
use crate::shape::{BendShape, DotShape, SegShape, Shape, ShapeTrait};
|
use crate::shape::{BendShape, DotShape, SegShape, Shape, ShapeTrait};
|
||||||
|
|
||||||
|
#[enum_dispatch]
|
||||||
|
pub trait GetGraph {
|
||||||
|
fn graph(&self) -> &StableDiGraph<Weight, Label, usize>;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[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]
|
#[enum_dispatch]
|
||||||
pub trait TaggedPrevTaggedNext {
|
pub trait TaggedPrevTaggedNext {
|
||||||
fn tagged_prev(&self) -> Option<Index>;
|
fn tagged_prev(&self) -> Option<Index>;
|
||||||
|
|
@ -27,7 +50,7 @@ pub trait MakeShape {
|
||||||
fn shape(&self) -> Shape;
|
fn shape(&self) -> Shape;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[enum_dispatch(MakeShape, TaggedPrevTaggedNext)]
|
#[enum_dispatch(GetNet, GetGraph, GetConnectable, TaggedPrevTaggedNext, MakeShape)]
|
||||||
pub enum Primitive<'a> {
|
pub enum Primitive<'a> {
|
||||||
Dot(Dot<'a>),
|
Dot(Dot<'a>),
|
||||||
Seg(Seg<'a>),
|
Seg(Seg<'a>),
|
||||||
|
|
@ -146,7 +169,7 @@ impl<'a, W> GenericPrimitive<'a, W> {
|
||||||
.next()
|
.next()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn connectable<WW>(&self, index: GenericIndex<WW>) -> bool {
|
/*pub fn connectable<WW>(&self, index: GenericIndex<WW>) -> bool {
|
||||||
let this = self.net(&self.index);
|
let this = self.net(&self.index);
|
||||||
let other = self.net(&index);
|
let other = self.net(&index);
|
||||||
|
|
||||||
|
|
@ -167,7 +190,7 @@ impl<'a, W> GenericPrimitive<'a, W> {
|
||||||
Weight::Seg(seg) => seg.net,
|
Weight::Seg(seg) => seg.net,
|
||||||
Weight::Bend(bend) => bend.net,
|
Weight::Bend(bend) => bend.net,
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
pub fn tagged_index(&self) -> Index {
|
pub fn tagged_index(&self) -> Index {
|
||||||
self.graph
|
self.graph
|
||||||
|
|
@ -214,6 +237,26 @@ impl<'a, W> Ends<DotIndex, DotIndex> for GenericPrimitive<'a, W> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a, W> GetGraph for GenericPrimitive<'a, W> {
|
||||||
|
fn graph(&self) -> &StableDiGraph<Weight, Label, usize> {
|
||||||
|
self.graph
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, W: GetNet> GetConnectable for GenericPrimitive<'a, W> where
|
||||||
|
GenericPrimitive<'a, W>: GetWeight<W>
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, W: GetNet> GetNet for GenericPrimitive<'a, W>
|
||||||
|
where
|
||||||
|
GenericPrimitive<'a, W>: GetWeight<W>,
|
||||||
|
{
|
||||||
|
fn net(&self) -> i64 {
|
||||||
|
self.weight().net()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a, W> TaggedPrevTaggedNext for GenericPrimitive<'a, W> {
|
impl<'a, W> TaggedPrevTaggedNext for GenericPrimitive<'a, W> {
|
||||||
fn tagged_prev(&self) -> Option<Index> {
|
fn tagged_prev(&self) -> Option<Index> {
|
||||||
self.prev_node()
|
self.prev_node()
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue