geometry: parameterize `Geometry` with general weights and dot weights

This commit is contained in:
Mikolaj Wielgus 2024-01-27 20:09:13 +00:00
parent 3fe54290c6
commit d35d8cd8dc
5 changed files with 84 additions and 33 deletions

View File

@ -22,14 +22,14 @@ use crate::connectivity::{
use crate::graph::{GenericIndex, GetNodeIndex};
use crate::guide::Guide;
use crate::layout::bend::BendIndex;
use crate::layout::geometry::{BendWeight, DotWeight, Geometry, SegWeight};
use crate::layout::dot::DotWeight;
use crate::layout::geometry::{BendWeightTrait, DotWeightTrait, Geometry, SegWeightTrait};
use crate::layout::seg::{SegIndex, SeqLooseSegWeight};
use crate::layout::{
bend::{FixedBendIndex, LooseBendIndex, LooseBendWeight},
dot::{DotIndex, FixedDotIndex, FixedDotWeight, LooseDotIndex, LooseDotWeight},
geometry::{
GeometryGraph, GeometryIndex, GeometryLabel, GeometryWeight, GetComponentIndex,
MakePrimitive, Retag,
GeometryIndex, GeometryLabel, GeometryWeight, GetComponentIndex, MakePrimitive, Retag,
},
seg::{FixedSegIndex, FixedSegWeight, LoneLooseSegIndex, LoneLooseSegWeight, SeqLooseSegIndex},
};
@ -75,7 +75,7 @@ pub struct AlreadyConnected(pub i64, pub GeometryIndex);
pub struct Layout {
rtree: RTree<RTreeWrapper>,
connectivity: ConnectivityGraph,
geometry: Geometry<DotIndex, SegIndex, BendIndex>,
geometry: Geometry<GeometryWeight, DotWeight, DotIndex, SegIndex, BendIndex>,
}
#[debug_invariant(self.geometry.graph().node_count() == self.rtree.size())]
@ -224,7 +224,7 @@ impl Layout {
#[debug_ensures(ret.is_ok() -> self.geometry.graph().node_count() == old(self.geometry.graph().node_count() + 1))]
#[debug_ensures(ret.is_err() -> self.geometry.graph().node_count() == old(self.geometry.graph().node_count()))]
fn add_dot_infringably<W: DotWeight>(
fn add_dot_infringably<W: DotWeightTrait<GeometryWeight>>(
&mut self,
weight: W,
infringables: &[GeometryIndex],
@ -604,7 +604,7 @@ impl Layout {
#[debug_ensures(ret.is_ok() -> self.geometry.graph().edge_count() == old(self.geometry.graph().edge_count() + 2))]
#[debug_ensures(ret.is_err() -> self.geometry.graph().node_count() == old(self.geometry.graph().node_count()))]
#[debug_ensures(ret.is_err() -> self.geometry.graph().edge_count() == old(self.geometry.graph().edge_count()))]
fn add_seg_infringably<W: SegWeight>(
fn add_seg_infringably<W: SegWeightTrait<GeometryWeight>>(
&mut self,
from: DotIndex,
to: DotIndex,
@ -681,7 +681,7 @@ impl Layout {
#[debug_ensures(ret.is_err() -> self.geometry.graph().node_count() == old(self.geometry.graph().node_count()))]
#[debug_ensures(ret.is_ok() -> self.geometry.graph().edge_count() == old(self.geometry.graph().edge_count() + 3))]
#[debug_ensures(ret.is_err() -> self.geometry.graph().edge_count() == old(self.geometry.graph().edge_count()))]
fn add_core_bend_infringably<W: BendWeight>(
fn add_core_bend_infringably<W: BendWeightTrait<GeometryWeight>>(
&mut self,
from: DotIndex,
to: DotIndex,
@ -703,7 +703,7 @@ impl Layout {
#[debug_ensures(ret.is_err() -> self.geometry.graph().node_count() == old(self.geometry.graph().node_count()))]
#[debug_ensures(ret.is_ok() -> self.geometry.graph().edge_count() == old(self.geometry.graph().edge_count() + 4))]
#[debug_ensures(ret.is_err() -> self.geometry.graph().edge_count() == old(self.geometry.graph().edge_count()))]
fn add_outer_bend_infringably<W: BendWeight>(
fn add_outer_bend_infringably<W: BendWeightTrait<GeometryWeight>>(
&mut self,
from: LooseDotIndex,
to: LooseDotIndex,
@ -953,7 +953,7 @@ impl Layout {
#[debug_ensures(self.geometry.graph().node_count() == old(self.geometry.graph().node_count()))]
#[debug_ensures(self.geometry.graph().edge_count() == old(self.geometry.graph().edge_count()))]
pub fn geometry(&self) -> &Geometry<DotIndex, SegIndex, BendIndex> {
pub fn geometry(&self) -> &Geometry<GeometryWeight, DotWeight, DotIndex, SegIndex, BendIndex> {
&self.geometry
}

View File

@ -8,7 +8,7 @@ use crate::{
};
use super::geometry::{
BendWeight, GeometryIndex, GeometryWeight, GetBandIndex, GetComponentIndex,
BendWeightTrait, GeometryIndex, GeometryWeight, GetBandIndex, GetComponentIndex,
GetComponentIndexMut, GetOffset, GetWidth, MakePrimitive, Retag,
};
use petgraph::stable_graph::NodeIndex;
@ -37,7 +37,7 @@ pub struct FixedBendWeight {
}
impl_fixed_weight!(FixedBendWeight, FixedBend, FixedBendIndex);
impl BendWeight for FixedBendWeight {}
impl BendWeightTrait<GeometryWeight> for FixedBendWeight {}
impl GetWidth for FixedBendWeight {
fn width(&self) -> f64 {
@ -59,4 +59,4 @@ impl GetOffset for LooseBendWeight {
}
impl_loose_weight!(LooseBendWeight, LooseBend, LooseBendIndex);
impl BendWeight for LooseBendWeight {}
impl BendWeightTrait<GeometryWeight> for LooseBendWeight {}

View File

@ -9,7 +9,7 @@ use crate::{
};
use super::geometry::{
DotWeight, GeometryIndex, GeometryWeight, GetBandIndex, GetComponentIndex,
DotWeightTrait, GeometryIndex, GeometryWeight, GetBandIndex, GetComponentIndex,
GetComponentIndexMut, GetWidth, MakePrimitive, Retag,
};
use petgraph::stable_graph::NodeIndex;
@ -24,12 +24,42 @@ pub enum DotIndex {
impl From<DotIndex> for GeometryIndex {
fn from(dot: DotIndex) -> Self {
match dot {
DotIndex::Fixed(fixed) => GeometryIndex::FixedDot(fixed),
DotIndex::Loose(loose) => GeometryIndex::LooseDot(loose),
DotIndex::Fixed(index) => GeometryIndex::FixedDot(index),
DotIndex::Loose(index) => GeometryIndex::LooseDot(index),
}
}
}
#[enum_dispatch(GetWidth)]
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum DotWeight {
Fixed(FixedDotWeight),
Loose(LooseDotWeight),
}
impl From<DotWeight> for GeometryWeight {
fn from(dot: DotWeight) -> Self {
match dot {
DotWeight::Fixed(weight) => GeometryWeight::FixedDot(weight),
DotWeight::Loose(weight) => GeometryWeight::LooseDot(weight),
}
}
}
impl TryFrom<GeometryWeight> for DotWeight {
type Error = (); // TODO.
fn try_from(weight: GeometryWeight) -> Result<DotWeight, ()> {
match weight {
GeometryWeight::FixedDot(weight) => Ok(DotWeight::Fixed(weight)),
GeometryWeight::LooseDot(weight) => Ok(DotWeight::Loose(weight)),
_ => unreachable!(),
}
}
}
impl DotWeightTrait<GeometryWeight> for DotWeight {}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct FixedDotWeight {
pub component: ComponentIndex,
@ -37,7 +67,7 @@ pub struct FixedDotWeight {
}
impl_fixed_weight!(FixedDotWeight, FixedDot, FixedDotIndex);
impl DotWeight for FixedDotWeight {}
impl DotWeightTrait<GeometryWeight> for FixedDotWeight {}
impl GetWidth for FixedDotWeight {
fn width(&self) -> f64 {
@ -52,7 +82,7 @@ pub struct LooseDotWeight {
}
impl_loose_weight!(LooseDotWeight, LooseDot, LooseDotIndex);
impl DotWeight for LooseDotWeight {}
impl DotWeightTrait<GeometryWeight> for LooseDotWeight {}
impl GetWidth for LooseDotWeight {
fn width(&self) -> f64 {

View File

@ -44,6 +44,7 @@ pub trait GetWidth {
fn width(&self) -> f64;
}
#[enum_dispatch]
pub trait GetOffset {
fn offset(&self) -> f64;
}
@ -96,8 +97,6 @@ macro_rules! impl_loose_weight {
};
}
pub type GeometryGraph = StableDiGraph<GeometryWeight, GeometryLabel, usize>;
#[enum_dispatch(Retag)]
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum GeometryWeight {
@ -134,33 +133,55 @@ pub trait MakePrimitive {
fn primitive<'a>(&self, layout: &'a Layout) -> Primitive<'a>;
}
pub trait DotWeight: GetWidth + Into<GeometryWeight> + Copy {}
pub trait SegWeight: Into<GeometryWeight> + Copy {}
pub trait BendWeight: Into<GeometryWeight> + Copy {}
pub trait DotWeightTrait<GW>: GetWidth + Into<GW> + Copy {}
pub trait SegWeightTrait<GW>: Into<GW> + Copy {}
pub trait BendWeightTrait<GW>: Into<GW> + Copy {}
#[derive(Debug)]
pub struct Geometry<DI: GetNodeIndex, SI: GetNodeIndex, BI: GetNodeIndex> {
pub graph: GeometryGraph,
pub struct Geometry<
GW: TryInto<DW>,
DW: DotWeightTrait<GW>,
DI: GetNodeIndex,
SI: GetNodeIndex,
BI: GetNodeIndex,
> {
pub graph: StableDiGraph<GW, GeometryLabel, usize>,
weight_marker: PhantomData<GW>,
dot_weight_marker: PhantomData<DW>,
dot_index_marker: PhantomData<DI>,
seg_index_marker: PhantomData<SI>,
bend_index_marker: PhantomData<BI>,
}
impl<DI: GetNodeIndex, SI: GetNodeIndex, BI: GetNodeIndex> Geometry<DI, SI, BI> {
impl<
GW: TryInto<DW>,
DW: DotWeightTrait<GW> + Copy,
DI: GetNodeIndex,
SI: GetNodeIndex,
BI: GetNodeIndex,
> Geometry<GW, DW, DI, SI, BI>
{
pub fn new() -> Self {
Self {
graph: StableDiGraph::default(),
weight_marker: PhantomData,
dot_weight_marker: PhantomData,
dot_index_marker: PhantomData,
seg_index_marker: PhantomData,
bend_index_marker: PhantomData,
}
}
pub fn add_dot<W: DotWeight>(&mut self, weight: W) -> GenericIndex<W> {
pub fn add_dot<W: DotWeightTrait<GW>>(&mut self, weight: W) -> GenericIndex<W> {
GenericIndex::<W>::new(self.graph.add_node(weight.into()))
}
pub fn add_seg<W: SegWeight>(&mut self, from: DI, to: DI, weight: W) -> GenericIndex<W> {
pub fn add_seg<W: SegWeightTrait<GW>>(
&mut self,
from: DI,
to: DI,
weight: W,
) -> GenericIndex<W> {
let seg = GenericIndex::<W>::new(self.graph.add_node(weight.into()));
self.graph
@ -171,7 +192,7 @@ impl<DI: GetNodeIndex, SI: GetNodeIndex, BI: GetNodeIndex> Geometry<DI, SI, BI>
seg
}
pub fn add_bend<W: BendWeight>(
pub fn add_bend<W: BendWeightTrait<GW>>(
&mut self,
from: DI,
to: DI,
@ -193,7 +214,7 @@ impl<DI: GetNodeIndex, SI: GetNodeIndex, BI: GetNodeIndex> Geometry<DI, SI, BI>
bend
}
pub fn graph(&self) -> &GeometryGraph {
pub fn graph(&self) -> &StableDiGraph<GW, GeometryLabel, usize> {
&self.graph
}
}

View File

@ -9,7 +9,7 @@ use crate::{
use super::geometry::{
GeometryIndex, GeometryWeight, GetBandIndex, GetComponentIndex, GetComponentIndexMut, GetWidth,
MakePrimitive, Retag, SegWeight,
MakePrimitive, Retag, SegWeightTrait,
};
use petgraph::stable_graph::NodeIndex;
@ -38,7 +38,7 @@ pub struct FixedSegWeight {
}
impl_fixed_weight!(FixedSegWeight, FixedSeg, FixedSegIndex);
impl SegWeight for FixedSegWeight {}
impl SegWeightTrait<GeometryWeight> for FixedSegWeight {}
impl GetWidth for FixedSegWeight {
fn width(&self) -> f64 {
@ -52,7 +52,7 @@ pub struct LoneLooseSegWeight {
}
impl_loose_weight!(LoneLooseSegWeight, LoneLooseSeg, LoneLooseSegIndex);
impl SegWeight for LoneLooseSegWeight {}
impl SegWeightTrait<GeometryWeight> for LoneLooseSegWeight {}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct SeqLooseSegWeight {
@ -60,4 +60,4 @@ pub struct SeqLooseSegWeight {
}
impl_loose_weight!(SeqLooseSegWeight, SeqLooseSeg, SeqLooseSegIndex);
impl SegWeight for SeqLooseSegWeight {}
impl SegWeightTrait<GeometryWeight> for SeqLooseSegWeight {}