mirror of https://codeberg.org/topola/topola.git
autorouter,router: put stepper finishing in `Step` trait too
This commit is contained in:
parent
7830806834
commit
ece9c4aa5a
|
|
@ -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))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)?,
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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(|| ())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
20
src/step.rs
20
src/step.rs
|
|
@ -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>;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue