feat(topola-egui): Add way to access subprogress and subprogress bar

This will be useful in future commits when I will be improving
reconfiguration triggers.
This commit is contained in:
Mikolaj Wielgus 2025-11-01 02:40:25 +01:00
parent 24ff7f0dd8
commit 0f3f96d4af
14 changed files with 107 additions and 74 deletions

View File

@ -43,15 +43,26 @@ impl StatusBar {
let linear_progress = activity.estimate_linear_progress(); let linear_progress = activity.estimate_linear_progress();
let value = linear_progress.value(); let value = linear_progress.value();
let maximum = linear_progress.maximum(); let maximum = linear_progress.maximum();
let ratio = *value as f32 / *maximum as f32;
ui.add( ui.add(egui::ProgressBar::new(ratio).text(format!(
egui::ProgressBar::new((value / maximum) as f32).text(format!( "{:.1}% ({:.1}/{:.1})",
"{:.1} ({:.1}/{:.1})", ratio * 100.0,
value / maximum * 100.0, value,
value, maximum
maximum )));
)),
); let linear_subprogress = linear_progress.subscale();
let value = linear_subprogress.value();
let maximum = linear_subprogress.maximum();
let ratio = *value as f32 / *maximum as f32;
ui.add(egui::ProgressBar::new(ratio).text(format!(
"{:.1}% ({:.1}/{:.1})",
ratio * 100.0,
value,
maximum
)));
} }
}); });
} }

View File

@ -16,7 +16,7 @@ use crate::{
board::{edit::BoardEdit, AccessMesadata}, board::{edit::BoardEdit, AccessMesadata},
layout::via::ViaWeight, layout::via::ViaWeight,
router::ng, router::ng,
stepper::{Abort, EstimateLinearProgress, LinearProgress, Step}, stepper::{Abort, EstimateLinearProgress, LinearScale, Step},
}; };
use super::{ use super::{
@ -172,21 +172,28 @@ impl<M: AccessMesadata + Clone> Abort<Invoker<M>> for ExecutionStepper<M> {
} }
// Since enum_dispatch does not really support generics, we implement this the // Since enum_dispatch does not really support generics, we implement this the
// long way. // long way by using `match`.
impl<M> EstimateLinearProgress for ExecutionStepper<M> { impl<M> EstimateLinearProgress for ExecutionStepper<M> {
type Value = f64; type Value = usize;
type Subscale = LinearScale<f64>;
fn estimate_linear_progress(&self) -> LinearProgress<f64> { fn estimate_linear_progress(&self) -> LinearScale<usize, LinearScale<f64>> {
match self { match self {
ExecutionStepper::MultilayerAutoroute(autoroute) => { ExecutionStepper::MultilayerAutoroute(autoroute) => {
autoroute.estimate_linear_progress() autoroute.estimate_linear_progress()
} }
ExecutionStepper::PlanarAutoroute(autoroute) => autoroute.estimate_linear_progress(), ExecutionStepper::PlanarAutoroute(autoroute) => autoroute.estimate_linear_progress(),
ExecutionStepper::TopoAutoroute(toporoute) => toporoute.estimate_linear_progress(), ExecutionStepper::TopoAutoroute(..) => {
ExecutionStepper::PlaceVia(place_via) => place_via.estimate_linear_progress(), LinearScale::new(0, 0, LinearScale::new(0.0, 0.0, ()))
ExecutionStepper::RemoveBands(remove_bands) => remove_bands.estimate_linear_progress(), }
ExecutionStepper::MeasureLength(measure_length) => { ExecutionStepper::PlaceVia(..) => {
measure_length.estimate_linear_progress() LinearScale::new(0, 0, LinearScale::new(0.0, 0.0, ()))
}
ExecutionStepper::RemoveBands(..) => {
LinearScale::new(0, 0, LinearScale::new(0.0, 0.0, ()))
}
ExecutionStepper::MeasureLength(..) => {
LinearScale::new(0, 0, LinearScale::new(0.0, 0.0, ()))
} }
} }
} }

View File

@ -8,7 +8,6 @@
use crate::{ use crate::{
board::AccessMesadata, geometry::shape::MeasureLength as MeasureLengthTrait, graph::MakeRef, board::AccessMesadata, geometry::shape::MeasureLength as MeasureLengthTrait, graph::MakeRef,
stepper::EstimateLinearProgress,
}; };
use super::{invoker::GetDebugOverlayData, selection::BandSelection, Autorouter, AutorouterError}; use super::{invoker::GetDebugOverlayData, selection::BandSelection, Autorouter, AutorouterError};
@ -48,7 +47,4 @@ impl MeasureLengthExecutionStepper {
} }
} }
impl EstimateLinearProgress for MeasureLengthExecutionStepper {
type Value = f64;
}
impl GetDebugOverlayData for MeasureLengthExecutionStepper {} impl GetDebugOverlayData for MeasureLengthExecutionStepper {}

