geometry: make graph private, encapsulate all mutating usage of it

This commit is contained in:
Mikolaj Wielgus 2024-01-30 19:00:16 +00:00
parent 410b029eb3
commit 39bd393ff7
3 changed files with 63 additions and 44 deletions

View File

@ -1,6 +1,8 @@
use enum_dispatch::enum_dispatch;
use geo::Point;
use petgraph::stable_graph::NodeIndex;
use crate::{
graph::{GenericIndex, GetNodeIndex},
layout::{
@ -16,7 +18,7 @@ use crate::{
math::Circle,
};
use petgraph::stable_graph::NodeIndex;
use super::geometry::SetPos;
#[enum_dispatch(GetNodeIndex, MakePrimitive)]
#[derive(Debug, Clone, Copy, PartialEq)]
@ -46,7 +48,7 @@ impl TryFrom<GeometryIndex> for DotIndex {
}
}
#[enum_dispatch(GetPos, GetWidth)]
#[enum_dispatch(GetPos, SetPos, GetWidth)]
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum DotWeight {
Fixed(FixedDotWeight),
@ -91,6 +93,12 @@ impl GetPos for FixedDotWeight {
}
}
impl SetPos for FixedDotWeight {
fn set_pos(&mut self, pos: Point) {
self.circle.pos = pos
}
}
impl GetWidth for FixedDotWeight {
fn width(&self) -> f64 {
self.circle.r * 2.0
@ -112,6 +120,12 @@ impl GetPos for LooseDotWeight {
}
}
impl SetPos for LooseDotWeight {
fn set_pos(&mut self, pos: Point) {
self.circle.pos = pos
}
}
impl GetWidth for LooseDotWeight {
fn width(&self) -> f64 {
self.circle.r * 2.0

View File

@ -24,6 +24,11 @@ pub trait GetPos {
fn pos(&self) -> Point;
}
#[enum_dispatch]
pub trait SetPos {
fn set_pos(&mut self, pos: Point);
}
#[enum_dispatch]
pub trait GetWidth {
fn width(&self) -> f64;
@ -41,7 +46,7 @@ pub enum GeometryLabel {
Core,
}
pub trait DotWeightTrait<GW>: GetPos + GetWidth + Into<GW> + Copy {}
pub trait DotWeightTrait<GW>: GetPos + SetPos + GetWidth + Into<GW> + Copy {}
pub trait SegWeightTrait<GW>: GetWidth + Into<GW> + Copy {}
pub trait BendWeightTrait<GW>: GetOffset + GetWidth + Into<GW> + Copy {}
@ -56,7 +61,7 @@ pub struct Geometry<
SI: GetNodeIndex + Into<GI> + Copy,
BI: GetNodeIndex + Into<GI> + Copy,
> {
pub graph: StableDiGraph<GW, GeometryLabel, usize>,
graph: StableDiGraph<GW, GeometryLabel, usize>,
weight_marker: PhantomData<GW>,
dot_weight_marker: PhantomData<DW>,
seg_weight_marker: PhantomData<SW>,
@ -140,6 +145,40 @@ impl<
bend
}
pub fn remove(&mut self, node: GI) {
self.graph.remove_node(node.node_index());
}
pub fn move_dot(&mut self, dot: DI, to: Point) {
let mut weight = self.dot_weight(dot);
weight.set_pos(to);
*self.graph.node_weight_mut(dot.node_index()).unwrap() = weight.into()
}
pub fn flip_bend(&mut self, bend: BI) {
let (from, to) = self.bend_joints(bend);
let from_edge_weight = self
.graph
.remove_edge(
self.graph
.find_edge(from.node_index(), bend.node_index())
.unwrap(),
)
.unwrap();
let to_edge_weight = self
.graph
.remove_edge(
self.graph
.find_edge(bend.node_index(), to.node_index())
.unwrap(),
)
.unwrap();
self.graph
.update_edge(from.node_index(), bend.node_index(), to_edge_weight);
self.graph
.update_edge(bend.node_index(), to.node_index(), from_edge_weight);
}
pub fn reattach_bend(&mut self, bend: BI, maybe_new_inner: Option<BI>) {
if let Some(old_inner_edge) = self
.graph

View File

@ -18,7 +18,7 @@ use crate::guide::Guide;
use crate::layout::bend::BendIndex;
use crate::layout::dot::DotWeight;
use crate::layout::geometry::{
BendWeightTrait, DotWeightTrait, Geometry, GeometryLabel, SegWeightTrait,
BendWeightTrait, DotWeightTrait, Geometry, GeometryLabel, GetPos, SegWeightTrait,
};
use crate::layout::{
bend::{FixedBendIndex, LooseBendIndex, LooseBendWeight},
@ -188,7 +188,7 @@ impl Layout {
.unwrap();
self.remove_from_rtree(weight.retag(node.node_index()));
self.geometry.graph.remove_node(node.node_index());
self.geometry.remove(node);
}
// TODO: This method shouldn't be public.
@ -729,12 +729,6 @@ impl Layout {
.add_bend(from.into(), to.into(), core.into(), weight);
self.geometry.reattach_bend(bend.into(), Some(inner));
self.geometry.graph.update_edge(
inner.node_index(),
bend.node_index(),
GeometryLabel::Outer,
);
self.insert_into_rtree(bend.into());
self.fail_and_remove_if_infringes_except(bend.into(), infringables)?;
Ok(bend)
@ -744,15 +738,7 @@ impl Layout {
#[debug_ensures(self.geometry.graph().edge_count() == old(self.geometry.graph().edge_count()))]
pub fn flip_bend(&mut self, bend: FixedBendIndex) {
self.remove_from_rtree(bend.into());
let Some(GeometryWeight::FixedBend(weight)) =
self.geometry.graph.node_weight_mut(bend.node_index())
else {
unreachable!();
};
weight.cw = !weight.cw;
self.geometry.flip_bend(bend.into());
self.insert_into_rtree(bend.into());
}
@ -821,32 +807,12 @@ impl Layout {
) -> Result<(), Infringement> {
self.remove_from_rtree_with_limbs(dot.into());
let mut weight = *self.geometry.graph.node_weight(dot.node_index()).unwrap();
let old_weight = weight;
match weight {
GeometryWeight::FixedDot(ref mut fixed) => {
fixed.circle.pos = to;
}
GeometryWeight::LooseDot(ref mut loose) => {
loose.circle.pos = to;
}
_ => unreachable!(),
}
*self
.geometry
.graph
.node_weight_mut(dot.node_index())
.unwrap() = weight;
let old_pos = self.geometry.dot_weight(dot).pos();
self.geometry.move_dot(dot, to);
if let Some(infringement) = self.detect_infringement_except(dot.into(), infringables) {
// Restore original state.
*self
.geometry
.graph
.node_weight_mut(dot.node_index())
.unwrap() = old_weight;
self.geometry.move_dot(dot, old_pos);
self.insert_into_rtree_with_limbs(dot.into());
return Err(infringement);