autorouter,router: put stepper finishing in `Step` trait too

This commit is contained in:
Mikolaj Wielgus 2024-08-04 16:36:11 +02:00
parent 7830806834
commit ece9c4aa5a
10 changed files with 58 additions and 95 deletions

View File

@ -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<M: AccessMesadata> Step<Autorouter<M>, AutorouterStatus, AutorouterError> for Autoroute {
impl<M: AccessMesadata> Step<Autorouter<M>, AutorouterStatus, AutorouterError, ()> for Autoroute {
fn step(
&mut self,
autorouter: &mut Autorouter<M>,
@ -92,7 +92,7 @@ impl<M: AccessMesadata> Step<Autorouter<M>, 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))
}

View File

@ -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<M: AccessMesadata> Autorouter<M> {
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<Autoroute, AutorouterError> {
pub fn autoroute(&mut self, selection: &PinSelection) -> Result<Autoroute, AutorouterError> {
Autoroute::new(self, self.selected_ratlines(selection))
}
@ -89,12 +71,7 @@ impl<M: AccessMesadata> Autorouter<M> {
}
}
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<PlaceVia, AutorouterError> {
pub fn place_via(&self, weight: ViaWeight) -> Result<PlaceVia, AutorouterError> {
PlaceVia::new(weight)
}
@ -102,19 +79,7 @@ impl<M: AccessMesadata> Autorouter<M> {
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<RemoveBands, AutorouterError> {
pub fn remove_bands(&self, selection: &BandSelection) -> Result<RemoveBands, AutorouterError> {
RemoveBands::new(selection)
}

View File

@ -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<M: AccessMesadata> Step<Invoker<M>, InvokerStatus, InvokerError> for Execute {
impl<M: AccessMesadata> Step<Invoker<M>, InvokerStatus, InvokerError, ()> for Execute {
fn step(&mut self, invoker: &mut Invoker<M>) -> Result<InvokerStatus, InvokerError> {
match self.step_catch_err(invoker) {
Ok(InvokerStatus::Running) => Ok(InvokerStatus::Running),
@ -219,13 +219,13 @@ impl<M: AccessMesadata> Invoker<M> {
fn dispatch_command(&mut self, command: &Command) -> Result<Execute, InvokerError> {
match command {
Command::Autoroute(selection) => Ok::<Execute, InvokerError>(Execute::Autoroute(
self.autorouter.autoroute_walk(selection)?,
)),
Command::PlaceVia(weight) => Ok::<Execute, InvokerError>(Execute::PlaceVia(
self.autorouter.place_via_walk(*weight)?,
self.autorouter.autoroute(selection)?,
)),
Command::PlaceVia(weight) => {
Ok::<Execute, InvokerError>(Execute::PlaceVia(self.autorouter.place_via(*weight)?))
}
Command::RemoveBands(selection) => Ok::<Execute, InvokerError>(Execute::RemoveBands(
self.autorouter.remove_bands_walk(selection)?,
self.autorouter.remove_bands(selection)?,
)),
}
}

View File

@ -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(())
}

View File

@ -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(())
}

View File

@ -71,7 +71,7 @@ impl Route {
}
}
impl<'a, R: AccessRules> Step<Router<'a, R>, RouterStatus, RouterError> for Route {
impl<'a, R: AccessRules> Step<Router<'a, R>, RouterStatus, RouterError, ()> for Route {
fn step(&mut self, router: &mut Router<R>) -> Result<RouterStatus, RouterError> {
let tracer = Tracer::new(router.layout_mut());
let target = self.astar.graph.destination();

View File

@ -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<BandTermsegIndex, RouterError> {
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, RouterError> {
Route::new(self, from, to, width)
}

View File

@ -100,7 +100,7 @@ pub struct TraceStepInput<'a: 'b, 'b, R: AccessRules> {
pub width: f64,
}
impl<'a, 'b, R: AccessRules> Step<TraceStepInput<'a, 'b, R>, TracerStatus, TracerException>
impl<'a, 'b, R: AccessRules> Step<TraceStepInput<'a, 'b, R>, TracerStatus, TracerException, ()>
for Trace
{
#[debug_ensures(ret.is_ok() -> matches!(self.head, Head::Cane(..)))]
@ -125,7 +125,7 @@ impl<'a, 'b, R: AccessRules> Step<TraceStepInput<'a, 'b, R>, TracerStatus, Trace
}
}
impl<'a, R: AccessRules> StepBack<Tracer<'a, R>, TracerStatus, TracerException> for Trace {
impl<'a, R: AccessRules> StepBack<Tracer<'a, R>, 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<TracerStatus, TracerException> {
if let Head::Cane(head) = self.head {

View File

@ -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(|| ())
}
}

View File

@ -1,11 +1,19 @@
pub trait IsFinished {
fn finished(&self) -> bool;
pub trait GetMaybeOutcome<O> {
fn maybe_outcome(&self) -> Option<O>;
}
pub trait Step<I, S: IsFinished, E> {
fn step(&mut self, input: &mut I) -> Result<S, E>;
pub trait Step<C, S: GetMaybeOutcome<O>, E, O> {
fn step(&mut self, context: &mut C) -> Result<S, E>;
fn finish(&mut self, context: &mut C) -> Result<O, E> {
loop {
if let Some(outcome) = self.step(context)?.maybe_outcome() {
return Ok(outcome);
}
}
}
}
pub trait StepBack<I, S: IsFinished, E> {
fn step_back(&mut self, input: &mut I) -> Result<S, E>;
pub trait StepBack<C, S: GetMaybeOutcome<O>, E, O> {
fn step_back(&mut self, context: &mut C) -> Result<S, E>;
}