View File

@ -22,7 +22,7 @@ use crate::{
geometry::{edit::Edit, primitive::PrimitiveShape}, geometry::{edit::Edit, primitive::PrimitiveShape},
router::{navcord::Navcord, navmesh::Navmesh, thetastar::ThetastarStepper}, router::{navcord::Navcord, navmesh::Navmesh, thetastar::ThetastarStepper},
stepper::{ stepper::{
Abort, EstimateLinearProgress, LinearProgress, ReconfiguratorStatus, Reconfigure, Step, Abort, EstimateLinearProgress, LinearScale, ReconfiguratorStatus, Reconfigure, Step,
}, },
}; };
@ -120,9 +120,10 @@ impl<M: AccessMesadata> Reconfigure<Autorouter<M>> for MultilayerAutorouteExecut
} }
impl EstimateLinearProgress for MultilayerAutorouteExecutionStepper { impl EstimateLinearProgress for MultilayerAutorouteExecutionStepper {
type Value = f64; type Value = usize;
type Subscale = LinearScale<f64>;
fn estimate_linear_progress(&self) -> LinearProgress<f64> { fn estimate_linear_progress(&self) -> LinearScale<usize, LinearScale<f64>> {
self.planar.estimate_linear_progress() self.planar.estimate_linear_progress()
} }
} }

View File

@ -30,7 +30,7 @@ use crate::{
geometry::primitive::PrimitiveShape, geometry::primitive::PrimitiveShape,
router::{navcord::Navcord, navmesh::Navmesh, thetastar::ThetastarStepper}, router::{navcord::Navcord, navmesh::Navmesh, thetastar::ThetastarStepper},
stepper::{ stepper::{
Abort, EstimateLinearProgress, LinearProgress, ReconfiguratorStatus, Reconfigure, Step, Abort, EstimateLinearProgress, LinearScale, ReconfiguratorStatus, Reconfigure, Step,
}, },
}; };
@ -142,9 +142,10 @@ impl<M: AccessMesadata> Abort<Autorouter<M>> for MultilayerAutorouteReconfigurat
} }
impl EstimateLinearProgress for MultilayerAutorouteReconfigurator { impl EstimateLinearProgress for MultilayerAutorouteReconfigurator {
type Value = f64; type Value = usize;
type Subscale = LinearScale<f64>;
fn estimate_linear_progress(&self) -> LinearProgress<f64> { fn estimate_linear_progress(&self) -> LinearScale<usize, LinearScale<f64>> {
self.stepper.estimate_linear_progress() self.stepper.estimate_linear_progress()
} }
} }

View File

@ -12,7 +12,6 @@ use crate::{
AccessMesadata, AccessMesadata,
}, },
layout::{via::ViaWeight, LayoutEdit}, layout::{via::ViaWeight, LayoutEdit},
stepper::EstimateLinearProgress,
}; };
use super::{invoker::GetDebugOverlayData, Autorouter, AutorouterError}; use super::{invoker::GetDebugOverlayData, Autorouter, AutorouterError};
@ -53,7 +52,4 @@ impl PlaceViaExecutionStepper {
} }
} }
impl EstimateLinearProgress for PlaceViaExecutionStepper {
type Value = f64;
}
impl GetDebugOverlayData for PlaceViaExecutionStepper {} impl GetDebugOverlayData for PlaceViaExecutionStepper {}

View File

@ -21,7 +21,7 @@ use crate::{
router::{ router::{
navcord::Navcord, navmesh::Navmesh, thetastar::ThetastarStepper, RouteStepper, Router, navcord::Navcord, navmesh::Navmesh, thetastar::ThetastarStepper, RouteStepper, Router,
}, },
stepper::{Abort, EstimateLinearProgress, LinearProgress, Reconfigure, Step}, stepper::{Abort, EstimateLinearProgress, LinearScale, Reconfigure, Step},
}; };
use super::{ use super::{
@ -304,16 +304,22 @@ impl<M: AccessMesadata> Reconfigure<Autorouter<M>> for PlanarAutorouteExecutionS
} }
impl EstimateLinearProgress for PlanarAutorouteExecutionStepper { impl EstimateLinearProgress for PlanarAutorouteExecutionStepper {
type Value = f64; type Value = usize;
type Subscale = LinearScale<f64>;
fn estimate_linear_progress(&self) -> LinearProgress<f64> { fn estimate_linear_progress(&self) -> LinearScale<usize, LinearScale<f64>> {
LinearProgress::new( LinearScale::new(
self.curr_ratline_index as f64 self.curr_ratline_index,
+ self.route.as_ref().map_or(0.0, |route| { self.configuration().ratlines.len(),
route.estimate_linear_progress().value() LinearScale::new(
/ route.estimate_linear_progress().maximum() self.route
}), .as_ref()
self.configuration().ratlines.len() as f64, .map_or(0.0, |route| *route.estimate_linear_progress().value()),
self.route
.as_ref()
.map_or(0.0, |route| *route.estimate_linear_progress().maximum()),
(),
),
) )
} }
} }

