mirror of https://codeberg.org/topola/topola.git
Add `node_count == size` invariant for `Layout`
This commit is contained in:
parent
82081ef170
commit
1a271cd89c
|
|
@ -221,7 +221,7 @@ impl<'a> Draw<'a> {
|
|||
}
|
||||
|
||||
fn seg(&mut self, head: Head, to: Point, width: f64) -> Result<(Head, SegIndex), ()> {
|
||||
assert!(width <= self.layout.primitive(head.dot).weight().circle.r * 2.0);
|
||||
debug_assert!(width <= self.layout.primitive(head.dot).weight().circle.r * 2.0);
|
||||
|
||||
let net = self.layout.primitive(head.dot).weight().net;
|
||||
let to_index = self.layout.add_dot(DotWeight {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
use contracts::debug_invariant;
|
||||
use geo::Point;
|
||||
use petgraph::stable_graph::StableDiGraph;
|
||||
use petgraph::visit::EdgeRef;
|
||||
|
|
@ -22,6 +23,7 @@ pub struct Layout {
|
|||
pub graph: StableDiGraph<TaggedWeight, Label, usize>,
|
||||
}
|
||||
|
||||
#[debug_invariant(self.graph.node_count() == self.rtree.size())]
|
||||
impl Layout {
|
||||
pub fn new() -> Self {
|
||||
Layout {
|
||||
|
|
@ -54,8 +56,8 @@ impl Layout {
|
|||
pub fn add_dot(&mut self, weight: DotWeight) -> Result<DotIndex, ()> {
|
||||
let dot = DotIndex::new(self.graph.add_node(TaggedWeight::Dot(weight)));
|
||||
|
||||
self.fail_and_remove_if_collides_except(dot, &[])?;
|
||||
self.insert_into_rtree(dot.tag());
|
||||
self.fail_and_remove_if_collides_except(dot, &[])?;
|
||||
|
||||
Ok(dot)
|
||||
}
|
||||
|
|
@ -71,8 +73,8 @@ impl Layout {
|
|||
self.graph.add_edge(from.index, seg.index, Label::End);
|
||||
self.graph.add_edge(seg.index, to.index, Label::End);
|
||||
|
||||
self.fail_and_remove_if_collides_except(seg, &[from.tag(), to.tag()])?;
|
||||
self.insert_into_rtree(seg.tag());
|
||||
self.fail_and_remove_if_collides_except(seg, &[from.tag(), to.tag()])?;
|
||||
|
||||
self.graph
|
||||
.node_weight_mut(from.index)
|
||||
|
|
@ -117,8 +119,8 @@ impl Layout {
|
|||
self.graph.add_edge(bend.index, to.index, Label::End);
|
||||
self.graph.add_edge(bend.index, core.index, Label::Core);
|
||||
|
||||
self.fail_and_remove_if_collides_except(bend, &[from.tag(), to.tag(), core.tag()])?;
|
||||
self.insert_into_rtree(bend.tag());
|
||||
self.fail_and_remove_if_collides_except(bend, &[from.tag(), to.tag(), core.tag()])?;
|
||||
Ok(bend)
|
||||
}
|
||||
|
||||
|
|
@ -166,6 +168,45 @@ impl Layout {
|
|||
result
|
||||
}
|
||||
|
||||
pub fn bow(&self, bend: BendIndex) -> Bow {
|
||||
Bow::from_bend(bend, &self.graph)
|
||||
}
|
||||
|
||||
pub fn prev_segbend(&self, dot: DotIndex) -> Option<Segbend> {
|
||||
Segbend::from_dot_prev(dot, &self.graph)
|
||||
}
|
||||
|
||||
pub fn next_segbend(&self, dot: DotIndex) -> Option<Segbend> {
|
||||
Segbend::from_dot_next(dot, &self.graph)
|
||||
}
|
||||
|
||||
fn fail_and_remove_if_collides_except<Weight: std::marker::Copy>(
|
||||
&mut self,
|
||||
index: Index<Weight>,
|
||||
except: &[TaggedIndex],
|
||||
) -> Result<(), ()> {
|
||||
if let Some(..) = self.detect_collision_except(index, except) {
|
||||
self.remove(index);
|
||||
return Err(());
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn dots(&self) -> impl Iterator<Item = DotIndex> + '_ {
|
||||
self.nodes().filter_map(|ni| ni.as_dot().map(|di| *di))
|
||||
}
|
||||
|
||||
pub fn shapes(&self) -> impl Iterator<Item = Shape> + '_ {
|
||||
self.nodes()
|
||||
.map(|ni| untag!(ni, self.primitive(ni).shape()))
|
||||
}
|
||||
|
||||
fn nodes(&self) -> impl Iterator<Item = TaggedIndex> + '_ {
|
||||
self.rtree.iter().map(|wrapper| wrapper.data)
|
||||
}
|
||||
}
|
||||
|
||||
impl Layout {
|
||||
pub fn move_dot(&mut self, dot: DotIndex, to: Point) -> Result<(), ()> {
|
||||
let mut cur_bend = self.primitive(dot).outer();
|
||||
loop {
|
||||
|
|
@ -212,30 +253,6 @@ impl Layout {
|
|||
Primitive::new(index, &self.graph)
|
||||
}
|
||||
|
||||
pub fn bow(&self, bend: BendIndex) -> Bow {
|
||||
Bow::from_bend(bend, &self.graph)
|
||||
}
|
||||
|
||||
pub fn prev_segbend(&self, dot: DotIndex) -> Option<Segbend> {
|
||||
Segbend::from_dot_prev(dot, &self.graph)
|
||||
}
|
||||
|
||||
pub fn next_segbend(&self, dot: DotIndex) -> Option<Segbend> {
|
||||
Segbend::from_dot_next(dot, &self.graph)
|
||||
}
|
||||
|
||||
fn fail_and_remove_if_collides_except<Weight: std::marker::Copy>(
|
||||
&mut self,
|
||||
index: Index<Weight>,
|
||||
except: &[TaggedIndex],
|
||||
) -> Result<(), ()> {
|
||||
if let Some(..) = self.detect_collision_except(index, except) {
|
||||
self.graph.remove_node(index.index);
|
||||
return Err(());
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn detect_collision_except<Weight: std::marker::Copy>(
|
||||
&self,
|
||||
index: Index<Weight>,
|
||||
|
|
@ -263,22 +280,9 @@ impl Layout {
|
|||
|
||||
fn remove_from_rtree(&mut self, index: TaggedIndex) {
|
||||
let shape = untag!(index, self.primitive(index).shape());
|
||||
assert!(self
|
||||
debug_assert!(self
|
||||
.rtree
|
||||
.remove(&RTreeWrapper::new(shape, index))
|
||||
.is_some());
|
||||
}
|
||||
|
||||
pub fn dots(&self) -> impl Iterator<Item = DotIndex> + '_ {
|
||||
self.nodes().filter_map(|ni| ni.as_dot().map(|di| *di))
|
||||
}
|
||||
|
||||
pub fn shapes(&self) -> impl Iterator<Item = Shape> + '_ {
|
||||
self.nodes()
|
||||
.map(|ni| untag!(ni, self.primitive(ni).shape()))
|
||||
}
|
||||
|
||||
fn nodes(&self) -> impl Iterator<Item = TaggedIndex> + '_ {
|
||||
self.rtree.iter().map(|wrapper| wrapper.data)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,8 @@ use petgraph::stable_graph::{NodeIndex, StableDiGraph};
|
|||
use petgraph::Direction::{Incoming, Outgoing};
|
||||
|
||||
use crate::graph::{
|
||||
BendIndex, BendWeight, DotIndex, DotWeight, Ends, Index, Interior, Label, SegWeight, TaggedIndex, TaggedWeight,
|
||||
BendIndex, BendWeight, DotIndex, DotWeight, Ends, Index, Interior, Label, SegWeight,
|
||||
TaggedIndex, TaggedWeight,
|
||||
};
|
||||
use crate::math::{self, Circle};
|
||||
use crate::shape::{BendShape, DotShape, SegShape, Shape};
|
||||
|
|
@ -184,7 +185,9 @@ impl<'a, Weight> Primitive<'a, Weight> {
|
|||
let this = self.net(&self.index);
|
||||
let other = self.net(&index);
|
||||
|
||||
if this == -1 || other == -1 {
|
||||
if this == other {
|
||||
true
|
||||
} else if this == -1 || other == -1 {
|
||||
true
|
||||
} else if this == -2 || other == -2 {
|
||||
false
|
||||
|
|
|
|||
Loading…
Reference in New Issue