layout: Combine primitive creation methods into generics

This commit is contained in:
Mikolaj Wielgus 2023-10-26 14:32:44 +00:00
parent 21ed14ae3d
commit 3619c5eab4
2 changed files with 86 additions and 95 deletions

View File

@ -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 {

View File

@ -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