diff --git a/src/autorouter/autoroute.rs b/src/autorouter/autoroute.rs index e391d2d..577f2b7 100644 --- a/src/autorouter/autoroute.rs +++ b/src/autorouter/autoroute.rs @@ -2,7 +2,7 @@ use petgraph::graph::EdgeIndex; use crate::{ board::mesadata::AccessMesadata, - drawing::graph::PrimitiveIndex, + drawing::{band::BandTermsegIndex, graph::PrimitiveIndex}, geometry::primitive::PrimitiveShape, router::{navmesh::Navmesh, route::Route, trace::Trace, Router, RouterStatus}, step::Step, @@ -36,14 +36,14 @@ impl Autoroute { let this = Self { ratlines_iter, curr_ratline: Some(curr_ratline), - route: Some(router.route_walk(source, target, 100.0)?), + route: Some(router.route(source, target, 100.0)?), }; Ok(this) } } -impl Step, AutorouterStatus, AutorouterError> for Autoroute { +impl Step, AutorouterStatus, AutorouterError, ()> for Autoroute { fn step( &mut self, autorouter: &mut Autorouter, @@ -92,7 +92,7 @@ impl Step, AutorouterStatus, AutorouterError> f let mut router = Router::new(autorouter.board.layout_mut()); self.curr_ratline = Some(new_ratline); - self.route = Some(router.route_walk(source, target, 100.0)?); + self.route = Some(router.route(source, target, 100.0)?); Ok(AutorouterStatus::Routed(band_termseg)) } diff --git a/src/autorouter/autorouter.rs b/src/autorouter/autorouter.rs index 7d2afae..707efcf 100644 --- a/src/autorouter/autorouter.rs +++ b/src/autorouter/autorouter.rs @@ -7,7 +7,7 @@ use crate::{ drawing::{band::BandTermsegIndex, dot::FixedDotIndex, Infringement}, layout::via::ViaWeight, router::{navmesh::NavmeshError, RouterError}, - step::{IsFinished, Step}, + step::{GetMaybeOutcome, Step}, triangulation::GetTrianvertexNodeIndex, }; @@ -37,9 +37,9 @@ pub enum AutorouterStatus { Finished, } -impl IsFinished for AutorouterStatus { - fn finished(&self) -> bool { - matches!(self, AutorouterStatus::Finished) +impl GetMaybeOutcome<()> for AutorouterStatus { + fn maybe_outcome(&self) -> Option<()> { + matches!(self, AutorouterStatus::Finished).then(|| ()) } } @@ -54,25 +54,7 @@ impl Autorouter { Ok(Self { board, ratsnest }) } - pub fn autoroute(&mut self, selection: &PinSelection) -> Result<(), AutorouterError> { - let mut autoroute = self.autoroute_walk(selection)?; - - loop { - let status = match autoroute.step(self) { - Ok(status) => status, - Err(err) => return Err(err), - }; - - if let AutorouterStatus::Finished = status { - return Ok(()); - } - } - } - - pub fn autoroute_walk( - &mut self, - selection: &PinSelection, - ) -> Result { + pub fn autoroute(&mut self, selection: &PinSelection) -> Result { Autoroute::new(self, self.selected_ratlines(selection)) } @@ -89,12 +71,7 @@ impl Autorouter { } } - pub fn place_via(&mut self, weight: ViaWeight) -> Result<(), AutorouterError> { - self.board.layout_mut().add_via(weight)?; - Ok(()) - } - - pub fn place_via_walk(&self, weight: ViaWeight) -> Result { + pub fn place_via(&self, weight: ViaWeight) -> Result { PlaceVia::new(weight) } @@ -102,19 +79,7 @@ impl Autorouter { todo!(); } - pub fn remove_bands(&mut self, selection: &BandSelection) -> Result<(), AutorouterError> { - for selector in selection.selectors() { - let band = self.board.bandname_band(selector.band.clone()).unwrap().0; - self.board.layout_mut().remove_band(band); - } - - Ok(()) - } - - pub fn remove_bands_walk( - &self, - selection: &BandSelection, - ) -> Result { + pub fn remove_bands(&self, selection: &BandSelection) -> Result { RemoveBands::new(selection) } diff --git a/src/autorouter/invoker.rs b/src/autorouter/invoker.rs index 10055be..9807da3 100644 --- a/src/autorouter/invoker.rs +++ b/src/autorouter/invoker.rs @@ -9,7 +9,7 @@ use crate::{ geometry::primitive::PrimitiveShape, layout::via::ViaWeight, router::{navmesh::Navmesh, trace::Trace}, - step::{IsFinished, Step}, + step::{GetMaybeOutcome, Step}, }; use super::{ @@ -55,9 +55,9 @@ pub enum InvokerStatus { Finished, } -impl IsFinished for InvokerStatus { - fn finished(&self) -> bool { - matches!(self, InvokerStatus::Finished) +impl GetMaybeOutcome<()> for InvokerStatus { + fn maybe_outcome(&self) -> Option<()> { + matches!(self, InvokerStatus::Finished).then(|| ()) } } @@ -98,7 +98,7 @@ impl Execute { } } -impl Step, InvokerStatus, InvokerError> for Execute { +impl Step, InvokerStatus, InvokerError, ()> for Execute { fn step(&mut self, invoker: &mut Invoker) -> Result { match self.step_catch_err(invoker) { Ok(InvokerStatus::Running) => Ok(InvokerStatus::Running), @@ -219,13 +219,13 @@ impl Invoker { fn dispatch_command(&mut self, command: &Command) -> Result { match command { Command::Autoroute(selection) => Ok::(Execute::Autoroute( - self.autorouter.autoroute_walk(selection)?, - )), - Command::PlaceVia(weight) => Ok::(Execute::PlaceVia( - self.autorouter.place_via_walk(*weight)?, + self.autorouter.autoroute(selection)?, )), + Command::PlaceVia(weight) => { + Ok::(Execute::PlaceVia(self.autorouter.place_via(*weight)?)) + } Command::RemoveBands(selection) => Ok::(Execute::RemoveBands( - self.autorouter.remove_bands_walk(selection)?, + self.autorouter.remove_bands(selection)?, )), } } diff --git a/src/autorouter/place_via.rs b/src/autorouter/place_via.rs index fe4250d..93c5810 100644 --- a/src/autorouter/place_via.rs +++ b/src/autorouter/place_via.rs @@ -31,7 +31,8 @@ impl PlaceVia { ) -> Result<(), AutorouterError> { if !self.done { self.done = true; - autorouter.place_via(self.weight) + autorouter.board.layout_mut().add_via(self.weight)?; + Ok(()) } else { Ok(()) } diff --git a/src/autorouter/remove_bands.rs b/src/autorouter/remove_bands.rs index edeafc0..494f9c1 100644 --- a/src/autorouter/remove_bands.rs +++ b/src/autorouter/remove_bands.rs @@ -31,7 +31,16 @@ impl RemoveBands { ) -> Result<(), AutorouterError> { if !self.done { self.done = true; - autorouter.remove_bands(&self.selection) + + for selector in self.selection.selectors() { + let band = autorouter + .board + .bandname_band(selector.band.clone()) + .unwrap() + .0; + autorouter.board.layout_mut().remove_band(band); + } + Ok(()) } else { Ok(()) } diff --git a/src/router/route.rs b/src/router/route.rs index 091a8f8..7f14b1f 100644 --- a/src/router/route.rs +++ b/src/router/route.rs @@ -71,7 +71,7 @@ impl Route { } } -impl<'a, R: AccessRules> Step, RouterStatus, RouterError> for Route { +impl<'a, R: AccessRules> Step, RouterStatus, RouterError, ()> for Route { fn step(&mut self, router: &mut Router) -> Result { let tracer = Tracer::new(router.layout_mut()); let target = self.astar.graph.destination(); diff --git a/src/router/router.rs b/src/router/router.rs index 1e39cd9..31f8979 100644 --- a/src/router/router.rs +++ b/src/router/router.rs @@ -18,7 +18,7 @@ use crate::{ }, graph::{GetPetgraphIndex, MakeRef}, layout::Layout, - step::{IsFinished, Step, StepBack}, + step::{GetMaybeOutcome, Step, StepBack}, }; use super::{ @@ -43,9 +43,9 @@ pub enum RouterStatus { Finished(BandTermsegIndex), } -impl IsFinished for RouterStatus { - fn finished(&self) -> bool { - matches!(self, RouterStatus::Finished(..)) +impl GetMaybeOutcome<()> for RouterStatus { + fn maybe_outcome(&self) -> Option<()> { + matches!(self, RouterStatus::Finished(..)).then(|| ()) } } @@ -186,26 +186,6 @@ impl<'a, R: AccessRules> Router<'a, R> { from: FixedDotIndex, to: FixedDotIndex, width: f64, - ) -> Result { - let mut route = self.route_walk(from, to, width)?; - - loop { - let status = match route.step(self) { - Ok(status) => status, - Err(err) => return Err(err), - }; - - if let RouterStatus::Finished(band) = status { - return Ok(band); - } - } - } - - pub fn route_walk( - &mut self, - from: FixedDotIndex, - to: FixedDotIndex, - width: f64, ) -> Result { Route::new(self, from, to, width) } diff --git a/src/router/trace.rs b/src/router/trace.rs index 09d7fb0..12d909b 100644 --- a/src/router/trace.rs +++ b/src/router/trace.rs @@ -100,7 +100,7 @@ pub struct TraceStepInput<'a: 'b, 'b, R: AccessRules> { pub width: f64, } -impl<'a, 'b, R: AccessRules> Step, TracerStatus, TracerException> +impl<'a, 'b, R: AccessRules> Step, TracerStatus, TracerException, ()> for Trace { #[debug_ensures(ret.is_ok() -> matches!(self.head, Head::Cane(..)))] @@ -125,7 +125,7 @@ impl<'a, 'b, R: AccessRules> Step, TracerStatus, Trace } } -impl<'a, R: AccessRules> StepBack, TracerStatus, TracerException> for Trace { +impl<'a, R: AccessRules> StepBack, TracerStatus, TracerException, ()> for Trace { #[debug_ensures(self.path.len() == old(self.path.len() - 1))] fn step_back(&mut self, tracer: &mut Tracer<'a, R>) -> Result { if let Head::Cane(head) = self.head { diff --git a/src/router/tracer.rs b/src/router/tracer.rs index e9c13c2..5e8eb0b 100644 --- a/src/router/tracer.rs +++ b/src/router/tracer.rs @@ -4,7 +4,7 @@ use thiserror::Error; use crate::{ drawing::{band::BandTermsegIndex, dot::FixedDotIndex, rules::AccessRules}, layout::Layout, - step::{IsFinished, Step, StepBack}, + step::{GetMaybeOutcome, Step, StepBack}, }; use super::{ @@ -26,9 +26,9 @@ pub enum TracerStatus { Finished, } -impl IsFinished for TracerStatus { - fn finished(&self) -> bool { - matches!(self, TracerStatus::Finished) +impl GetMaybeOutcome<()> for TracerStatus { + fn maybe_outcome(&self) -> Option<()> { + matches!(self, TracerStatus::Finished).then(|| ()) } } diff --git a/src/step.rs b/src/step.rs index 77a7cd6..f9009ee 100644 --- a/src/step.rs +++ b/src/step.rs @@ -1,11 +1,19 @@ -pub trait IsFinished { - fn finished(&self) -> bool; +pub trait GetMaybeOutcome { + fn maybe_outcome(&self) -> Option; } -pub trait Step { - fn step(&mut self, input: &mut I) -> Result; +pub trait Step, E, O> { + fn step(&mut self, context: &mut C) -> Result; + + fn finish(&mut self, context: &mut C) -> Result { + loop { + if let Some(outcome) = self.step(context)?.maybe_outcome() { + return Ok(outcome); + } + } + } } -pub trait StepBack { - fn step_back(&mut self, input: &mut I) -> Result; +pub trait StepBack, E, O> { + fn step_back(&mut self, context: &mut C) -> Result; }