View File

@ -25,7 +25,7 @@ use crate::{
geometry::primitive::PrimitiveShape, geometry::primitive::PrimitiveShape,
router::{navcord::Navcord, navmesh::Navmesh, thetastar::ThetastarStepper}, router::{navcord::Navcord, navmesh::Navmesh, thetastar::ThetastarStepper},
stepper::{ stepper::{
Abort, EstimateLinearProgress, LinearProgress, ReconfiguratorStatus, Reconfigure, Step, Abort, EstimateLinearProgress, LinearScale, ReconfiguratorStatus, Reconfigure, Step,
}, },
}; };
@ -121,9 +121,10 @@ impl<M: AccessMesadata> Abort<Autorouter<M>> for PlanarAutorouteReconfigurator {
} }
impl EstimateLinearProgress for PlanarAutorouteReconfigurator { impl EstimateLinearProgress for PlanarAutorouteReconfigurator {
type Value = f64; type Value = usize;
type Subscale = LinearScale<f64>;
fn estimate_linear_progress(&self) -> LinearProgress<f64> { fn estimate_linear_progress(&self) -> LinearScale<usize, LinearScale<f64>> {
self.stepper.estimate_linear_progress() self.stepper.estimate_linear_progress()
} }
} }

View File

@ -4,10 +4,7 @@
//! Provides functionality to remove bands from the layout. //! Provides functionality to remove bands from the layout.
use crate::{ use crate::board::{edit::BoardEdit, AccessMesadata};
board::{edit::BoardEdit, AccessMesadata},
stepper::EstimateLinearProgress,
};
use super::{invoker::GetDebugOverlayData, selection::BandSelection, Autorouter, AutorouterError}; use super::{invoker::GetDebugOverlayData, selection::BandSelection, Autorouter, AutorouterError};
@ -48,7 +45,4 @@ impl RemoveBandsExecutionStepper {
} }
} }
impl EstimateLinearProgress for RemoveBandsExecutionStepper {
type Value = f64;
}
impl GetDebugOverlayData for RemoveBandsExecutionStepper {} impl GetDebugOverlayData for RemoveBandsExecutionStepper {}

View File

