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 {
|
macro_rules! impl_type {
|
||||||
($weight_struct_name:ident, $weight_variant_name:ident, $index_struct_name:ident) => {
|
($weight_struct:ident, $weight_variant:ident, $index_struct:ident) => {
|
||||||
impl Retag for $weight_struct_name {
|
impl Retag for $weight_struct {
|
||||||
fn retag(&self, index: NodeIndex<usize>) -> Index {
|
fn retag(&self, index: NodeIndex<usize>) -> Index {
|
||||||
Index::$weight_variant_name($index_struct_name {
|
Index::$weight_variant($index_struct {
|
||||||
node_index: index,
|
node_index: index,
|
||||||
marker: PhantomData,
|
marker: PhantomData,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GetNet for $weight_struct_name {
|
impl GetNet for $weight_struct {
|
||||||
fn net(&self) -> i64 {
|
fn net(&self) -> i64 {
|
||||||
self.net
|
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>(
|
fn primitive<'a>(
|
||||||
&self,
|
&self,
|
||||||
graph: &'a StableDiGraph<Weight, Label, usize>,
|
graph: &'a StableDiGraph<Weight, Label, usize>,
|
||||||
) -> Primitive<'a> {
|
) -> 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)]
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
pub struct FixedDotWeight {
|
pub struct FixedDotWeight {
|
||||||
pub net: i64,
|
pub net: i64,
|
||||||
|
|
@ -144,6 +146,7 @@ pub struct FixedDotWeight {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_type!(FixedDotWeight, FixedDot, FixedDotIndex);
|
impl_type!(FixedDotWeight, FixedDot, FixedDotIndex);
|
||||||
|
impl DotWeight for FixedDotWeight {}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
pub struct LooseDotWeight {
|
pub struct LooseDotWeight {
|
||||||
|
|
@ -152,6 +155,9 @@ pub struct LooseDotWeight {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_type!(LooseDotWeight, LooseDot, LooseDotIndex);
|
impl_type!(LooseDotWeight, LooseDot, LooseDotIndex);
|
||||||
|
impl DotWeight for LooseDotWeight {}
|
||||||
|
|
||||||
|
pub trait SegWeight: GetNet + Into<Weight> + Copy {}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
pub struct FixedSegWeight {
|
pub struct FixedSegWeight {
|
||||||
|
|
@ -160,6 +166,7 @@ pub struct FixedSegWeight {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_type!(FixedSegWeight, FixedSeg, FixedSegIndex);
|
impl_type!(FixedSegWeight, FixedSeg, FixedSegIndex);
|
||||||
|
impl SegWeight for FixedSegWeight {}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
pub struct HalfLooseSegWeight {
|
pub struct HalfLooseSegWeight {
|
||||||
|
|
@ -168,6 +175,7 @@ pub struct HalfLooseSegWeight {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_type!(HalfLooseSegWeight, HalfLooseSeg, HalfLooseSegIndex);
|
impl_type!(HalfLooseSegWeight, HalfLooseSeg, HalfLooseSegIndex);
|
||||||
|
impl SegWeight for HalfLooseSegWeight {}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
pub struct FullyLooseSegWeight {
|
pub struct FullyLooseSegWeight {
|
||||||
|
|
@ -176,6 +184,9 @@ pub struct FullyLooseSegWeight {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_type!(FullyLooseSegWeight, FullyLooseSeg, FullyLooseSegIndex);
|
impl_type!(FullyLooseSegWeight, FullyLooseSeg, FullyLooseSegIndex);
|
||||||
|
impl SegWeight for FullyLooseSegWeight {}
|
||||||
|
|
||||||
|
pub trait BendWeight: GetNet + Into<Weight> + Copy {}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
pub struct FixedBendWeight {
|
pub struct FixedBendWeight {
|
||||||
|
|
@ -184,6 +195,7 @@ pub struct FixedBendWeight {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_type!(FixedBendWeight, FixedBend, FixedBendIndex);
|
impl_type!(FixedBendWeight, FixedBend, FixedBendIndex);
|
||||||
|
impl BendWeight for FixedBendWeight {}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
pub struct LooseBendWeight {
|
pub struct LooseBendWeight {
|
||||||
|
|
@ -192,6 +204,7 @@ pub struct LooseBendWeight {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_type!(LooseBendWeight, LooseBend, LooseBendIndex);
|
impl_type!(LooseBendWeight, LooseBend, LooseBendIndex);
|
||||||
|
impl BendWeight for LooseBendWeight {}
|
||||||
|
|
||||||
#[derive(Debug, EnumAsInner, Clone, Copy, PartialEq)]
|
#[derive(Debug, EnumAsInner, Clone, Copy, PartialEq)]
|
||||||
pub enum Label {
|
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::bow::Bow;
|
||||||
use crate::graph::{
|
use crate::graph::{
|
||||||
FixedBendIndex, FixedBendWeight, FixedDotIndex, FixedDotWeight, FixedSegIndex, FixedSegWeight,
|
BendWeight, DotIndex, DotWeight, FixedBendIndex, FixedBendWeight, FixedDotIndex,
|
||||||
GenericIndex, GetNodeIndex, HalfLooseSegWeight, Index, Interior, Label, LooseDotIndex,
|
FixedDotWeight, FixedSegIndex, FixedSegWeight, FullyLooseSegIndex, FullyLooseSegWeight,
|
||||||
LooseDotWeight, MakePrimitive, Retag, Weight,
|
GenericIndex, GetNodeIndex, HalfLooseSegIndex, HalfLooseSegWeight, Index, Interior, Label,
|
||||||
|
LooseDotIndex, LooseDotWeight, LooseSegIndex, MakePrimitive, Retag, SegWeight, Weight,
|
||||||
};
|
};
|
||||||
use crate::primitive::{GenericPrimitive, GetConnectable, GetWeight, MakeShape};
|
use crate::primitive::{GenericPrimitive, GetConnectable, GetWeight, MakeShape};
|
||||||
use crate::segbend::Segbend;
|
use crate::segbend::Segbend;
|
||||||
|
|
@ -64,9 +65,17 @@ impl Layout {
|
||||||
self.graph.remove_node(index.node_index());
|
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, ()> {
|
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.insert_into_rtree(dot.into());
|
||||||
self.fail_and_remove_if_collides_except(dot.into(), &[])?;
|
self.fail_and_remove_if_collides_except(dot.into(), &[])?;
|
||||||
|
|
@ -74,93 +83,59 @@ impl Layout {
|
||||||
Ok(dot)
|
Ok(dot)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[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_loose_dot(&mut self, weight: LooseDotWeight) -> Result<LooseDotIndex, ()> {
|
#[debug_ensures(ret.is_ok() -> self.graph.edge_count() == old(self.graph.edge_count() + 2))]
|
||||||
let dot = LooseDotIndex::new(self.graph.add_node(weight.into()));
|
#[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()))]
|
||||||
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))]
|
|
||||||
pub fn add_fixed_seg(
|
pub fn add_fixed_seg(
|
||||||
&mut self,
|
&mut self,
|
||||||
from: FixedDotIndex,
|
from: FixedDotIndex,
|
||||||
to: FixedDotIndex,
|
to: FixedDotIndex,
|
||||||
weight: FixedSegWeight,
|
weight: FixedSegWeight,
|
||||||
) -> Result<FixedSegIndex, ()> {
|
) -> Result<FixedSegIndex, ()> {
|
||||||
let seg = FixedSegIndex::new(self.graph.add_node(weight.into()));
|
self.add_seg(from, to, weight)
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[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))]
|
||||||
#[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count() + 2))]
|
#[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(
|
pub fn add_half_loose_seg(
|
||||||
&mut self,
|
&mut self,
|
||||||
from: FixedDotIndex,
|
from: FixedDotIndex,
|
||||||
to: LooseDotIndex,
|
to: LooseDotIndex,
|
||||||
weight: HalfLooseSegWeight,
|
weight: HalfLooseSegWeight,
|
||||||
) -> Result<FixedSegIndex, ()> {
|
) -> Result<HalfLooseSegIndex, ()> {
|
||||||
let seg = FixedSegIndex::new(self.graph.add_node(weight.into()));
|
self.add_seg(from, to, weight)
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[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))]
|
||||||
#[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count() + 2))]
|
#[debug_ensures(ret.is_ok() -> self.graph.edge_count() == old(self.graph.edge_count() + 2))]
|
||||||
pub fn add_loose_seg(
|
#[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,
|
&mut self,
|
||||||
from: LooseDotIndex,
|
from: LooseDotIndex,
|
||||||
to: LooseDotIndex,
|
to: LooseDotIndex,
|
||||||
weight: HalfLooseSegWeight,
|
weight: FullyLooseSegWeight,
|
||||||
) -> Result<FixedSegIndex, ()> {
|
) -> Result<FullyLooseSegIndex, ()> {
|
||||||
let seg = FixedSegIndex::new(self.graph.add_node(weight.into()));
|
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
|
self.graph
|
||||||
.add_edge(from.node_index(), seg.node_index(), Label::Adjacent);
|
.add_edge(from.node_index(), seg.node_index(), Label::Adjacent);
|
||||||
|
|
@ -175,13 +150,13 @@ impl Layout {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.as_fixed_dot_mut()
|
.as_fixed_dot_mut()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.net = weight.net;
|
.net = weight.net();
|
||||||
self.graph
|
self.graph
|
||||||
.node_weight_mut(to.node_index())
|
.node_weight_mut(to.node_index())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.as_fixed_dot_mut()
|
.as_fixed_dot_mut()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.net = weight.net;
|
.net = weight.net();
|
||||||
|
|
||||||
Ok(seg)
|
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()))]
|
#[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))]
|
||||||
pub fn add_loose_bend(
|
pub fn add_loose_bend(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
|
@ -216,19 +191,22 @@ impl Layout {
|
||||||
Index::FixedBend(around) => self.add_outer_bend(from, to, around, weight),
|
Index::FixedBend(around) => self.add_outer_bend(from, to, around, weight),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}*/
|
}
|
||||||
|
|
||||||
#[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()))]
|
#[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_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()))]
|
#[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,
|
&mut self,
|
||||||
from: FixedDotIndex,
|
from: impl GetNodeIndex,
|
||||||
to: FixedDotIndex,
|
to: impl GetNodeIndex,
|
||||||
core: FixedDotIndex,
|
core: FixedDotIndex,
|
||||||
weight: FixedBendWeight,
|
weight: W,
|
||||||
) -> Result<FixedBendIndex, ()> {
|
) -> Result<FixedBendIndex, ()>
|
||||||
|
where
|
||||||
|
GenericIndex<W>: Into<Index> + Copy,
|
||||||
|
{
|
||||||
let bend = FixedBendIndex::new(self.graph.add_node(weight.into()));
|
let bend = FixedBendIndex::new(self.graph.add_node(weight.into()));
|
||||||
|
|
||||||
self.graph
|
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_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_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()))]
|
#[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,
|
&mut self,
|
||||||
from: FixedDotIndex,
|
from: impl GetNodeIndex,
|
||||||
to: FixedDotIndex,
|
to: impl GetNodeIndex,
|
||||||
inner: FixedBendIndex,
|
inner: impl GetNodeIndex,
|
||||||
weight: FixedBendWeight,
|
weight: W,
|
||||||
) -> Result<FixedBendIndex, ()> {
|
) -> Result<FixedBendIndex, ()> {
|
||||||
let core = *self
|
let core = *self
|
||||||
.graph
|
.graph
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue