mirror of https://codeberg.org/topola/topola.git
layout: Combine primitive creation methods into generics
This commit is contained in:
parent
21ed14ae3d
commit
3619c5eab4
27
src/graph.rs
27
src/graph.rs
|
|
@ -27,30 +27,30 @@ pub trait GetNet {
|
|||
}
|
||||
|
||||
macro_rules! impl_type {
|
||||
($weight_struct_name:ident, $weight_variant_name:ident, $index_struct_name:ident) => {
|
||||
impl Retag for $weight_struct_name {
|
||||
($weight_struct:ident, $weight_variant:ident, $index_struct:ident) => {
|
||||
impl Retag for $weight_struct {
|
||||
fn retag(&self, index: NodeIndex<usize>) -> Index {
|
||||
Index::$weight_variant_name($index_struct_name {
|
||||
Index::$weight_variant($index_struct {
|
||||
node_index: index,
|
||||
marker: PhantomData,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl GetNet for $weight_struct_name {
|
||||
impl GetNet for $weight_struct {
|
||||
fn net(&self) -> i64 {
|
||||
self.net
|
||||
}
|
||||
}
|
||||
|
||||
pub type $index_struct_name = GenericIndex<$weight_struct_name>;
|
||||
pub type $index_struct = GenericIndex<$weight_struct>;
|
||||
|
||||
impl MakePrimitive for $index_struct_name {
|
||||
impl MakePrimitive for $index_struct {
|
||||
fn primitive<'a>(
|
||||
&self,
|
||||
graph: &'a StableDiGraph<Weight, Label, usize>,
|
||||
) -> Primitive<'a> {
|
||||
Primitive::$weight_variant_name(GenericPrimitive::new(*self, graph))
|
||||
Primitive::$weight_variant(GenericPrimitive::new(*self, graph))
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -137,6 +137,8 @@ impl From<BendIndex> for Index {
|
|||
}
|
||||
}
|
||||
|
||||
pub trait DotWeight: GetNet + Into<Weight> + Copy {}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub struct FixedDotWeight {
|
||||
pub net: i64,
|
||||
|
|
@ -144,6 +146,7 @@ pub struct FixedDotWeight {
|
|||
}
|
||||
|
||||
impl_type!(FixedDotWeight, FixedDot, FixedDotIndex);
|
||||
impl DotWeight for FixedDotWeight {}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub struct LooseDotWeight {
|
||||
|
|
@ -152,6 +155,9 @@ pub struct LooseDotWeight {
|
|||
}
|
||||
|
||||
impl_type!(LooseDotWeight, LooseDot, LooseDotIndex);
|
||||
impl DotWeight for LooseDotWeight {}
|
||||
|
||||
pub trait SegWeight: GetNet + Into<Weight> + Copy {}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub struct FixedSegWeight {
|
||||
|
|
@ -160,6 +166,7 @@ pub struct FixedSegWeight {
|
|||
}
|
||||
|
||||
impl_type!(FixedSegWeight, FixedSeg, FixedSegIndex);
|
||||
impl SegWeight for FixedSegWeight {}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub struct HalfLooseSegWeight {
|
||||
|
|
@ -168,6 +175,7 @@ pub struct HalfLooseSegWeight {
|
|||
}
|
||||
|
||||
impl_type!(HalfLooseSegWeight, HalfLooseSeg, HalfLooseSegIndex);
|
||||
impl SegWeight for HalfLooseSegWeight {}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub struct FullyLooseSegWeight {
|
||||
|
|
@ -176,6 +184,9 @@ pub struct FullyLooseSegWeight {
|
|||
}
|
||||
|
||||
impl_type!(FullyLooseSegWeight, FullyLooseSeg, FullyLooseSegIndex);
|
||||
impl SegWeight for FullyLooseSegWeight {}
|
||||
|
||||
pub trait BendWeight: GetNet + Into<Weight> + Copy {}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub struct FixedBendWeight {
|
||||
|
|
@ -184,6 +195,7 @@ pub struct FixedBendWeight {
|
|||
}
|
||||
|
||||
impl_type!(FixedBendWeight, FixedBend, FixedBendIndex);
|
||||
impl BendWeight for FixedBendWeight {}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub struct LooseBendWeight {
|
||||
|
|
@ -192,6 +204,7 @@ pub struct LooseBendWeight {
|
|||
}
|
||||
|
||||
impl_type!(LooseBendWeight, LooseBend, LooseBendIndex);
|
||||
impl BendWeight for LooseBendWeight {}
|
||||
|
||||
#[derive(Debug, EnumAsInner, Clone, Copy, PartialEq)]
|
||||
pub enum Label {
|
||||
|
|
|
|||
154
src/layout.rs
154
src/layout.rs
|
|
@ -8,9 +8,10 @@ use rstar::{RTree, RTreeObject};
|
|||
|
||||
use crate::bow::Bow;
|
||||
use crate::graph::{
|
||||
FixedBendIndex, FixedBendWeight, FixedDotIndex, FixedDotWeight, FixedSegIndex, FixedSegWeight,
|
||||
GenericIndex, GetNodeIndex, HalfLooseSegWeight, Index, Interior, Label, LooseDotIndex,
|
||||
LooseDotWeight, MakePrimitive, Retag, Weight,
|
||||
BendWeight, DotIndex, DotWeight, FixedBendIndex, FixedBendWeight, FixedDotIndex,
|
||||
FixedDotWeight, FixedSegIndex, FixedSegWeight, FullyLooseSegIndex, FullyLooseSegWeight,
|
||||
GenericIndex, GetNodeIndex, HalfLooseSegIndex, HalfLooseSegWeight, Index, Interior, Label,
|
||||
LooseDotIndex, LooseDotWeight, LooseSegIndex, MakePrimitive, Retag, SegWeight, Weight,
|
||||
};
|
||||
use crate::primitive::{GenericPrimitive, GetConnectable, GetWeight, MakeShape};
|
||||
use crate::segbend::Segbend;
|
||||
|
|
@ -64,9 +65,17 @@ impl Layout {
|
|||
self.graph.remove_node(index.node_index());
|
||||
}
|
||||
|
||||
#[debug_ensures(self.graph.node_count() == old(self.graph.node_count() + 1))]
|
||||
#[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count() + 1))]
|
||||
pub fn add_fixed_dot(&mut self, weight: FixedDotWeight) -> Result<FixedDotIndex, ()> {
|
||||
let dot = FixedDotIndex::new(self.graph.add_node(weight.into()));
|
||||
self.add_dot(weight)
|
||||
}
|
||||
|
||||
#[debug_ensures(self.graph.node_count() == old(self.graph.node_count() + 1))]
|
||||
fn add_dot<W: DotWeight>(&mut self, weight: W) -> Result<GenericIndex<W>, ()>
|
||||
where
|
||||
GenericIndex<W>: Into<Index> + Copy,
|
||||
{
|
||||
let dot = GenericIndex::<W>::new(self.graph.add_node(weight.into()));
|
||||
|
||||
self.insert_into_rtree(dot.into());
|
||||
self.fail_and_remove_if_collides_except(dot.into(), &[])?;
|
||||
|
|
@ -74,93 +83,59 @@ impl Layout {
|
|||
Ok(dot)
|
||||
}
|
||||
|
||||
#[debug_ensures(self.graph.node_count() == old(self.graph.node_count() + 1))]
|
||||
pub fn add_loose_dot(&mut self, weight: LooseDotWeight) -> Result<LooseDotIndex, ()> {
|
||||
let dot = LooseDotIndex::new(self.graph.add_node(weight.into()));
|
||||
|
||||
self.insert_into_rtree(dot.into());
|
||||
self.fail_and_remove_if_collides_except(dot.into(), &[])?;
|
||||
|
||||
Ok(dot)
|
||||
}
|
||||
|
||||
#[debug_ensures(self.graph.node_count() == old(self.graph.node_count() + 1))]
|
||||
#[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count() + 2))]
|
||||
#[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count() + 1))]
|
||||
#[debug_ensures(ret.is_ok() -> self.graph.edge_count() == old(self.graph.edge_count() + 2))]
|
||||
#[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))]
|
||||
#[debug_ensures(ret.is_err() -> self.graph.edge_count() == old(self.graph.edge_count()))]
|
||||
pub fn add_fixed_seg(
|
||||
&mut self,
|
||||
from: FixedDotIndex,
|
||||
to: FixedDotIndex,
|
||||
weight: FixedSegWeight,
|
||||
) -> Result<FixedSegIndex, ()> {
|
||||
let seg = FixedSegIndex::new(self.graph.add_node(weight.into()));
|
||||
|
||||
self.graph
|
||||
.add_edge(from.node_index(), seg.node_index(), Label::Adjacent);
|
||||
self.graph
|
||||
.add_edge(seg.node_index(), to.node_index(), Label::Adjacent);
|
||||
|
||||
self.insert_into_rtree(seg.into());
|
||||
self.fail_and_remove_if_collides_except(seg.into(), &[])?;
|
||||
|
||||
self.graph
|
||||
.node_weight_mut(from.node_index())
|
||||
.unwrap()
|
||||
.as_fixed_dot_mut()
|
||||
.unwrap()
|
||||
.net = weight.net;
|
||||
self.graph
|
||||
.node_weight_mut(to.node_index())
|
||||
.unwrap()
|
||||
.as_fixed_dot_mut()
|
||||
.unwrap()
|
||||
.net = weight.net;
|
||||
|
||||
Ok(seg)
|
||||
self.add_seg(from, to, weight)
|
||||
}
|
||||
|
||||
#[debug_ensures(self.graph.node_count() == old(self.graph.node_count() + 1))]
|
||||
#[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count() + 2))]
|
||||
#[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count() + 1))]
|
||||
#[debug_ensures(ret.is_ok() -> self.graph.edge_count() == old(self.graph.edge_count() + 2))]
|
||||
#[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))]
|
||||
#[debug_ensures(ret.is_err() -> self.graph.edge_count() == old(self.graph.edge_count()))]
|
||||
pub fn add_half_loose_seg(
|
||||
&mut self,
|
||||
from: FixedDotIndex,
|
||||
to: LooseDotIndex,
|
||||
weight: HalfLooseSegWeight,
|
||||
) -> Result<FixedSegIndex, ()> {
|
||||
let seg = FixedSegIndex::new(self.graph.add_node(weight.into()));
|
||||
|
||||
self.graph
|
||||
.add_edge(from.node_index(), seg.node_index(), Label::Adjacent);
|
||||
self.graph
|
||||
.add_edge(seg.node_index(), to.node_index(), Label::Adjacent);
|
||||
|
||||
self.insert_into_rtree(seg.into());
|
||||
self.fail_and_remove_if_collides_except(seg.into(), &[])?;
|
||||
|
||||
self.graph
|
||||
.node_weight_mut(from.node_index())
|
||||
.unwrap()
|
||||
.as_fixed_dot_mut()
|
||||
.unwrap()
|
||||
.net = weight.net;
|
||||
self.graph
|
||||
.node_weight_mut(to.node_index())
|
||||
.unwrap()
|
||||
.as_fixed_dot_mut()
|
||||
.unwrap()
|
||||
.net = weight.net;
|
||||
|
||||
Ok(seg)
|
||||
) -> Result<HalfLooseSegIndex, ()> {
|
||||
self.add_seg(from, to, weight)
|
||||
}
|
||||
|
||||
#[debug_ensures(self.graph.node_count() == old(self.graph.node_count() + 1))]
|
||||
#[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count() + 2))]
|
||||
pub fn add_loose_seg(
|
||||
#[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count() + 1))]
|
||||
#[debug_ensures(ret.is_ok() -> self.graph.edge_count() == old(self.graph.edge_count() + 2))]
|
||||
#[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))]
|
||||
#[debug_ensures(ret.is_err() -> self.graph.edge_count() == old(self.graph.edge_count()))]
|
||||
pub fn add_fully_loose_seg(
|
||||
&mut self,
|
||||
from: LooseDotIndex,
|
||||
to: LooseDotIndex,
|
||||
weight: HalfLooseSegWeight,
|
||||
) -> Result<FixedSegIndex, ()> {
|
||||
let seg = FixedSegIndex::new(self.graph.add_node(weight.into()));
|
||||
weight: FullyLooseSegWeight,
|
||||
) -> Result<FullyLooseSegIndex, ()> {
|
||||
self.add_seg(from, to, weight)
|
||||
}
|
||||
|
||||
#[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count() + 1))]
|
||||
#[debug_ensures(ret.is_ok() -> self.graph.edge_count() == old(self.graph.edge_count() + 2))]
|
||||
#[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))]
|
||||
#[debug_ensures(ret.is_err() -> self.graph.edge_count() == old(self.graph.edge_count()))]
|
||||
fn add_seg<W: SegWeight>(
|
||||
&mut self,
|
||||
from: impl GetNodeIndex,
|
||||
to: impl GetNodeIndex,
|
||||
weight: W,
|
||||
) -> Result<GenericIndex<W>, ()>
|
||||
where
|
||||
GenericIndex<W>: Into<Index> + Copy,
|
||||
{
|
||||
let seg = GenericIndex::<W>::new(self.graph.add_node(weight.into()));
|
||||
|
||||
self.graph
|
||||
.add_edge(from.node_index(), seg.node_index(), Label::Adjacent);
|
||||
|
|
@ -175,13 +150,13 @@ impl Layout {
|
|||
.unwrap()
|
||||
.as_fixed_dot_mut()
|
||||
.unwrap()
|
||||
.net = weight.net;
|
||||
.net = weight.net();
|
||||
self.graph
|
||||
.node_weight_mut(to.node_index())
|
||||
.unwrap()
|
||||
.as_fixed_dot_mut()
|
||||
.unwrap()
|
||||
.net = weight.net;
|
||||
.net = weight.net();
|
||||
|
||||
Ok(seg)
|
||||
}
|
||||
|
|
@ -202,7 +177,7 @@ impl Layout {
|
|||
}
|
||||
}
|
||||
|
||||
/*#[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count() + 1))]
|
||||
#[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count() + 1))]
|
||||
#[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))]
|
||||
pub fn add_loose_bend(
|
||||
&mut self,
|
||||
|
|
@ -216,19 +191,22 @@ impl Layout {
|
|||
Index::FixedBend(around) => self.add_outer_bend(from, to, around, weight),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
#[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count() + 1))]
|
||||
#[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))]
|
||||
#[debug_ensures(ret.is_ok() -> self.graph.edge_count() == old(self.graph.edge_count() + 3))]
|
||||
#[debug_ensures(ret.is_err() -> self.graph.edge_count() == old(self.graph.edge_count()))]
|
||||
pub fn add_core_bend(
|
||||
fn add_core_bend<W: BendWeight>(
|
||||
&mut self,
|
||||
from: FixedDotIndex,
|
||||
to: FixedDotIndex,
|
||||
from: impl GetNodeIndex,
|
||||
to: impl GetNodeIndex,
|
||||
core: FixedDotIndex,
|
||||
weight: FixedBendWeight,
|
||||
) -> Result<FixedBendIndex, ()> {
|
||||
weight: W,
|
||||
) -> Result<FixedBendIndex, ()>
|
||||
where
|
||||
GenericIndex<W>: Into<Index> + Copy,
|
||||
{
|
||||
let bend = FixedBendIndex::new(self.graph.add_node(weight.into()));
|
||||
|
||||
self.graph
|
||||
|
|
@ -247,12 +225,12 @@ impl Layout {
|
|||
#[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))]
|
||||
#[debug_ensures(ret.is_ok() -> self.graph.edge_count() == old(self.graph.edge_count() + 4))]
|
||||
#[debug_ensures(ret.is_err() -> self.graph.edge_count() == old(self.graph.edge_count()))]
|
||||
pub fn add_outer_bend(
|
||||
fn add_outer_bend<W: BendWeight>(
|
||||
&mut self,
|
||||
from: FixedDotIndex,
|
||||
to: FixedDotIndex,
|
||||
inner: FixedBendIndex,
|
||||
weight: FixedBendWeight,
|
||||
from: impl GetNodeIndex,
|
||||
to: impl GetNodeIndex,
|
||||
inner: impl GetNodeIndex,
|
||||
weight: W,
|
||||
) -> Result<FixedBendIndex, ()> {
|
||||
let core = *self
|
||||
.graph
|
||||
|
|
|
|||
Loading…
Reference in New Issue