Add `untag!` macro, move `.shape()` to `Primitive`

This commit is contained in:
Mikolaj Wielgus 2023-07-21 23:31:26 +02:00
parent 8b5cfb3686
commit dea65a3b43
4 changed files with 75 additions and 74 deletions

View File

@ -9,7 +9,6 @@ use crate::shape::Shape;
use crate::weight::{TaggedWeight, DotWeight, SegWeight, BendWeight};
use crate::math;
pub struct Layout {
mesh: Mesh,
rules: Rules,
@ -54,10 +53,6 @@ impl Layout {
self.add_seg(head.dot, to, width);
}
/*pub fn shove_around_dot(&mut self, head: Head, around: DotIndex, cw: bool, width: f64) -> Head {
}*/
pub fn route_around_dot(&mut self, head: Head, around: DotIndex, cw: bool, width: f64) -> Head {
let from_circle = self.head_guidecircle(&head, width);
@ -163,7 +158,7 @@ impl Layout {
let mut layer = bend;
while let Some(inner) = self.mesh.primitive(layer).inner() {
r += 5.0 + self.mesh.shape(inner.tag()).width();
r += 5.0 + self.mesh.primitive(inner).shape().width();
layer = inner;
}
@ -225,7 +220,7 @@ impl Layout {
self.mesh.add_seg(from, to, SegWeight {net, width})
}
pub fn shapes(&self) -> Box<dyn Iterator<Item=Shape> + '_> {
self.mesh.shapes()
pub fn shapes(&self) -> impl Iterator<Item=Shape> + '_ {
self.mesh.nodes().map(|ni| untag!(ni, self.mesh.primitive(ni).shape()))
}
}

View File

@ -1,8 +1,8 @@
extern crate sdl2;
#[macro_use] mod mesh;
mod layout;
mod rules;
mod mesh;
mod primitive;
mod shape;
mod weight;

View File

@ -30,6 +30,16 @@ pub trait Tag {
fn tag(&self) -> TaggedIndex;
}
macro_rules! untag {
($index:ident, $expr:expr) => {
match $index {
TaggedIndex::Dot($index) => $expr,
TaggedIndex::Seg($index) => $expr,
TaggedIndex::Bend($index) => $expr,
}
}
}
pub type DotIndex = Index<DotWeight>;
impl Tag for DotIndex {
@ -78,13 +88,12 @@ impl Mesh {
pub fn add_dot(&mut self, weight: DotWeight) -> DotIndex {
let dot = DotIndex::new(self.graph.add_node(TaggedWeight::Dot(weight)));
let index = TaggedIndex::Dot(dot);
self.rtree.insert(RTreeWrapper::new(self.shape(index), index));
self.rtree.insert(RTreeWrapper::new(self.primitive(dot).shape(), TaggedIndex::Dot(dot)));
dot
}
pub fn remove_dot(&mut self, dot: DotIndex) {
self.rtree.remove(&RTreeWrapper::new(self.shape(TaggedIndex::Dot(dot)), TaggedIndex::Dot(dot)));
self.rtree.remove(&RTreeWrapper::new(self.primitive(dot).shape(), TaggedIndex::Dot(dot)));
self.graph.remove_node(dot.index);
}
@ -93,14 +102,12 @@ impl Mesh {
self.graph.add_edge(seg.index, from.index, Label::End);
self.graph.add_edge(seg.index, to.index, Label::End);
let index = TaggedIndex::Seg(seg);
self.rtree.insert(RTreeWrapper::new(self.shape(index), index));
self.rtree.insert(RTreeWrapper::new(self.primitive(seg).shape(), TaggedIndex::Seg(seg)));
seg
}
pub fn remove_seg(&mut self, seg: SegIndex) {
self.rtree.remove(&RTreeWrapper::new(self.shape(TaggedIndex::Seg(seg)), TaggedIndex::Seg(seg)));
self.rtree.remove(&RTreeWrapper::new(self.primitive(seg).shape(), TaggedIndex::Seg(seg)));
self.graph.remove_node(seg.index);
}
@ -120,8 +127,7 @@ impl Mesh {
self.graph.add_edge(bend.index, to.index, Label::End);
self.graph.add_edge(bend.index, core.index, Label::Core);
let index = TaggedIndex::Bend(bend);
self.rtree.insert(RTreeWrapper::new(self.shape(index), index));
self.rtree.insert(RTreeWrapper::new(self.primitive(bend).shape(), TaggedIndex::Bend(bend)));
bend
}
@ -138,60 +144,15 @@ impl Mesh {
}
pub fn remove_bend(&mut self, bend: BendIndex) {
self.rtree.remove(&RTreeWrapper::new(self.shape(TaggedIndex::Bend(bend)), TaggedIndex::Bend(bend)));
self.rtree.remove(&RTreeWrapper::new(self.primitive(bend).shape(), TaggedIndex::Bend(bend)));
self.graph.remove_node(bend.index);
}
pub fn shapes(&self) -> Box<dyn Iterator<Item=Shape> + '_> {
Box::new(self.rtree.iter().map(|wrapper| self.shape(wrapper.data)))
}
pub fn shape(&self, index: TaggedIndex) -> Shape {
Shape {
weight: match index {
TaggedIndex::Dot(index) => self.primitive(index).tagged_weight(),
TaggedIndex::Seg(index) => self.primitive(index).tagged_weight(),
TaggedIndex::Bend(index) => self.primitive(index).tagged_weight(),
},
dot_neighbor_weights: match index {
TaggedIndex::Dot(index) => {
self.primitive(index).ends()
.into_iter()
.map(|index| self.primitive(index).weight())
.collect()
},
TaggedIndex::Seg(index) => {
self.primitive(index).ends()
.into_iter()
.map(|index| self.primitive(index).weight())
.collect()
},
TaggedIndex::Bend(index) => {
self.primitive(index).ends()
.into_iter()
.map(|index| self.primitive(index).weight())
.collect()
},
},
core_pos: match index {
TaggedIndex::Bend(bend) => {
Some(self.primitive(self.primitive(bend).core()).weight().circle.pos)
},
_ => None,
},
}
pub fn nodes(&self) -> impl Iterator<Item=TaggedIndex> + '_ {
self.rtree.iter().map(|wrapper| wrapper.data)
}
pub fn primitive<Weight>(&self, index: Index<Weight>) -> Primitive<Weight> {
Primitive::new(index, &self.graph)
}
/*pub fn tagged_weight(&self, index: TaggedIndex) -> Weight {
match index {
TaggedIndex::Dot(DotIndex {index: node, ..})
| TaggedIndex::Seg(SegIndex {index: node, ..})
| TaggedIndex::Bend(BendIndex {index: node, ..}) =>
*self.graph.node_weight(node).unwrap(),
}
}*/
}

View File

@ -2,6 +2,7 @@ use petgraph::Direction::{Outgoing, Incoming};
use petgraph::stable_graph::StableDiGraph;
use crate::{mesh::{DotIndex, SegIndex, BendIndex, TaggedIndex, Mesh, Tag, Index}, weight::{DotWeight, SegWeight, BendWeight, TaggedWeight, Label}};
use crate::shape::Shape;
pub struct Primitive<'a, Weight> {
index: Index<Weight>,
@ -13,17 +14,13 @@ impl<'a, Weight> Primitive<'a, Weight> {
Primitive::<Weight> {index, graph}
}
pub fn ends(&self) -> Vec<DotIndex> {
self.graph.neighbors(self.index.index)
.filter(|ni| self.graph.edge_weight(self.graph.find_edge(self.index.index, *ni).unwrap()).unwrap().is_end())
.filter(|ni| self.graph.node_weight(*ni).unwrap().is_dot())
.map(|ni| DotIndex::new(ni))
.collect()
}
pub fn tagged_weight(&self) -> TaggedWeight {
*self.graph.node_weight(self.index.index).unwrap()
}
fn primitive<W>(&self, index: Index<W>) -> Primitive<W> {
Primitive::new(index, &self.graph)
}
}
type Dot<'a> = Primitive<'a, DotWeight>;
@ -31,18 +28,66 @@ type Seg<'a> = Primitive<'a, SegWeight>;
type Bend<'a> = Primitive<'a, BendWeight>;
impl<'a> Dot<'a> {
pub fn shape(&self) -> Shape {
Shape {
weight: self.tagged_weight(),
dot_neighbor_weights: vec![],
core_pos: None,
}
}
pub fn weight(&self) -> DotWeight {
*self.tagged_weight().as_dot().unwrap()
}
}
impl<'a> Seg<'a> {
pub fn shape(&self) -> Shape {
Shape {
weight: self.tagged_weight(),
dot_neighbor_weights:
self.ends()
.into_iter()
.map(|index| self.primitive(index).weight())
.collect(),
core_pos: None,
}
}
pub fn ends(&self) -> Vec<DotIndex> {
self.graph.neighbors(self.index.index)
.filter(|ni| self.graph.edge_weight(self.graph.find_edge(self.index.index, *ni).unwrap()).unwrap().is_end())
.filter(|ni| self.graph.node_weight(*ni).unwrap().is_dot())
.map(|ni| DotIndex::new(ni))
.collect()
}
pub fn weight(&self) -> SegWeight {
*self.tagged_weight().as_seg().unwrap()
}
}
impl<'a> Bend<'a> {
pub fn shape(&self) -> Shape {
Shape {
weight: self.tagged_weight(),
dot_neighbor_weights:
self.ends()
.into_iter()
.map(|index| self.primitive(index).weight())
.collect(),
core_pos: Some(self.primitive(self.core()).weight().circle.pos),
}
}
pub fn ends(&self) -> Vec<DotIndex> {
self.graph.neighbors(self.index.index)
.filter(|ni| self.graph.edge_weight(self.graph.find_edge(self.index.index, *ni).unwrap()).unwrap().is_end())
.filter(|ni| self.graph.node_weight(*ni).unwrap().is_dot())
.map(|ni| DotIndex::new(ni))
.collect()
}
pub fn around(&self) -> TaggedIndex {
if let Some(inner) = self.inner() {
TaggedIndex::Bend(inner)