egui,autorouter: make detour comparison invokable from GUI

This commit is contained in:
Mikolaj Wielgus 2024-08-05 13:14:56 +02:00
parent b2c9305cea
commit 47d8e82344
5 changed files with 60 additions and 33 deletions

View File

@ -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<M: AccessMesadata> Autorouter<M> {
todo!();
}
pub fn compare(&mut self, selection: &PinSelection) -> Result<Compare, AutorouterError> {
pub fn compare(&mut self, selection: &PinSelection) -> Result<CompareDetours, AutorouterError> {
self.compare_ratlines(self.selected_ratlines(selection))
}
fn compare_ratlines(
&mut self,
ratlines: Vec<EdgeIndex<usize>>,
) -> Result<Compare, AutorouterError> {
) -> Result<CompareDetours, AutorouterError> {
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(

View File

@ -15,22 +15,22 @@ use super::{
Autorouter, AutorouterError,
};
pub enum CompareStatus {
pub enum CompareDetoursStatus {
Running,
Finished(f64),
}
impl TryInto<f64> for CompareStatus {
impl TryInto<f64> for CompareDetoursStatus {
type Error = ();
fn try_into(self) -> Result<f64, ()> {
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<Autoroute>,
ratline1: EdgeIndex<usize>,
@ -39,7 +39,7 @@ pub struct Compare {
total_length2: Option<f64>,
}
impl Compare {
impl CompareDetours {
pub fn new(
autorouter: &mut Autorouter<impl AccessMesadata>,
ratline1: EdgeIndex<usize>,
@ -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<M: AccessMesadata> Step<Autorouter<M>, CompareStatus, AutorouterError, f64> for Compare {
fn step(&mut self, autorouter: &mut Autorouter<M>) -> Result<CompareStatus, AutorouterError> {
impl<M: AccessMesadata> Step<Autorouter<M>, CompareDetoursStatus, AutorouterError, f64>
for CompareDetours
{
fn step(
&mut self,
autorouter: &mut Autorouter<M>,
) -> Result<CompareDetoursStatus, AutorouterError> {
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<M: AccessMesadata> Step<Autorouter<M>, 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<M: AccessMesadata> Step<Autorouter<M>, 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()
}

View File

@ -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<M: AccessMesadata> Invoker<M> {
Command::RemoveBands(selection) => Ok::<Execute, InvokerError>(Execute::RemoveBands(
self.autorouter.remove_bands(selection)?,
)),
Command::Compare(selection) => {
Ok::<Execute, InvokerError>(Execute::Compare(self.autorouter.compare(selection)?))
}
Command::CompareDetours(selection) => Ok::<Execute, InvokerError>(
Execute::CompareDetours(self.autorouter.compare(selection)?),
),
}
}
@ -252,7 +252,7 @@ impl<M: AccessMesadata> Invoker<M> {
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()?)

View File

@ -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;

View File

@ -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 OriginDestination");
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>(())