feat(autorouter/autoroute): Track progress of also past and future ratlines

This commit is contained in:
Mikolaj Wielgus 2025-07-09 20:52:25 +02:00
parent 68d9844d0d
commit ef78c92506
1 changed files with 28 additions and 32 deletions

View File

@ -34,14 +34,14 @@ pub enum AutorouteContinueStatus {
/// Manages the autorouting process across multiple ratlines. /// Manages the autorouting process across multiple ratlines.
pub struct AutorouteExecutionStepper { pub struct AutorouteExecutionStepper {
/// An iterator over ratlines that tracks which segments still need to be routed. /// The ratlines which we are routing.
ratlines_iter: Box<dyn Iterator<Item = EdgeIndex<usize>>>, ratlines: Vec<EdgeIndex<usize>>,
/// The options for the autorouting process, defining how routing should be carried out. /// Keeps track of the current ratline being routed, if one is active.
options: AutorouterOptions, curr_ratline_index: usize,
/// Stores the current route being processed, if any. /// Stores the current route being processed, if any.
route: Option<RouteStepper>, route: Option<RouteStepper>,
/// Keeps track of the current ratline being routed, if one is active. /// The options for the autorouting process, defining how routing should be carried out.
curr_ratline: Option<EdgeIndex<usize>>, options: AutorouterOptions,
} }
impl AutorouteExecutionStepper { impl AutorouteExecutionStepper {
@ -52,28 +52,26 @@ impl AutorouteExecutionStepper {
/// and stores the associated data for future routing steps. /// and stores the associated data for future routing steps.
pub fn new( pub fn new(
autorouter: &mut Autorouter<impl AccessMesadata>, autorouter: &mut Autorouter<impl AccessMesadata>,
ratlines: impl IntoIterator<Item = EdgeIndex<usize>> + 'static, ratlines: Vec<EdgeIndex<usize>>,
options: AutorouterOptions, options: AutorouterOptions,
) -> Result<Self, AutorouterError> { ) -> Result<Self, AutorouterError> {
let mut ratlines_iter = Box::new(ratlines.into_iter()); if ratlines.is_empty() {
let Some(curr_ratline) = ratlines_iter.next() else {
return Err(AutorouterError::NothingToRoute); return Err(AutorouterError::NothingToRoute);
}; };
let (origin, destination) = autorouter.ratline_endpoints(curr_ratline); let (origin, destination) = autorouter.ratline_endpoints(ratlines[0]);
let mut router = Router::new(autorouter.board.layout_mut(), options.router_options); let mut router = Router::new(autorouter.board.layout_mut(), options.router_options);
Ok(Self { Ok(Self {
ratlines_iter, ratlines,
options, curr_ratline_index: 0,
route: Some(router.route( route: Some(router.route(
LayoutEdit::new(), LayoutEdit::new(),
origin, origin,
destination, destination,
options.router_options.routed_band_width, options.router_options.routed_band_width,
)?), )?),
curr_ratline: Some(curr_ratline), options,
}) })
} }
} }
@ -87,7 +85,7 @@ impl<M: AccessMesadata> Step<Autorouter<M>, Option<LayoutEdit>, AutorouteContinu
&mut self, &mut self,
autorouter: &mut Autorouter<M>, autorouter: &mut Autorouter<M>,
) -> Result<ControlFlow<Option<LayoutEdit>, AutorouteContinueStatus>, AutorouterError> { ) -> Result<ControlFlow<Option<LayoutEdit>, AutorouteContinueStatus>, AutorouterError> {
let Some(curr_ratline) = self.curr_ratline else { if self.curr_ratline_index >= self.ratlines.len() {
let recorder = if let Some(taken_route) = self.route.take() { let recorder = if let Some(taken_route) = self.route.take() {
let (_thetastar, navcord, ..) = taken_route.dissolve(); let (_thetastar, navcord, ..) = taken_route.dissolve();
navcord.recorder navcord.recorder
@ -96,14 +94,14 @@ impl<M: AccessMesadata> Step<Autorouter<M>, Option<LayoutEdit>, AutorouteContinu
}; };
return Ok(ControlFlow::Break(Some(recorder))); return Ok(ControlFlow::Break(Some(recorder)));
}; }
let Some(ref mut route) = self.route else { let Some(ref mut route) = self.route else {
// Shouldn't happen. // Shouldn't happen.
return Ok(ControlFlow::Break(None)); return Ok(ControlFlow::Break(None));
}; };
let (source, target) = autorouter.ratline_endpoints(curr_ratline); let (source, target) = autorouter.ratline_endpoints(self.ratlines[self.curr_ratline_index]);
let ret = if let Some(band_termseg) = autorouter.board.band_between_nodes(source, target) { let ret = if let Some(band_termseg) = autorouter.board.band_between_nodes(source, target) {
AutorouteContinueStatus::Skipped(band_termseg[false]) AutorouteContinueStatus::Skipped(band_termseg[false])
@ -125,9 +123,10 @@ impl<M: AccessMesadata> Step<Autorouter<M>, Option<LayoutEdit>, AutorouteContinu
.loose_band_uid(band_termseg.into()) .loose_band_uid(band_termseg.into())
.expect("a completely routed band should've Seg's as ends"); .expect("a completely routed band should've Seg's as ends");
autorouter autorouter.ratsnest.assign_band_termseg_to_ratline(
.ratsnest self.ratlines[self.curr_ratline_index],
.assign_band_termseg_to_ratline(self.curr_ratline.unwrap(), band_termseg); band_termseg,
);
autorouter autorouter
.board .board
@ -136,13 +135,13 @@ impl<M: AccessMesadata> Step<Autorouter<M>, Option<LayoutEdit>, AutorouteContinu
AutorouteContinueStatus::Routed(band_termseg) AutorouteContinueStatus::Routed(band_termseg)
}; };
if let Some(new_ratline) = self.ratlines_iter.next() { self.curr_ratline_index += 1;
let (source, target) = autorouter.ratline_endpoints(new_ratline);
if let Some(new_ratline) = self.ratlines.get(self.curr_ratline_index) {
let (source, target) = autorouter.ratline_endpoints(*new_ratline);
let mut router = let mut router =
Router::new(autorouter.board.layout_mut(), self.options.router_options); Router::new(autorouter.board.layout_mut(), self.options.router_options);
self.curr_ratline = Some(new_ratline);
let recorder = if let Some(taken_route) = self.route.take() { let recorder = if let Some(taken_route) = self.route.take() {
let (_thetastar, navcord, ..) = taken_route.dissolve(); let (_thetastar, navcord, ..) = taken_route.dissolve();
navcord.recorder navcord.recorder
@ -156,8 +155,6 @@ impl<M: AccessMesadata> Step<Autorouter<M>, Option<LayoutEdit>, AutorouteContinu
target, target,
self.options.router_options.routed_band_width, self.options.router_options.routed_band_width,
)?); )?);
} else {
self.curr_ratline = None;
} }
Ok(ControlFlow::Continue(ret)) Ok(ControlFlow::Continue(ret))
@ -168,15 +165,14 @@ impl EstimateProgress for AutorouteExecutionStepper {
type Value = f64; type Value = f64;
fn estimate_progress_value(&self) -> f64 { fn estimate_progress_value(&self) -> f64 {
self.route self.curr_ratline_index as f64
.as_ref() + self.route.as_ref().map_or(0.0, |route| {
.map_or(0.0, |route| route.estimate_progress_value()) route.estimate_progress_value() / route.estimate_progress_maximum()
})
} }
fn estimate_progress_maximum(&self) -> f64 { fn estimate_progress_maximum(&self) -> f64 {
self.route self.ratlines.len() as f64
.as_ref()
.map_or(0.0, |route| route.estimate_progress_maximum())
} }
} }