From 4fa97509e4815a8dbc4abcb143705ca5124bae63 Mon Sep 17 00:00:00 2001 From: Mikolaj Wielgus Date: Thu, 27 Jun 2024 23:56:39 +0200 Subject: [PATCH] router: split out `Trace` to its own file and give it its own methods We'll be following this pattern: * `Autorouter` - `Autoroute`, * `Router` - `Route` (not yet done), * `Tracer` - `Trace`. Agent nouns (ending with -er) denote the object that holds large and "unportable" parts of the state (such as `Board`, `Layout`, `Drawing`, `Geometry`), while verbs (ending with -e) denote holders of other, more "portable" parts of the state. --- src/autorouter/autoroute.rs | 2 +- src/autorouter/autorouter.rs | 2 +- src/drawing/guide.rs | 6 +- src/router/mod.rs | 1 + src/router/router.rs | 11 ++-- src/router/trace.rs | 118 +++++++++++++++++++++++++++++++++++ src/router/tracer.rs | 108 +++----------------------------- 7 files changed, 137 insertions(+), 111 deletions(-) create mode 100644 src/router/trace.rs diff --git a/src/autorouter/autoroute.rs b/src/autorouter/autoroute.rs index b6d1eff..7dd5f7a 100644 --- a/src/autorouter/autoroute.rs +++ b/src/autorouter/autoroute.rs @@ -14,8 +14,8 @@ pub struct Autoroute { impl Autoroute { pub fn new( - ratlines: impl IntoIterator> + 'static, autorouter: &mut Autorouter, + ratlines: impl IntoIterator> + 'static, ) -> Result { let mut ratlines_iter = Box::new(ratlines.into_iter()); diff --git a/src/autorouter/autorouter.rs b/src/autorouter/autorouter.rs index 4eff5e7..012191a 100644 --- a/src/autorouter/autorouter.rs +++ b/src/autorouter/autorouter.rs @@ -60,7 +60,7 @@ impl Autorouter { } pub fn autoroute_walk(&mut self, selection: &Selection) -> Result { - Autoroute::new(self.selected_ratlines(selection), self) + Autoroute::new(self, self.selected_ratlines(selection)) } pub fn undo_autoroute(&mut self, selection: &Selection) { diff --git a/src/drawing/guide.rs b/src/drawing/guide.rs index 80c1776..cab3c73 100644 --- a/src/drawing/guide.rs +++ b/src/drawing/guide.rs @@ -38,12 +38,12 @@ pub enum Head { #[derive(Debug, Clone, Copy)] pub struct BareHead { - pub dot: FixedDotIndex, + pub face: FixedDotIndex, } impl HeadTrait for BareHead { fn face(&self) -> DotIndex { - self.dot.into() + self.face.into() } } @@ -233,7 +233,7 @@ impl<'a, CW: Copy, R: RulesTrait> Guide<'a, CW, R> { pub fn head(&self, face: DotIndex) -> Head { match face { - DotIndex::Fixed(dot) => BareHead { dot }.into(), + DotIndex::Fixed(dot) => BareHead { face: dot }.into(), DotIndex::Loose(dot) => self.cane_head(dot).into(), } } diff --git a/src/router/mod.rs b/src/router/mod.rs index 56540e7..7be38f9 100644 --- a/src/router/mod.rs +++ b/src/router/mod.rs @@ -2,6 +2,7 @@ pub mod astar; pub mod draw; pub mod navmesh; mod router; +pub mod trace; pub mod tracer; pub use router::*; diff --git a/src/router/router.rs b/src/router/router.rs index d5b616f..a4834bb 100644 --- a/src/router/router.rs +++ b/src/router/router.rs @@ -25,7 +25,8 @@ use crate::{ BinavvertexNodeIndex, Navmesh, NavmeshEdgeReference, NavmeshError, NavvertexIndex, NavvertexWeight, }, - tracer::{Trace, Tracer}, + trace::Trace, + tracer::Tracer, }, }; @@ -118,13 +119,13 @@ impl<'a, R: RulesTrait> AstarStrategy let width = self.trace.width; let result = self - .tracer - .step(navmesh, &mut self.trace, edge.target(), width); + .trace + .step(&mut self.tracer, navmesh, edge.target(), width); let probe_length = self.bihead_length() - prev_bihead_length; if result.is_ok() { - self.tracer.undo_step(navmesh, &mut self.trace); + self.trace.undo_step(&mut self.tracer); Some(probe_length) } else { None @@ -169,7 +170,7 @@ impl Router { let target = navmesh.target(); let mut tracer = Tracer::new(layout); - let mut trace = tracer.start(&navmesh, source, source_navvertex, width); + let mut trace = tracer.start(source, source_navvertex, width); let mut strategy = RouterAstarStrategy::new(tracer, &mut trace, target); let astar = Astar::new(navmesh, source_navvertex, &mut strategy); diff --git a/src/router/trace.rs b/src/router/trace.rs new file mode 100644 index 0000000..1648dff --- /dev/null +++ b/src/router/trace.rs @@ -0,0 +1,118 @@ +use contracts::debug_ensures; +use petgraph::data::DataMap; + +use crate::{ + drawing::{ + bend::LooseBendIndex, + dot::FixedDotIndex, + graph::PrimitiveIndex, + guide::{BareHead, CaneHead, Head}, + rules::RulesTrait, + }, + router::{ + draw::Draw, + navmesh::{BinavvertexNodeIndex, Navmesh, NavvertexIndex}, + tracer::{Tracer, TracerException}, + }, +}; + +#[derive(Debug)] +pub struct Trace { + pub path: Vec, + pub head: Head, + pub width: f64, +} + +impl Trace { + pub fn new(source: FixedDotIndex, source_navvertex: NavvertexIndex, width: f64) -> Trace { + Self { + path: vec![source_navvertex], + head: BareHead { face: source }.into(), + width, + } + } + + #[debug_ensures(ret.is_ok() -> matches!(self.head, Head::Cane(..)))] + #[debug_ensures(ret.is_ok() -> self.path.len() == old(self.path.len() + 1))] + #[debug_ensures(ret.is_err() -> self.path.len() == old(self.path.len()))] + pub fn step( + &mut self, + tracer: &mut Tracer, + navmesh: &Navmesh, + to: NavvertexIndex, + width: f64, + ) -> Result<(), TracerException> { + self.head = self.wrap(tracer, navmesh, self.head, to, width)?.into(); + self.path.push(to); + + Ok::<(), TracerException>(()) + } + + #[debug_ensures(self.path.len() == old(self.path.len() - 1))] + pub fn undo_step(&mut self, tracer: &mut Tracer) { + if let Head::Cane(head) = self.head { + self.head = Draw::new(tracer.layout).undo_cane(head).unwrap(); + } else { + panic!(); + } + + self.path.pop(); + } + + fn wrap( + &mut self, + tracer: &mut Tracer, + navmesh: &Navmesh, + head: Head, + around: NavvertexIndex, + width: f64, + ) -> Result { + let cw = self + .maybe_cw(navmesh, around) + .ok_or(TracerException::CannotWrap)?; + + match self.binavvertex(navmesh, around) { + BinavvertexNodeIndex::FixedDot(dot) => { + self.wrap_around_fixed_dot(tracer, head, dot, cw, width) + } + BinavvertexNodeIndex::FixedBend(_fixed_bend) => todo!(), + BinavvertexNodeIndex::LooseBend(loose_bend) => { + self.wrap_around_loose_bend(tracer, head, loose_bend, cw, width) + } + } + } + + fn wrap_around_fixed_dot( + &mut self, + tracer: &mut Tracer, + head: Head, + around: FixedDotIndex, + cw: bool, + width: f64, + ) -> Result { + Ok(Draw::new(tracer.layout).cane_around_dot(head, around.into(), cw, width)?) + } + + fn wrap_around_loose_bend( + &mut self, + tracer: &mut Tracer, + head: Head, + around: LooseBendIndex, + cw: bool, + width: f64, + ) -> Result { + Ok(Draw::new(tracer.layout).cane_around_bend(head, around.into(), cw, width)?) + } + + fn binavvertex(&self, navmesh: &Navmesh, navvertex: NavvertexIndex) -> BinavvertexNodeIndex { + navmesh.node_weight(navvertex).unwrap().node + } + + fn primitive(&self, navmesh: &Navmesh, navvertex: NavvertexIndex) -> PrimitiveIndex { + self.binavvertex(navmesh, navvertex).into() + } + + fn maybe_cw(&self, navmesh: &Navmesh, navvertex: NavvertexIndex) -> Option { + navmesh.node_weight(navvertex).unwrap().maybe_cw + } +} diff --git a/src/router/tracer.rs b/src/router/tracer.rs index 4947432..72f514e 100644 --- a/src/router/tracer.rs +++ b/src/router/tracer.rs @@ -18,6 +18,7 @@ use crate::{ router::{ draw::{Draw, DrawException}, navmesh::{BinavvertexNodeIndex, Navmesh, NavvertexIndex, NavvertexWeight}, + trace::Trace, }, }; @@ -29,13 +30,6 @@ pub enum TracerException { CannotWrap, } -#[derive(Debug)] -pub struct Trace { - pub path: Vec, - pub head: Head, - pub width: f64, -} - #[derive(Debug)] pub struct Tracer<'a, R: RulesTrait> { pub layout: &'a mut Layout, @@ -48,16 +42,11 @@ impl<'a, R: RulesTrait> Tracer<'a, R> { pub fn start( &mut self, - _navmesh: &Navmesh, source: FixedDotIndex, source_navvertex: NavvertexIndex, width: f64, ) -> Trace { - Trace { - path: vec![source_navvertex], - head: BareHead { dot: source }.into(), - width, - } + Trace::new(source, source_navvertex, width) } pub fn finish( @@ -87,7 +76,7 @@ impl<'a, R: RulesTrait> Tracer<'a, R> { .count(); let length = trace.path.len(); - self.undo_path(navmesh, trace, length - prefix_length); + self.undo_path(trace, length - prefix_length); Ok::<(), TracerException>(self.path(navmesh, trace, &path[prefix_length..], width)?) } @@ -100,8 +89,8 @@ impl<'a, R: RulesTrait> Tracer<'a, R> { width: f64, ) -> Result<(), TracerException> { for (i, vertex) in path.iter().enumerate() { - if let Err(err) = self.step(navmesh, trace, *vertex, width) { - self.undo_path(navmesh, trace, i); + if let Err(err) = trace.step(self, navmesh, *vertex, width) { + self.undo_path(trace, i); return Err(err.into()); } } @@ -110,92 +99,9 @@ impl<'a, R: RulesTrait> Tracer<'a, R> { } #[debug_ensures(trace.path.len() == old(trace.path.len() - step_count))] - pub fn undo_path(&mut self, navmesh: &Navmesh, trace: &mut Trace, step_count: usize) { + pub fn undo_path(&mut self, trace: &mut Trace, step_count: usize) { for _ in 0..step_count { - self.undo_step(navmesh, trace); + trace.undo_step(self); } } - - #[debug_ensures(ret.is_ok() -> matches!(trace.head, Head::Cane(..)))] - #[debug_ensures(ret.is_ok() -> trace.path.len() == old(trace.path.len() + 1))] - #[debug_ensures(ret.is_err() -> trace.path.len() == old(trace.path.len()))] - pub fn step( - &mut self, - navmesh: &Navmesh, - trace: &mut Trace, - to: NavvertexIndex, - width: f64, - ) -> Result<(), TracerException> { - trace.head = self.wrap(navmesh, trace.head, to, width)?.into(); - trace.path.push(to); - - Ok::<(), TracerException>(()) - } - - fn wrap( - &mut self, - navmesh: &Navmesh, - head: Head, - around: NavvertexIndex, - width: f64, - ) -> Result { - let cw = self - .maybe_cw(navmesh, around) - .ok_or(TracerException::CannotWrap)?; - - match self.binavvertex(navmesh, around) { - BinavvertexNodeIndex::FixedDot(dot) => { - self.wrap_around_fixed_dot(navmesh, head, dot, cw, width) - } - BinavvertexNodeIndex::FixedBend(_fixed_bend) => todo!(), - BinavvertexNodeIndex::LooseBend(loose_bend) => { - self.wrap_around_loose_bend(navmesh, head, loose_bend, cw, width) - } - } - } - - fn wrap_around_fixed_dot( - &mut self, - _navmesh: &Navmesh, - head: Head, - around: FixedDotIndex, - cw: bool, - width: f64, - ) -> Result { - Ok(Draw::new(self.layout).cane_around_dot(head, around.into(), cw, width)?) - } - - fn wrap_around_loose_bend( - &mut self, - _navmesh: &Navmesh, - head: Head, - around: LooseBendIndex, - cw: bool, - width: f64, - ) -> Result { - Ok(Draw::new(self.layout).cane_around_bend(head, around.into(), cw, width)?) - } - - #[debug_ensures(trace.path.len() == old(trace.path.len() - 1))] - pub fn undo_step(&mut self, _navmesh: &Navmesh, trace: &mut Trace) { - if let Head::Cane(head) = trace.head { - trace.head = Draw::new(self.layout).undo_cane(head).unwrap(); - } else { - panic!(); - } - - trace.path.pop(); - } - - fn maybe_cw(&self, navmesh: &Navmesh, navvertex: NavvertexIndex) -> Option { - navmesh.node_weight(navvertex).unwrap().maybe_cw - } - - fn binavvertex(&self, navmesh: &Navmesh, navvertex: NavvertexIndex) -> BinavvertexNodeIndex { - navmesh.node_weight(navvertex).unwrap().node - } - - fn primitive(&self, navmesh: &Navmesh, navvertex: NavvertexIndex) -> PrimitiveIndex { - self.binavvertex(navmesh, navvertex).into() - } }