mirror of https://codeberg.org/topola/topola.git
graph: Move `retag` to an enum-dispatched trait
This commit is contained in:
parent
b7ff507302
commit
ae9dd23b7c
|
|
@ -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<TaggedWeight, Label, usize>,
|
||||
graph: &StableDiGraph<Weight, Label, usize>,
|
||||
) -> Option<Self> {
|
||||
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<TaggedWeight, Label, usize>,
|
||||
graph: &StableDiGraph<Weight, Label, usize>,
|
||||
) -> Option<Self> {
|
||||
let mut prev_index = dot.tag();
|
||||
let mut interior = vec![];
|
||||
|
|
|
|||
|
|
@ -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<TaggedWeight, Label, usize>) -> Self {
|
||||
pub fn from_bend(index: BendIndex, graph: &StableDiGraph<Weight, Label, usize>) -> Self {
|
||||
let bend = index;
|
||||
|
||||
let seg1_dot2 = Bend::new(bend, graph).prev().unwrap();
|
||||
|
|
|
|||
61
src/graph.rs
61
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<Start, Stop> {
|
|||
fn ends(&self) -> (Start, Stop);
|
||||
}
|
||||
|
||||
#[enum_dispatch]
|
||||
pub trait Retag {
|
||||
fn retag(&self, index: NodeIndex<usize>) -> 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<usize>) -> 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<usize>) -> 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<usize>) -> TaggedIndex {
|
||||
TaggedIndex::Bend(BendIndex {
|
||||
index,
|
||||
marker: PhantomData,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, EnumAsInner, Clone, Copy, PartialEq)]
|
||||
pub enum Label {
|
||||
End,
|
||||
|
|
@ -64,23 +98,6 @@ impl<T> Index<T> {
|
|||
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 {
|
||||
|
|
|
|||
|
|
@ -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<Shape, TaggedIndex>;
|
|||
|
||||
pub struct Layout {
|
||||
rtree: RTree<RTreeWrapper>,
|
||||
pub graph: StableDiGraph<TaggedWeight, Label, usize>,
|
||||
pub graph: StableDiGraph<Weight, Label, usize>,
|
||||
}
|
||||
|
||||
#[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<DotIndex, ()> {
|
||||
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<SegIndex, ()> {
|
||||
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<BendIndex, ()> {
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -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<Weight>,
|
||||
graph: &'a StableDiGraph<TaggedWeight, Label, usize>,
|
||||
pub struct Primitive<'a, W> {
|
||||
pub index: Index<W>,
|
||||
graph: &'a StableDiGraph<Weight, Label, usize>,
|
||||
}
|
||||
|
||||
impl<'a, Weight> Primitive<'a, Weight> {
|
||||
pub fn new(index: Index<Weight>, graph: &'a StableDiGraph<TaggedWeight, Label, usize>) -> Self {
|
||||
impl<'a, W> Primitive<'a, W> {
|
||||
pub fn new(index: Index<W>, graph: &'a StableDiGraph<Weight, Label, usize>) -> 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<Item = TaggedIndex> + '_ {
|
||||
self.graph
|
||||
.neighbors_undirected(self.index.index)
|
||||
.map(|index| Index::<Label>::new(index).retag(self.graph.node_weight(index).unwrap()))
|
||||
.map(|index| self.graph.node_weight(index).unwrap().retag(index))
|
||||
}
|
||||
|
||||
pub fn prev_bend(&self) -> Option<BendIndex> {
|
||||
|
|
@ -99,7 +99,7 @@ impl<'a, Weight> Primitive<'a, Weight> {
|
|||
{
|
||||
let weight = *self.graph.node_weight(index).unwrap();
|
||||
|
||||
if let Some(TaggedWeight::Bend(..)) = self.graph.node_weight(index) {
|
||||
if let Some(Weight::Bend(..)) = self.graph.node_weight(index) {
|
||||
return Some(BendIndex::new(index));
|
||||
}
|
||||
|
||||
|
|
@ -111,7 +111,7 @@ impl<'a, Weight> Primitive<'a, Weight> {
|
|||
|
||||
pub fn tagged_prev(&self) -> Option<TaggedIndex> {
|
||||
self.prev_node()
|
||||
.map(|ni| Index::<Label>::new(ni).retag(self.graph.node_weight(ni).unwrap()))
|
||||
.map(|ni| self.graph.node_weight(ni).unwrap().retag(ni))
|
||||
}
|
||||
|
||||
fn prev_node(&self) -> Option<NodeIndex<usize>> {
|
||||
|
|
@ -145,7 +145,7 @@ impl<'a, Weight> Primitive<'a, Weight> {
|
|||
{
|
||||
let weight = *self.graph.node_weight(index).unwrap();
|
||||
|
||||
if let Some(TaggedWeight::Bend(..)) = self.graph.node_weight(index) {
|
||||
if let Some(Weight::Bend(..)) = self.graph.node_weight(index) {
|
||||
return Some(BendIndex::new(index));
|
||||
}
|
||||
|
||||
|
|
@ -157,7 +157,7 @@ impl<'a, Weight> Primitive<'a, Weight> {
|
|||
|
||||
pub fn tagged_next(&self) -> Option<TaggedIndex> {
|
||||
self.next_node()
|
||||
.map(|ni| Index::<Label>::new(ni).retag(self.graph.node_weight(ni).unwrap()))
|
||||
.map(|ni| self.graph.node_weight(ni).unwrap().retag(ni))
|
||||
}
|
||||
|
||||
fn next_node(&self) -> Option<NodeIndex<usize>> {
|
||||
|
|
@ -185,7 +185,7 @@ impl<'a, Weight> Primitive<'a, Weight> {
|
|||
.next()
|
||||
}
|
||||
|
||||
pub fn connectable<W>(&self, index: Index<W>) -> bool {
|
||||
pub fn connectable<WW>(&self, index: Index<WW>) -> bool {
|
||||
let this = self.net(&self.index);
|
||||
let other = self.net(&index);
|
||||
|
||||
|
|
@ -200,24 +200,26 @@ impl<'a, Weight> Primitive<'a, Weight> {
|
|||
}
|
||||
}
|
||||
|
||||
fn net<W>(&self, index: &Index<W>) -> i64 {
|
||||
fn net<WW>(&self, index: &Index<WW>) -> i64 {
|
||||
match self.graph.node_weight(index.index).unwrap() {
|
||||
TaggedWeight::Dot(dot) => dot.net,
|
||||
TaggedWeight::Seg(seg) => seg.net,
|
||||
TaggedWeight::Bend(bend) => bend.net,
|
||||
Weight::Dot(dot) => dot.net,
|
||||
Weight::Seg(seg) => seg.net,
|
||||
Weight::Bend(bend) => bend.net,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn tagged_index(&self) -> TaggedIndex {
|
||||
self.index
|
||||
.retag(self.graph.node_weight(self.index.index).unwrap())
|
||||
self.graph
|
||||
.node_weight(self.index.index)
|
||||
.unwrap()
|
||||
.retag(self.index.index)
|
||||
}
|
||||
|
||||
pub fn tagged_weight(&self) -> TaggedWeight {
|
||||
pub fn tagged_weight(&self) -> Weight {
|
||||
*self.graph.node_weight(self.index.index).unwrap()
|
||||
}
|
||||
|
||||
fn primitive<W>(&self, index: Index<W>) -> Primitive<W> {
|
||||
fn primitive<WW>(&self, index: Index<WW>) -> Primitive<WW> {
|
||||
Primitive::new(index, &self.graph)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use petgraph::stable_graph::StableDiGraph;
|
||||
|
||||
use crate::{
|
||||
graph::{BendIndex, DotIndex, Ends, Interior, Label, SegIndex, TaggedIndex, TaggedWeight},
|
||||
graph::{BendIndex, DotIndex, Ends, Interior, Label, SegIndex, TaggedIndex, Weight},
|
||||
primitive::{Bend, Dot},
|
||||
};
|
||||
|
||||
|
|
@ -19,7 +19,7 @@ impl Segbend {
|
|||
|
||||
pub fn from_dot_prev(
|
||||
dot: DotIndex,
|
||||
graph: &StableDiGraph<TaggedWeight, Label, usize>,
|
||||
graph: &StableDiGraph<Weight, Label, usize>,
|
||||
) -> Option<Self> {
|
||||
let bend = *Dot::new(dot, graph).tagged_prev()?.as_bend()?;
|
||||
let dot = Bend::new(bend, graph).prev().unwrap();
|
||||
|
|
@ -33,7 +33,7 @@ impl Segbend {
|
|||
|
||||
pub fn from_dot_next(
|
||||
dot: DotIndex,
|
||||
graph: &StableDiGraph<TaggedWeight, Label, usize>,
|
||||
graph: &StableDiGraph<Weight, Label, usize>,
|
||||
) -> Option<Self> {
|
||||
let bend = *Dot::new(dot, graph).tagged_next()?.as_bend()?;
|
||||
let dot = Bend::new(bend, graph).next().unwrap();
|
||||
|
|
|
|||
Loading…
Reference in New Issue