mirror of https://codeberg.org/topola/topola.git
egui,autorouter: make detour comparison invokable from GUI
This commit is contained in:
parent
b2c9305cea
commit
47d8e82344
|
|
@ -12,7 +12,7 @@ use crate::{
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
autoroute::Autoroute,
|
autoroute::Autoroute,
|
||||||
compare::Compare,
|
compare_detours::CompareDetours,
|
||||||
place_via::PlaceVia,
|
place_via::PlaceVia,
|
||||||
ratsnest::{Ratsnest, RatvertexIndex},
|
ratsnest::{Ratsnest, RatvertexIndex},
|
||||||
remove_bands::RemoveBands,
|
remove_bands::RemoveBands,
|
||||||
|
|
@ -88,21 +88,21 @@ impl<M: AccessMesadata> Autorouter<M> {
|
||||||
todo!();
|
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))
|
self.compare_ratlines(self.selected_ratlines(selection))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compare_ratlines(
|
fn compare_ratlines(
|
||||||
&mut self,
|
&mut self,
|
||||||
ratlines: Vec<EdgeIndex<usize>>,
|
ratlines: Vec<EdgeIndex<usize>>,
|
||||||
) -> Result<Compare, AutorouterError> {
|
) -> Result<CompareDetours, AutorouterError> {
|
||||||
let ratline1 = *ratlines
|
let ratline1 = *ratlines
|
||||||
.get(0)
|
.get(0)
|
||||||
.ok_or(AutorouterError::NeedExactlyTwoRatlines)?;
|
.ok_or(AutorouterError::NeedExactlyTwoRatlines)?;
|
||||||
let ratline2 = *ratlines
|
let ratline2 = *ratlines
|
||||||
.get(1)
|
.get(1)
|
||||||
.ok_or(AutorouterError::NeedExactlyTwoRatlines)?;
|
.ok_or(AutorouterError::NeedExactlyTwoRatlines)?;
|
||||||
Compare::new(self, ratline1, ratline2)
|
CompareDetours::new(self, ratline1, ratline2)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ratline_endpoints(
|
pub fn ratline_endpoints(
|
||||||
|
|
|
||||||
|
|
@ -15,22 +15,22 @@ use super::{
|
||||||
Autorouter, AutorouterError,
|
Autorouter, AutorouterError,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub enum CompareStatus {
|
pub enum CompareDetoursStatus {
|
||||||
Running,
|
Running,
|
||||||
Finished(f64),
|
Finished(f64),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryInto<f64> for CompareStatus {
|
impl TryInto<f64> for CompareDetoursStatus {
|
||||||
type Error = ();
|
type Error = ();
|
||||||
fn try_into(self) -> Result<f64, ()> {
|
fn try_into(self) -> Result<f64, ()> {
|
||||||
match self {
|
match self {
|
||||||
CompareStatus::Running => Err(()),
|
CompareDetoursStatus::Running => Err(()),
|
||||||
CompareStatus::Finished(delta) => Ok(delta),
|
CompareDetoursStatus::Finished(delta) => Ok(delta),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Compare {
|
pub struct CompareDetours {
|
||||||
autoroute: Autoroute,
|
autoroute: Autoroute,
|
||||||
next_autoroute: Option<Autoroute>,
|
next_autoroute: Option<Autoroute>,
|
||||||
ratline1: EdgeIndex<usize>,
|
ratline1: EdgeIndex<usize>,
|
||||||
|
|
@ -39,7 +39,7 @@ pub struct Compare {
|
||||||
total_length2: Option<f64>,
|
total_length2: Option<f64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Compare {
|
impl CompareDetours {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
autorouter: &mut Autorouter<impl AccessMesadata>,
|
autorouter: &mut Autorouter<impl AccessMesadata>,
|
||||||
ratline1: EdgeIndex<usize>,
|
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
|
// 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.
|
// aren't steppable either. It may be useful for debugging later on tho.
|
||||||
impl<M: AccessMesadata> Step<Autorouter<M>, CompareStatus, AutorouterError, f64> for Compare {
|
impl<M: AccessMesadata> Step<Autorouter<M>, CompareDetoursStatus, AutorouterError, f64>
|
||||||
fn step(&mut self, autorouter: &mut Autorouter<M>) -> Result<CompareStatus, AutorouterError> {
|
for CompareDetours
|
||||||
|
{
|
||||||
|
fn step(
|
||||||
|
&mut self,
|
||||||
|
autorouter: &mut Autorouter<M>,
|
||||||
|
) -> Result<CompareDetoursStatus, AutorouterError> {
|
||||||
match self.autoroute.step(autorouter)? {
|
match self.autoroute.step(autorouter)? {
|
||||||
AutorouteStatus::Running => Ok(CompareStatus::Running),
|
AutorouteStatus::Running => Ok(CompareDetoursStatus::Running),
|
||||||
AutorouteStatus::Routed(band_termseg) => {
|
AutorouteStatus::Routed(band_termseg) => {
|
||||||
let length = band_termseg
|
let length = band_termseg
|
||||||
.ref_(autorouter.board.layout().drawing())
|
.ref_(autorouter.board.layout().drawing())
|
||||||
|
|
@ -75,18 +80,18 @@ impl<M: AccessMesadata> Step<Autorouter<M>, CompareStatus, AutorouterError, f64>
|
||||||
panic!();
|
panic!();
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(CompareStatus::Running)
|
Ok(CompareDetoursStatus::Running)
|
||||||
}
|
}
|
||||||
AutorouteStatus::Finished => {
|
AutorouteStatus::Finished => {
|
||||||
if let Some(next_autoroute) = self.next_autoroute.take() {
|
if let Some(next_autoroute) = self.next_autoroute.take() {
|
||||||
autorouter.undo_autoroute_ratlines(vec![self.ratline1, self.ratline2]);
|
autorouter.undo_autoroute_ratlines(vec![self.ratline1, self.ratline2]);
|
||||||
self.autoroute = next_autoroute;
|
self.autoroute = next_autoroute;
|
||||||
|
|
||||||
Ok(CompareStatus::Running)
|
Ok(CompareDetoursStatus::Running)
|
||||||
} else {
|
} else {
|
||||||
autorouter.undo_autoroute_ratlines(vec![self.ratline2, self.ratline1]);
|
autorouter.undo_autoroute_ratlines(vec![self.ratline2, self.ratline1]);
|
||||||
|
|
||||||
Ok(CompareStatus::Finished(
|
Ok(CompareDetoursStatus::Finished(
|
||||||
self.total_length1.unwrap() - self.total_length2.unwrap(),
|
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> {
|
fn maybe_navmesh(&self) -> Option<&Navmesh> {
|
||||||
self.autoroute.maybe_navmesh()
|
self.autoroute.maybe_navmesh()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GetMaybeTrace for Compare {
|
impl GetMaybeTrace for CompareDetours {
|
||||||
fn maybe_trace(&self) -> Option<&Trace> {
|
fn maybe_trace(&self) -> Option<&Trace> {
|
||||||
self.autoroute.maybe_trace()
|
self.autoroute.maybe_trace()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GetGhosts for Compare {
|
impl GetGhosts for CompareDetours {
|
||||||
fn ghosts(&self) -> &[PrimitiveShape] {
|
fn ghosts(&self) -> &[PrimitiveShape] {
|
||||||
self.autoroute.ghosts()
|
self.autoroute.ghosts()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GetObstacles for Compare {
|
impl GetObstacles for CompareDetours {
|
||||||
fn obstacles(&self) -> &[PrimitiveIndex] {
|
fn obstacles(&self) -> &[PrimitiveIndex] {
|
||||||
self.autoroute.obstacles()
|
self.autoroute.obstacles()
|
||||||
}
|
}
|
||||||
|
|
@ -14,7 +14,7 @@ use crate::{
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
autoroute::{Autoroute, AutorouteStatus},
|
autoroute::{Autoroute, AutorouteStatus},
|
||||||
compare::{Compare, CompareStatus},
|
compare_detours::{CompareDetours, CompareDetoursStatus},
|
||||||
history::{History, HistoryError},
|
history::{History, HistoryError},
|
||||||
place_via::PlaceVia,
|
place_via::PlaceVia,
|
||||||
remove_bands::RemoveBands,
|
remove_bands::RemoveBands,
|
||||||
|
|
@ -71,7 +71,7 @@ pub enum Command {
|
||||||
Autoroute(PinSelection),
|
Autoroute(PinSelection),
|
||||||
PlaceVia(ViaWeight),
|
PlaceVia(ViaWeight),
|
||||||
RemoveBands(BandSelection),
|
RemoveBands(BandSelection),
|
||||||
Compare(PinSelection),
|
CompareDetours(PinSelection),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[enum_dispatch(GetMaybeNavmesh, GetMaybeTrace, GetGhosts, GetObstacles)]
|
#[enum_dispatch(GetMaybeNavmesh, GetMaybeTrace, GetGhosts, GetObstacles)]
|
||||||
|
|
@ -79,7 +79,7 @@ pub enum Execute {
|
||||||
Autoroute(Autoroute),
|
Autoroute(Autoroute),
|
||||||
PlaceVia(PlaceVia),
|
PlaceVia(PlaceVia),
|
||||||
RemoveBands(RemoveBands),
|
RemoveBands(RemoveBands),
|
||||||
Compare(Compare),
|
CompareDetours(CompareDetours),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Execute {
|
impl Execute {
|
||||||
|
|
@ -101,9 +101,9 @@ impl Execute {
|
||||||
remove_bands.doit(&mut invoker.autorouter)?;
|
remove_bands.doit(&mut invoker.autorouter)?;
|
||||||
Ok(InvokerStatus::Finished)
|
Ok(InvokerStatus::Finished)
|
||||||
}
|
}
|
||||||
Execute::Compare(compare) => match compare.step(&mut invoker.autorouter)? {
|
Execute::CompareDetours(compare) => match compare.step(&mut invoker.autorouter)? {
|
||||||
CompareStatus::Running => Ok(InvokerStatus::Running),
|
CompareDetoursStatus::Running => Ok(InvokerStatus::Running),
|
||||||
CompareStatus::Finished(delta) => Ok(InvokerStatus::Finished),
|
CompareDetoursStatus::Finished(delta) => Ok(InvokerStatus::Finished),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -238,9 +238,9 @@ impl<M: AccessMesadata> Invoker<M> {
|
||||||
Command::RemoveBands(selection) => Ok::<Execute, InvokerError>(Execute::RemoveBands(
|
Command::RemoveBands(selection) => Ok::<Execute, InvokerError>(Execute::RemoveBands(
|
||||||
self.autorouter.remove_bands(selection)?,
|
self.autorouter.remove_bands(selection)?,
|
||||||
)),
|
)),
|
||||||
Command::Compare(selection) => {
|
Command::CompareDetours(selection) => Ok::<Execute, InvokerError>(
|
||||||
Ok::<Execute, InvokerError>(Execute::Compare(self.autorouter.compare(selection)?))
|
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::Autoroute(ref selection) => self.autorouter.undo_autoroute(selection),
|
||||||
Command::PlaceVia(weight) => self.autorouter.undo_place_via(*weight),
|
Command::PlaceVia(weight) => self.autorouter.undo_place_via(*weight),
|
||||||
Command::RemoveBands(ref selection) => self.autorouter.undo_remove_bands(selection),
|
Command::RemoveBands(ref selection) => self.autorouter.undo_remove_bands(selection),
|
||||||
Command::Compare(..) => (),
|
Command::CompareDetours(..) => (),
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok::<(), InvokerError>(self.history.undo()?)
|
Ok::<(), InvokerError>(self.history.undo()?)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
pub mod autoroute;
|
pub mod autoroute;
|
||||||
mod autorouter;
|
mod autorouter;
|
||||||
pub mod compare;
|
pub mod compare_detours;
|
||||||
pub mod history;
|
pub mod history;
|
||||||
pub mod invoker;
|
pub mod invoker;
|
||||||
pub mod place_via;
|
pub mod place_via;
|
||||||
|
|
|
||||||
|
|
@ -80,6 +80,11 @@ impl Top {
|
||||||
egui::Modifiers::NONE,
|
egui::Modifiers::NONE,
|
||||||
egui::Key::Delete,
|
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 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));
|
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_navmesh, "Show Navmesh");
|
||||||
ui.checkbox(&mut self.show_bboxes, "Show BBoxes");
|
ui.checkbox(&mut self.show_bboxes, "Show BBoxes");
|
||||||
ui.checkbox(&mut self.show_origin_destination, "Show Origin–Destination");
|
ui.checkbox(&mut self.show_origin_destination, "Show Origin–Destination");
|
||||||
|
|
||||||
|
ui.separator();
|
||||||
|
compare_detours.button(ctx, ui);
|
||||||
});
|
});
|
||||||
|
|
||||||
ui.separator();
|
ui.separator();
|
||||||
|
|
@ -240,10 +248,24 @@ impl Top {
|
||||||
invoker.undo();
|
invoker.undo();
|
||||||
}
|
}
|
||||||
} else if redo.consume_key_triggered(ctx, ui) {
|
} 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();
|
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>(())
|
Ok::<(), InvokerError>(())
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue