From 2f6b40410c660672e51cff3e930ccdac719ad909 Mon Sep 17 00:00:00 2001 From: Mikolaj Wielgus Date: Thu, 29 Feb 2024 02:28:15 +0000 Subject: [PATCH] board: make layout private Also add board/ directory, as I forgot to add it in the previous commit. --- src/bin/topola-sdl2-demo/main.rs | 12 ++-- src/board/board.rs | 118 +++++++++++++++++++++++++++++++ src/board/connectivity.rs | 41 +++++++++++ src/board/mod.rs | 4 ++ src/draw.rs | 61 ++++++++-------- src/dsn/rules.rs | 9 ++- src/layout/layout.rs | 7 -- src/router.rs | 19 +++-- src/tracer.rs | 2 +- 9 files changed, 221 insertions(+), 52 deletions(-) create mode 100644 src/board/board.rs create mode 100644 src/board/connectivity.rs create mode 100644 src/board/mod.rs diff --git a/src/bin/topola-sdl2-demo/main.rs b/src/bin/topola-sdl2-demo/main.rs index ebe4541..f4fb76a 100644 --- a/src/bin/topola-sdl2-demo/main.rs +++ b/src/bin/topola-sdl2-demo/main.rs @@ -127,7 +127,7 @@ impl<'a, R: RulesTrait> RouterObserverTrait for DebugRouterObserver<'a> { self.window, self.renderer, self.font_context, - RouterOrLayout::Layout(&tracer.board.layout), + RouterOrLayout::Layout(tracer.board.layout()), None, Some(tracer.mesh.clone()), &trace.path, @@ -145,7 +145,7 @@ impl<'a, R: RulesTrait> RouterObserverTrait for DebugRouterObserver<'a> { self.window, self.renderer, self.font_context, - RouterOrLayout::Layout(&tracer.board.layout), + RouterOrLayout::Layout(tracer.board.layout()), None, Some(tracer.mesh.clone()), &path, @@ -176,7 +176,7 @@ impl<'a, R: RulesTrait> RouterObserverTrait for DebugRouterObserver<'a> { self.window, self.renderer, self.font_context, - RouterOrLayout::Layout(&tracer.board.layout), + RouterOrLayout::Layout(tracer.board.layout()), None, Some(tracer.mesh.clone()), &trace.path, @@ -257,7 +257,7 @@ fn main() -> Result<(), anyhow::Error> { &window, &mut renderer, &font_context, - RouterOrLayout::Layout(&router.board.layout), + RouterOrLayout::Layout(router.board.layout()), None, None, &[], @@ -280,7 +280,7 @@ fn main() -> Result<(), anyhow::Error> { &window, &mut renderer, &font_context, - RouterOrLayout::Layout(&router.board.layout), + RouterOrLayout::Layout(router.board.layout()), None, None, &[], @@ -347,7 +347,7 @@ fn render_times( maybe_mesh = None; } - &router.board.layout + router.board.layout() } RouterOrLayout::Layout(layout) => layout, }; diff --git a/src/board/board.rs b/src/board/board.rs new file mode 100644 index 0000000..ebcc366 --- /dev/null +++ b/src/board/board.rs @@ -0,0 +1,118 @@ +use geo::Point; +use petgraph::stable_graph::StableDiGraph; + +use crate::{ + graph::GetNodeIndex, + layout::{ + bend::LooseBendWeight, + dot::{DotIndex, FixedDotIndex, LooseDotIndex, LooseDotWeight}, + rules::RulesTrait, + seg::{LoneLooseSegIndex, LoneLooseSegWeight, SeqLooseSegIndex, SeqLooseSegWeight}, + segbend::Segbend, + Infringement, Layout, LayoutException, + }, + wraparoundable::WraparoundableIndex, +}; + +use super::connectivity::{ + BandIndex, BandWeight, ConnectivityLabel, ConnectivityWeight, ContinentIndex, +}; + +pub struct Board { + layout: Layout, // Shouldn't be public, but is for now because `Draw` needs it. + connectivity: StableDiGraph, +} + +impl Board { + pub fn new(layout: Layout) -> Self { + Self { + layout, + connectivity: StableDiGraph::default(), + } + } + + pub fn remove_band(&mut self, band: BandIndex) { + todo!() + } + + pub fn remove_segbend(&mut self, segbend: &Segbend, face: LooseDotIndex) { + self.layout.remove_segbend(segbend, face) + } + + pub fn start_band(&mut self, from: FixedDotIndex) -> BandIndex { + let band = self + .connectivity + .add_node(ConnectivityWeight::Band(BandWeight { from, to: None })); + self.connectivity.update_edge( + self.continent(from.into()).node_index(), + band, + ConnectivityLabel::Band, + ); + BandIndex::new(band) + } + + pub fn finish_band(&mut self, band: BandIndex, to: FixedDotIndex) { + self.connectivity.update_edge( + band.node_index(), + self.continent(to.into()).node_index(), + ConnectivityLabel::Band, + ); + } + + pub fn insert_segbend( + &mut self, + from: DotIndex, + around: WraparoundableIndex, + dot_weight: LooseDotWeight, + seg_weight: SeqLooseSegWeight, + bend_weight: LooseBendWeight, + cw: bool, + ) -> Result { + self.layout + .insert_segbend(from, around, dot_weight, seg_weight, bend_weight, cw) + } + + pub fn add_lone_loose_seg( + &mut self, + from: FixedDotIndex, + to: FixedDotIndex, + weight: LoneLooseSegWeight, + ) -> Result { + self.layout.add_lone_loose_seg(from, to, weight) + } + + pub fn add_seq_loose_seg( + &mut self, + from: DotIndex, + to: LooseDotIndex, + weight: SeqLooseSegWeight, + ) -> Result { + self.layout.add_seq_loose_seg(from, to, weight) + } + + pub fn move_dot(&mut self, dot: DotIndex, to: Point) -> Result<(), Infringement> { + self.layout.move_dot(dot, to) + } + + pub fn band_from(&self, band: BandIndex) -> FixedDotIndex { + todo!() + } + + pub fn band_to(&self, band: BandIndex) -> Option { + todo!() + } + + pub fn band_length(&self, band: BandIndex) -> f64 { + // TODO. + 0.0 + } + + pub fn layout(&self) -> &Layout { + &self.layout + } + + pub fn continent(&self, dot: FixedDotIndex) -> ContinentIndex { + // TODO. + ContinentIndex::new(0.into()) + } +} diff --git a/src/board/connectivity.rs b/src/board/connectivity.rs new file mode 100644 index 0000000..47a345e --- /dev/null +++ b/src/board/connectivity.rs @@ -0,0 +1,41 @@ +use enum_dispatch::enum_dispatch; +use petgraph::stable_graph::StableDiGraph; + +use crate::{ + graph::GenericIndex, + layout::{dot::FixedDotIndex, graph::GetNet, primitive::Primitive, rules::RulesTrait}, +}; + +pub type ConnectivityGraph = StableDiGraph; + +#[derive(Debug, Clone, Copy)] +pub enum ConnectivityWeight { + Continent(ContinentWeight), + Band(BandWeight), +} + +#[derive(Debug, Clone, Copy)] +pub struct ContinentWeight { + pub net: i64, +} + +impl GetNet for ContinentWeight { + fn net(&self) -> i64 { + self.net + } +} + +pub type ContinentIndex = GenericIndex; + +#[derive(Debug, Clone, Copy)] +pub struct BandWeight { + pub from: FixedDotIndex, + pub to: Option, +} + +pub type BandIndex = GenericIndex; + +#[derive(Debug, Clone, Copy)] +pub enum ConnectivityLabel { + Band, +} diff --git a/src/board/mod.rs b/src/board/mod.rs new file mode 100644 index 0000000..34c2521 --- /dev/null +++ b/src/board/mod.rs @@ -0,0 +1,4 @@ +mod board; +pub mod connectivity; + +pub use board::*; diff --git a/src/draw.rs b/src/draw.rs index f947e4e..c25f003 100644 --- a/src/draw.rs +++ b/src/draw.rs @@ -3,7 +3,7 @@ use geo::{EuclideanLength, Point}; use thiserror::Error; use crate::{ - geometry::GetWidth, + board::Board, layout::{ bend::{BendIndex, LooseBendWeight}, dot::{DotIndex, FixedDotIndex, LooseDotIndex, LooseDotWeight}, @@ -12,7 +12,7 @@ use crate::{ primitive::GetOtherJoint, rules::RulesTrait, seg::{LoneLooseSegWeight, SeqLooseSegWeight}, - Infringement, Layout, LayoutException, + Infringement, LayoutException, }, math::{Circle, NoTangents}, wraparoundable::WraparoundableIndex, @@ -31,20 +31,20 @@ pub enum DrawException { } pub struct Draw<'a, R: RulesTrait> { - layout: &'a mut Layout, + board: &'a mut Board, } impl<'a, R: RulesTrait> Draw<'a, R> { - pub fn new(layout: &'a mut Layout) -> Self { - Self { layout } + pub fn new(board: &'a mut Board) -> Self { + Self { board } } pub fn start(&mut self, from: LooseDotIndex) -> Head { self.guide().segbend_head(from).into() } - #[debug_ensures(ret.is_ok() -> self.layout.node_count() == old(self.layout.node_count() + 1))] - #[debug_ensures(ret.is_err() -> self.layout.node_count() == old(self.layout.node_count()))] + #[debug_ensures(ret.is_ok() -> self.board.layout().node_count() == old(self.board.layout().node_count() + 1))] + #[debug_ensures(ret.is_err() -> self.board.layout().node_count() == old(self.board.layout().node_count()))] pub fn finish_in_dot( &mut self, head: Head, @@ -58,16 +58,16 @@ impl<'a, R: RulesTrait> Draw<'a, R> { let head = self .extend_head(head, tangent.start_point()) .map_err(|err| DrawException::CannotFinishIn(into, err.into()))?; - let net = head.face().primitive(self.layout).net(); + let net = head.face().primitive(self.board.layout()).net(); match head.face() { DotIndex::Fixed(dot) => { - self.layout + self.board .add_lone_loose_seg(dot, into.into(), LoneLooseSegWeight { net, width }) .map_err(|err| DrawException::CannotFinishIn(into, err.into()))?; } DotIndex::Loose(dot) => { - self.layout + self.board .add_seq_loose_seg(into.into(), dot, SeqLooseSegWeight { net, width }) .map_err(|err| DrawException::CannotFinishIn(into, err.into()))?; } @@ -75,8 +75,8 @@ impl<'a, R: RulesTrait> Draw<'a, R> { Ok::<(), DrawException>(()) } - #[debug_ensures(ret.is_ok() -> self.layout.node_count() == old(self.layout.node_count() + 4))] - #[debug_ensures(ret.is_err() -> self.layout.node_count() == old(self.layout.node_count()))] + #[debug_ensures(ret.is_ok() -> self.board.layout().node_count() == old(self.board.layout().node_count() + 4))] + #[debug_ensures(ret.is_err() -> self.board.layout().node_count() == old(self.board.layout().node_count()))] pub fn segbend_around_dot( &mut self, head: Head, @@ -120,8 +120,8 @@ impl<'a, R: RulesTrait> Draw<'a, R> { )) } - #[debug_ensures(ret.is_ok() -> self.layout.node_count() == old(self.layout.node_count() + 4))] - #[debug_ensures(ret.is_err() -> self.layout.node_count() == old(self.layout.node_count()))] + #[debug_ensures(ret.is_ok() -> self.board.layout().node_count() == old(self.board.layout().node_count() + 4))] + #[debug_ensures(ret.is_err() -> self.board.layout().node_count() == old(self.board.layout().node_count()))] pub fn segbend_around_bend( &mut self, head: Head, @@ -165,8 +165,8 @@ impl<'a, R: RulesTrait> Draw<'a, R> { )) } - #[debug_ensures(ret.is_ok() -> self.layout.node_count() == old(self.layout.node_count() + 4))] - #[debug_ensures(ret.is_err() -> self.layout.node_count() == old(self.layout.node_count()))] + #[debug_ensures(ret.is_ok() -> self.board.layout().node_count() == old(self.board.layout().node_count() + 4))] + #[debug_ensures(ret.is_err() -> self.board.layout().node_count() == old(self.board.layout().node_count()))] fn segbend_around( &mut self, head: Head, @@ -181,18 +181,18 @@ impl<'a, R: RulesTrait> Draw<'a, R> { self.segbend(head, around, to, cw, width, offset) } - #[debug_ensures(self.layout.node_count() == old(self.layout.node_count()))] + #[debug_ensures(self.board.layout().node_count() == old(self.board.layout().node_count()))] fn extend_head(&mut self, head: Head, to: Point) -> Result { if let Head::Segbend(head) = head { - self.layout.move_dot(head.face.into(), to)?; + self.board.move_dot(head.face.into(), to)?; Ok(Head::Segbend(head)) } else { Ok(head) } } - #[debug_ensures(ret.is_ok() -> self.layout.node_count() == old(self.layout.node_count() + 4))] - #[debug_ensures(ret.is_err() -> self.layout.node_count() == old(self.layout.node_count()))] + #[debug_ensures(ret.is_ok() -> self.board.layout().node_count() == old(self.board.layout().node_count() + 4))] + #[debug_ensures(ret.is_err() -> self.board.layout().node_count() == old(self.board.layout().node_count()))] fn segbend( &mut self, head: Head, @@ -202,8 +202,8 @@ impl<'a, R: RulesTrait> Draw<'a, R> { width: f64, offset: f64, ) -> Result { - let net = head.face().primitive(self.layout).net(); - let segbend = self.layout.insert_segbend( + let net = head.face().primitive(self.board.layout()).net(); + let segbend = self.board.insert_segbend( head.face(), around, LooseDotWeight { @@ -218,24 +218,29 @@ impl<'a, R: RulesTrait> Draw<'a, R> { cw, )?; Ok::(SegbendHead { - face: self.layout.primitive(segbend.bend).other_joint(segbend.dot), + face: self + .board + .layout() + .primitive(segbend.bend) + .other_joint(segbend.dot), segbend, }) } - #[debug_ensures(ret.is_some() -> self.layout.node_count() == old(self.layout.node_count() - 4))] - #[debug_ensures(ret.is_none() -> self.layout.node_count() == old(self.layout.node_count()))] + #[debug_ensures(ret.is_some() -> self.board.layout().node_count() == old(self.board.layout().node_count() - 4))] + #[debug_ensures(ret.is_none() -> self.board.layout().node_count() == old(self.board.layout().node_count()))] pub fn undo_segbend(&mut self, head: SegbendHead) -> Option { let prev_dot = self - .layout + .board + .layout() .primitive(head.segbend.seg) .other_joint(head.segbend.dot.into()); - self.layout.remove_segbend(&head.segbend, head.face); + self.board.remove_segbend(&head.segbend, head.face); Some(self.guide().head(prev_dot)) } fn guide(&self) -> Guide { - Guide::new(self.layout) + Guide::new(self.board.layout()) } } diff --git a/src/dsn/rules.rs b/src/dsn/rules.rs index ef172f5..3eac064 100644 --- a/src/dsn/rules.rs +++ b/src/dsn/rules.rs @@ -43,7 +43,8 @@ impl Rules { let mut net_id_classes = HashMap::new(); let class_rules = HashMap::from_iter( - pcb.network.classes + pcb.network + .classes .iter() .inspect(|class| { for net in &class.nets { @@ -51,7 +52,7 @@ impl Rules { net_id_classes.insert(*net_id, class.name.clone()); } }) - .map(|class| (class.name.clone(), Rule::from_dsn(&class.rule))) + .map(|class| (class.name.clone(), Rule::from_dsn(&class.rule))), ); Self { @@ -64,7 +65,9 @@ impl Rules { pub fn get_rule(&self, net: i64) -> &Rule { if let Some(netclass) = self.net_id_classes.get(&net) { - self.class_rules.get(netclass).unwrap_or(&self.structure_rule) + self.class_rules + .get(netclass) + .unwrap_or(&self.structure_rule) } else { &self.structure_rule } diff --git a/src/layout/layout.rs b/src/layout/layout.rs index a52f2ff..2f837c3 100644 --- a/src/layout/layout.rs +++ b/src/layout/layout.rs @@ -173,13 +173,6 @@ impl Layout { self.add_dot_infringably(weight, &[]) } - /*#[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(self.graph.edge_count() == old(self.graph.edge_count()))] - fn add_loose_dot(&mut self, weight: LooseDotWeight) -> Result { - self.add_dot_infringably(weight, &[]) - }*/ - #[debug_ensures(ret.is_ok() -> self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count() + 1))] #[debug_ensures(ret.is_err() -> self.geometry_with_rtree.graph().node_count() == old(self.geometry_with_rtree.graph().node_count()))] fn add_dot_infringably>( diff --git a/src/router.rs b/src/router.rs index f2cdf31..7981ba6 100644 --- a/src/router.rs +++ b/src/router.rs @@ -8,13 +8,12 @@ use crate::astar::{astar, AstarStrategy, PathTracker}; use crate::board::connectivity::BandIndex; use crate::board::Board; use crate::draw::DrawException; -use crate::geometry::{shape::ShapeTrait, GetWidth}; +use crate::geometry::shape::ShapeTrait; use crate::layout::{ dot::FixedDotIndex, graph::{GeometryIndex, MakePrimitive}, primitive::MakeShape, rules::RulesTrait, - Layout, }; use crate::mesh::{Mesh, MeshEdgeReference, VertexIndex}; @@ -120,10 +119,16 @@ impl<'a, RO: RouterObserverTrait, R: RulesTrait> AstarStrategy<&Mesh, f64> fn estimate_cost(&mut self, vertex: VertexIndex) -> f64 { self.observer.on_estimate(&self.tracer, vertex); let start_point = GeometryIndex::from(vertex) - .primitive(&self.tracer.board.layout) + .primitive(self.tracer.board.layout()) + .shape() + .center(); + let end_point = self + .tracer + .board + .layout() + .primitive(self.to) .shape() .center(); - let end_point = self.tracer.board.layout.primitive(self.to).shape().center(); end_point.euclidean_distance(&start_point) } } @@ -143,8 +148,8 @@ impl Router { // XXX: Should we actually store the mesh? May be useful for debugging, but doesn't look // right. //self.mesh.triangulate(&self.layout)?; - let mut mesh = Mesh::new(&self.board.layout); - mesh.generate(&self.board.layout) + let mut mesh = Mesh::new(self.board.layout()); + mesh.generate(self.board.layout()) .map_err(|err| RoutingError { from, to, @@ -179,7 +184,7 @@ impl Router { let from_dot = self.board.band_from(band); let to_dot = self.board.band_to(band).unwrap(); self.board.remove_band(band); - self.board.layout.move_dot(to_dot.into(), to).unwrap(); // TODO: Remove `.unwrap()`. + self.board.move_dot(to_dot.into(), to).unwrap(); // TODO: Remove `.unwrap()`. self.route_band(from_dot, to_dot, width, observer) } diff --git a/src/tracer.rs b/src/tracer.rs index 9faff89..babcb69 100644 --- a/src/tracer.rs +++ b/src/tracer.rs @@ -158,6 +158,6 @@ impl<'a, R: RulesTrait> Tracer<'a, R> { } fn draw(&mut self) -> Draw { - Draw::new(&mut self.board.layout) + Draw::new(&mut self.board) } }