From 47d8e8234467046dbfcee1d54994accc946507d0 Mon Sep 17 00:00:00 2001 From: Mikolaj Wielgus Date: Mon, 5 Aug 2024 13:14:56 +0200 Subject: [PATCH] egui,autorouter: make detour comparison invokable from GUI --- src/autorouter/autorouter.rs | 8 ++-- .../{compare.rs => compare_detours.rs} | 37 +++++++++++-------- src/autorouter/invoker.rs | 20 +++++----- src/autorouter/mod.rs | 2 +- src/bin/topola-egui/top.rs | 26 ++++++++++++- 5 files changed, 60 insertions(+), 33 deletions(-) rename src/autorouter/{compare.rs => compare_detours.rs} (76%) diff --git a/src/autorouter/autorouter.rs b/src/autorouter/autorouter.rs index 938c386..a9c72d6 100644 --- a/src/autorouter/autorouter.rs +++ b/src/autorouter/autorouter.rs @@ -12,7 +12,7 @@ use crate::{ use super::{ autoroute::Autoroute, - compare::Compare, + compare_detours::CompareDetours, place_via::PlaceVia, ratsnest::{Ratsnest, RatvertexIndex}, remove_bands::RemoveBands, @@ -88,21 +88,21 @@ impl Autorouter { todo!(); } - pub fn compare(&mut self, selection: &PinSelection) -> Result { + pub fn compare(&mut self, selection: &PinSelection) -> Result { self.compare_ratlines(self.selected_ratlines(selection)) } fn compare_ratlines( &mut self, ratlines: Vec>, - ) -> Result { + ) -> Result { let ratline1 = *ratlines .get(0) .ok_or(AutorouterError::NeedExactlyTwoRatlines)?; let ratline2 = *ratlines .get(1) .ok_or(AutorouterError::NeedExactlyTwoRatlines)?; - Compare::new(self, ratline1, ratline2) + CompareDetours::new(self, ratline1, ratline2) } pub fn ratline_endpoints( diff --git a/src/autorouter/compare.rs b/src/autorouter/compare_detours.rs similarity index 76% rename from src/autorouter/compare.rs rename to src/autorouter/compare_detours.rs index 06c694a..12506ac 100644 --- a/src/autorouter/compare.rs +++ b/src/autorouter/compare_detours.rs @@ -15,22 +15,22 @@ use super::{ Autorouter, AutorouterError, }; -pub enum CompareStatus { +pub enum CompareDetoursStatus { Running, Finished(f64), } -impl TryInto for CompareStatus { +impl TryInto for CompareDetoursStatus { type Error = (); fn try_into(self) -> Result { match self { - CompareStatus::Running => Err(()), - CompareStatus::Finished(delta) => Ok(delta), + CompareDetoursStatus::Running => Err(()), + CompareDetoursStatus::Finished(delta) => Ok(delta), } } } -pub struct Compare { +pub struct CompareDetours { autoroute: Autoroute, next_autoroute: Option, ratline1: EdgeIndex, @@ -39,7 +39,7 @@ pub struct Compare { total_length2: Option, } -impl Compare { +impl CompareDetours { pub fn new( autorouter: &mut Autorouter, ratline1: EdgeIndex, @@ -58,10 +58,15 @@ impl Compare { // XXX: Do we really need this to be a stepper? We don't use at the moment, as sorting functions // aren't steppable either. It may be useful for debugging later on tho. -impl Step, CompareStatus, AutorouterError, f64> for Compare { - fn step(&mut self, autorouter: &mut Autorouter) -> Result { +impl Step, CompareDetoursStatus, AutorouterError, f64> + for CompareDetours +{ + fn step( + &mut self, + autorouter: &mut Autorouter, + ) -> Result { match self.autoroute.step(autorouter)? { - AutorouteStatus::Running => Ok(CompareStatus::Running), + AutorouteStatus::Running => Ok(CompareDetoursStatus::Running), AutorouteStatus::Routed(band_termseg) => { let length = band_termseg .ref_(autorouter.board.layout().drawing()) @@ -75,18 +80,18 @@ impl Step, CompareStatus, AutorouterError, f64> panic!(); } - Ok(CompareStatus::Running) + Ok(CompareDetoursStatus::Running) } AutorouteStatus::Finished => { if let Some(next_autoroute) = self.next_autoroute.take() { autorouter.undo_autoroute_ratlines(vec![self.ratline1, self.ratline2]); self.autoroute = next_autoroute; - Ok(CompareStatus::Running) + Ok(CompareDetoursStatus::Running) } else { autorouter.undo_autoroute_ratlines(vec![self.ratline2, self.ratline1]); - Ok(CompareStatus::Finished( + Ok(CompareDetoursStatus::Finished( self.total_length1.unwrap() - self.total_length2.unwrap(), )) } @@ -95,25 +100,25 @@ impl Step, CompareStatus, AutorouterError, f64> } } -impl GetMaybeNavmesh for Compare { +impl GetMaybeNavmesh for CompareDetours { fn maybe_navmesh(&self) -> Option<&Navmesh> { self.autoroute.maybe_navmesh() } } -impl GetMaybeTrace for Compare { +impl GetMaybeTrace for CompareDetours { fn maybe_trace(&self) -> Option<&Trace> { self.autoroute.maybe_trace() } } -impl GetGhosts for Compare { +impl GetGhosts for CompareDetours { fn ghosts(&self) -> &[PrimitiveShape] { self.autoroute.ghosts() } } -impl GetObstacles for Compare { +impl GetObstacles for CompareDetours { fn obstacles(&self) -> &[PrimitiveIndex] { self.autoroute.obstacles() } diff --git a/src/autorouter/invoker.rs b/src/autorouter/invoker.rs index a56d285..9fc389c 100644 --- a/src/autorouter/invoker.rs +++ b/src/autorouter/invoker.rs @@ -14,7 +14,7 @@ use crate::{ use super::{ autoroute::{Autoroute, AutorouteStatus}, - compare::{Compare, CompareStatus}, + compare_detours::{CompareDetours, CompareDetoursStatus}, history::{History, HistoryError}, place_via::PlaceVia, remove_bands::RemoveBands, @@ -71,7 +71,7 @@ pub enum Command { Autoroute(PinSelection), PlaceVia(ViaWeight), RemoveBands(BandSelection), - Compare(PinSelection), + CompareDetours(PinSelection), } #[enum_dispatch(GetMaybeNavmesh, GetMaybeTrace, GetGhosts, GetObstacles)] @@ -79,7 +79,7 @@ pub enum Execute { Autoroute(Autoroute), PlaceVia(PlaceVia), RemoveBands(RemoveBands), - Compare(Compare), + CompareDetours(CompareDetours), } impl Execute { @@ -101,9 +101,9 @@ impl Execute { remove_bands.doit(&mut invoker.autorouter)?; Ok(InvokerStatus::Finished) } - Execute::Compare(compare) => match compare.step(&mut invoker.autorouter)? { - CompareStatus::Running => Ok(InvokerStatus::Running), - CompareStatus::Finished(delta) => Ok(InvokerStatus::Finished), + Execute::CompareDetours(compare) => match compare.step(&mut invoker.autorouter)? { + CompareDetoursStatus::Running => Ok(InvokerStatus::Running), + CompareDetoursStatus::Finished(delta) => Ok(InvokerStatus::Finished), }, } } @@ -238,9 +238,9 @@ impl Invoker { Command::RemoveBands(selection) => Ok::(Execute::RemoveBands( self.autorouter.remove_bands(selection)?, )), - Command::Compare(selection) => { - Ok::(Execute::Compare(self.autorouter.compare(selection)?)) - } + Command::CompareDetours(selection) => Ok::( + Execute::CompareDetours(self.autorouter.compare(selection)?), + ), } } @@ -252,7 +252,7 @@ impl Invoker { Command::Autoroute(ref selection) => self.autorouter.undo_autoroute(selection), Command::PlaceVia(weight) => self.autorouter.undo_place_via(*weight), Command::RemoveBands(ref selection) => self.autorouter.undo_remove_bands(selection), - Command::Compare(..) => (), + Command::CompareDetours(..) => (), } Ok::<(), InvokerError>(self.history.undo()?) diff --git a/src/autorouter/mod.rs b/src/autorouter/mod.rs index 94c5d81..dd32e30 100644 --- a/src/autorouter/mod.rs +++ b/src/autorouter/mod.rs @@ -1,6 +1,6 @@ pub mod autoroute; mod autorouter; -pub mod compare; +pub mod compare_detours; pub mod history; pub mod invoker; pub mod place_via; diff --git a/src/bin/topola-egui/top.rs b/src/bin/topola-egui/top.rs index 831093d..720153d 100644 --- a/src/bin/topola-egui/top.rs +++ b/src/bin/topola-egui/top.rs @@ -80,6 +80,11 @@ impl Top { egui::Modifiers::NONE, egui::Key::Delete, )); + let mut compare_detours = Trigger::new(Action::new( + "Compare Detours", + egui::Modifiers::NONE, + egui::Key::Minus, + )); let mut undo = Trigger::new(Action::new("Undo", egui::Modifiers::CTRL, egui::Key::Z)); let mut redo = Trigger::new(Action::new("Redo", egui::Modifiers::CTRL, egui::Key::Y)); @@ -123,6 +128,9 @@ impl Top { ui.checkbox(&mut self.show_navmesh, "Show Navmesh"); ui.checkbox(&mut self.show_bboxes, "Show BBoxes"); ui.checkbox(&mut self.show_origin_destination, "Show Origin–Destination"); + + ui.separator(); + compare_detours.button(ctx, ui); }); ui.separator(); @@ -240,10 +248,24 @@ impl Top { invoker.undo(); } } else if redo.consume_key_triggered(ctx, ui) { - if let Some(ref mut invoker) = arc_mutex_maybe_invoker.lock().unwrap().as_mut() - { + if let Some(invoker) = arc_mutex_maybe_invoker.lock().unwrap().as_mut() { invoker.redo(); } + } else if compare_detours.consume_key_triggered(ctx, ui) { + if maybe_execute.as_mut().map_or(true, |execute| { + matches!(execute.maybe_status(), Some(InvokerStatus::Finished)) + }) { + if let (Some(invoker), Some(ref mut overlay)) = ( + arc_mutex_maybe_invoker.lock().unwrap().as_mut(), + maybe_overlay, + ) { + let selection = overlay.selection().clone(); + overlay.clear_selection(); + maybe_execute.insert(ExecuteWithStatus::new(invoker.execute_stepper( + Command::CompareDetours(selection.pin_selection), + )?)); + } + } } Ok::<(), InvokerError>(())