@ -25,7 +25,7 @@ use crate::{
ng, ng,
thetastar::ThetastarStepper, thetastar::ThetastarStepper,
}, },
stepper::{Abort, EstimateLinearProgress, LinearProgress, OnEvent, Step}, stepper::{Abort, EstimateLinearProgress, LinearScale, OnEvent, Step},
}; };
/// Stores the interactive input data from the user. /// Stores the interactive input data from the user.
@ -101,11 +101,14 @@ impl<M: AccessMesadata + Clone> Abort<Invoker<M>> for ActivityStepper<M> {
// Since enum_dispatch does not really support generics, we implement this the // Since enum_dispatch does not really support generics, we implement this the
// long way. // long way.
impl<M> EstimateLinearProgress for ActivityStepper<M> { impl<M> EstimateLinearProgress for ActivityStepper<M> {
type Value = f64; type Value = usize;
type Subscale = LinearScale<f64>;
fn estimate_linear_progress(&self) -> LinearProgress<f64> { fn estimate_linear_progress(&self) -> LinearScale<usize, LinearScale<f64>> {
match self { match self {
ActivityStepper::Interaction(..) => LinearProgress::new(0.0, 0.0), ActivityStepper::Interaction(..) => {
LinearScale::new(0, 0, LinearScale::new(0.0, 0.0, ()))
}
ActivityStepper::Execution(execution) => execution.estimate_linear_progress(), ActivityStepper::Execution(execution) => execution.estimate_linear_progress(),
} }
} }
@ -193,9 +196,10 @@ impl<M: AccessMesadata + Clone> OnEvent<ActivityContext<'_, M>, InteractiveEvent
} }
impl<M> EstimateLinearProgress for ActivityStepperWithStatus<M> { impl<M> EstimateLinearProgress for ActivityStepperWithStatus<M> {
type Value = f64; type Value = usize;
type Subscale = LinearScale<f64>;
fn estimate_linear_progress(&self) -> LinearProgress<f64> { fn estimate_linear_progress(&self) -> LinearScale<usize, LinearScale<f64>> {
self.activity.estimate_linear_progress() self.activity.estimate_linear_progress()
} }
} }

View File

@ -233,10 +233,6 @@ impl<R: AccessRules + Clone + std::panic::RefUnwindSafe> AutorouteExecutionStepp
} }
} }
impl<M> EstimateLinearProgress for AutorouteExecutionStepper<M> {
type Value = f64;
}
impl<M> GetDebugOverlayData for AutorouteExecutionStepper<M> { impl<M> GetDebugOverlayData for AutorouteExecutionStepper<M> {
fn maybe_topo_navmesh(&self) -> Option<pie::navmesh::NavmeshRef<'_, super::PieNavmeshBase>> { fn maybe_topo_navmesh(&self) -> Option<pie::navmesh::NavmeshRef<'_, super::PieNavmeshBase>> {
Some(pie::navmesh::NavmeshRef { Some(pie::navmesh::NavmeshRef {

View File

@ -19,7 +19,7 @@ use crate::{
thetastar::{ThetastarError, ThetastarStepper}, thetastar::{ThetastarError, ThetastarStepper},
Router, RouterThetastarStrategy, Router, RouterThetastarStrategy,
}, },
stepper::{EstimateLinearProgress, LinearProgress, Step}, stepper::{EstimateLinearProgress, LinearScale, Step},
}; };
#[derive(Getters, Dissolve)] #[derive(Getters, Dissolve)]
@ -101,8 +101,9 @@ impl<R: AccessRules> Step<Router<'_, R>, BandTermsegIndex> for RouteStepper {
impl EstimateLinearProgress for RouteStepper { impl EstimateLinearProgress for RouteStepper {
type Value = f64; type Value = f64;
type Subscale = ();
fn estimate_linear_progress(&self) -> LinearProgress<f64> { fn estimate_linear_progress(&self) -> LinearScale<f64> {
self.thetastar.estimate_linear_progress() self.thetastar.estimate_linear_progress()
} }
} }

View File

@ -20,7 +20,7 @@ use thiserror::Error;
use std::cmp::Ordering; use std::cmp::Ordering;
use crate::stepper::{EstimateLinearProgress, LinearProgress, Step}; use crate::stepper::{EstimateLinearProgress, LinearScale, Step};
#[derive(Copy, Clone, Debug)] #[derive(Copy, Clone, Debug)]
pub struct MinScored<K, T>(pub K, pub T); pub struct MinScored<K, T>(pub K, pub T);
@ -451,8 +451,13 @@ where
K: Measure + Copy + Sub<Output = K>, K: Measure + Copy + Sub<Output = K>,
{ {
type Value = K; type Value = K;
type Subscale = ();
fn estimate_linear_progress(&self) -> LinearProgress<Self::Value> { fn estimate_linear_progress(&self) -> LinearScale<Self::Value> {
LinearProgress::new(self.progress_estimate_value, self.progress_estimate_maximum) LinearScale::new(
self.progress_estimate_value,
self.progress_estimate_maximum,
(),
)
} }
} }

View File

@ -84,22 +84,36 @@ pub trait OnEvent<Ctx, Event> {
} }
#[derive(Clone, Copy, Debug, Getters)] #[derive(Clone, Copy, Debug, Getters)]
pub struct LinearProgress<V> { pub struct LinearScale<V, S = ()> {
value: V, value: V,
maximum: V, maximum: V,
subscale: S,
} }
impl<V> LinearProgress<V> { impl<V, S> LinearScale<V, S> {
pub fn new(value: V, maximum: V) -> Self { pub fn new(value: V, maximum: V, subscale: S) -> Self {
Self { value, maximum } Self {
value,
maximum,
subscale,
}
}
}
impl<V: Default> Default for LinearScale<V> {
fn default() -> Self {
Self {
value: V::default(),
maximum: V::default(),
subscale: (),
}
} }
} }
/// Some steppers report estimates of how far they are from completion. /// Some steppers report estimates of how far they are from completion.
pub trait EstimateLinearProgress { pub trait EstimateLinearProgress {
type Value: Default; type Value;
type Subscale;
fn estimate_linear_progress(&self) -> LinearProgress<Self::Value> { fn estimate_linear_progress(&self) -> LinearScale<Self::Value, Self::Subscale>;
LinearProgress::new(Self::Value::default(), Self::Value::default())
}
} }