mirror of https://codeberg.org/topola/topola.git
autorouter: add new compare command to be used for sorting later
This commit is contained in:
parent
43b48e78e3
commit
b2c9305cea
|
|
@ -10,9 +10,26 @@ use crate::{
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
invoker::{GetGhosts, GetMaybeNavmesh, GetMaybeTrace, GetObstacles},
|
invoker::{GetGhosts, GetMaybeNavmesh, GetMaybeTrace, GetObstacles},
|
||||||
Autorouter, AutorouterError, AutorouterStatus,
|
Autorouter, AutorouterError,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub enum AutorouteStatus {
|
||||||
|
Running,
|
||||||
|
Routed(BandTermsegIndex),
|
||||||
|
Finished,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryInto<()> for AutorouteStatus {
|
||||||
|
type Error = ();
|
||||||
|
fn try_into(self) -> Result<(), ()> {
|
||||||
|
match self {
|
||||||
|
AutorouteStatus::Running => Err(()),
|
||||||
|
AutorouteStatus::Routed(..) => Err(()),
|
||||||
|
AutorouteStatus::Finished => Ok(()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Autoroute {
|
pub struct Autoroute {
|
||||||
ratlines_iter: Box<dyn Iterator<Item = EdgeIndex<usize>>>,
|
ratlines_iter: Box<dyn Iterator<Item = EdgeIndex<usize>>>,
|
||||||
route: Option<Route>,
|
route: Option<Route>,
|
||||||
|
|
@ -43,18 +60,15 @@ impl Autoroute {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M: AccessMesadata> Step<Autorouter<M>, AutorouterStatus, AutorouterError, ()> for Autoroute {
|
impl<M: AccessMesadata> Step<Autorouter<M>, AutorouteStatus, AutorouterError, ()> for Autoroute {
|
||||||
fn step(
|
fn step(&mut self, autorouter: &mut Autorouter<M>) -> Result<AutorouteStatus, AutorouterError> {
|
||||||
&mut self,
|
|
||||||
autorouter: &mut Autorouter<M>,
|
|
||||||
) -> Result<AutorouterStatus, AutorouterError> {
|
|
||||||
let Some(ref mut route) = self.route else {
|
let Some(ref mut route) = self.route else {
|
||||||
// Shouldn't happen.
|
// Shouldn't happen.
|
||||||
return Ok(AutorouterStatus::Finished);
|
return Ok(AutorouteStatus::Finished);
|
||||||
};
|
};
|
||||||
|
|
||||||
let Some(curr_ratline) = self.curr_ratline else {
|
let Some(curr_ratline) = self.curr_ratline else {
|
||||||
return Ok(AutorouterStatus::Finished);
|
return Ok(AutorouteStatus::Finished);
|
||||||
};
|
};
|
||||||
|
|
||||||
let (source, target) = autorouter.ratline_endpoints(curr_ratline);
|
let (source, target) = autorouter.ratline_endpoints(curr_ratline);
|
||||||
|
|
@ -63,7 +77,7 @@ impl<M: AccessMesadata> Step<Autorouter<M>, AutorouterStatus, AutorouterError, (
|
||||||
let mut router = Router::new(autorouter.board.layout_mut());
|
let mut router = Router::new(autorouter.board.layout_mut());
|
||||||
|
|
||||||
let RouterStatus::Finished(band_termseg) = route.step(&mut router)? else {
|
let RouterStatus::Finished(band_termseg) = route.step(&mut router)? else {
|
||||||
return Ok(AutorouterStatus::Running);
|
return Ok(AutorouteStatus::Running);
|
||||||
};
|
};
|
||||||
band_termseg
|
band_termseg
|
||||||
};
|
};
|
||||||
|
|
@ -85,7 +99,7 @@ impl<M: AccessMesadata> Step<Autorouter<M>, AutorouterStatus, AutorouterError, (
|
||||||
|
|
||||||
let Some(new_ratline) = self.ratlines_iter.next() else {
|
let Some(new_ratline) = self.ratlines_iter.next() else {
|
||||||
self.curr_ratline = None;
|
self.curr_ratline = None;
|
||||||
return Ok(AutorouterStatus::Finished);
|
return Ok(AutorouteStatus::Finished);
|
||||||
};
|
};
|
||||||
|
|
||||||
let (source, target) = autorouter.ratline_endpoints(new_ratline);
|
let (source, target) = autorouter.ratline_endpoints(new_ratline);
|
||||||
|
|
@ -94,7 +108,7 @@ impl<M: AccessMesadata> Step<Autorouter<M>, AutorouterStatus, AutorouterError, (
|
||||||
self.curr_ratline = Some(new_ratline);
|
self.curr_ratline = Some(new_ratline);
|
||||||
self.route = Some(router.route(source, target, 100.0)?);
|
self.route = Some(router.route(source, target, 100.0)?);
|
||||||
|
|
||||||
Ok(AutorouterStatus::Routed(band_termseg))
|
Ok(AutorouteStatus::Routed(band_termseg))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ use thiserror::Error;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
board::{mesadata::AccessMesadata, Board},
|
board::{mesadata::AccessMesadata, Board},
|
||||||
drawing::{band::BandTermsegIndex, dot::FixedDotIndex, Infringement},
|
drawing::{dot::FixedDotIndex, Infringement},
|
||||||
layout::via::ViaWeight,
|
layout::via::ViaWeight,
|
||||||
router::{navmesh::NavmeshError, RouterError},
|
router::{navmesh::NavmeshError, RouterError},
|
||||||
triangulation::GetTrianvertexNodeIndex,
|
triangulation::GetTrianvertexNodeIndex,
|
||||||
|
|
@ -12,6 +12,7 @@ use crate::{
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
autoroute::Autoroute,
|
autoroute::Autoroute,
|
||||||
|
compare::Compare,
|
||||||
place_via::PlaceVia,
|
place_via::PlaceVia,
|
||||||
ratsnest::{Ratsnest, RatvertexIndex},
|
ratsnest::{Ratsnest, RatvertexIndex},
|
||||||
remove_bands::RemoveBands,
|
remove_bands::RemoveBands,
|
||||||
|
|
@ -28,23 +29,8 @@ pub enum AutorouterError {
|
||||||
Router(#[from] RouterError),
|
Router(#[from] RouterError),
|
||||||
#[error("could not place via")]
|
#[error("could not place via")]
|
||||||
CouldNotPlaceVia(#[from] Infringement),
|
CouldNotPlaceVia(#[from] Infringement),
|
||||||
}
|
#[error("need exactly two ratlines")]
|
||||||
|
NeedExactlyTwoRatlines,
|
||||||
pub enum AutorouterStatus {
|
|
||||||
Running,
|
|
||||||
Routed(BandTermsegIndex),
|
|
||||||
Finished,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TryInto<()> for AutorouterStatus {
|
|
||||||
type Error = ();
|
|
||||||
fn try_into(self) -> Result<(), ()> {
|
|
||||||
match self {
|
|
||||||
AutorouterStatus::Running => Err(()),
|
|
||||||
AutorouterStatus::Routed(..) => Err(()),
|
|
||||||
AutorouterStatus::Finished => Ok(()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Autorouter<M: AccessMesadata> {
|
pub struct Autorouter<M: AccessMesadata> {
|
||||||
|
|
@ -59,11 +45,22 @@ impl<M: AccessMesadata> Autorouter<M> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn autoroute(&mut self, selection: &PinSelection) -> Result<Autoroute, AutorouterError> {
|
pub fn autoroute(&mut self, selection: &PinSelection) -> Result<Autoroute, AutorouterError> {
|
||||||
Autoroute::new(self, self.selected_ratlines(selection))
|
self.autoroute_ratlines(self.selected_ratlines(selection))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(super) fn autoroute_ratlines(
|
||||||
|
&mut self,
|
||||||
|
ratlines: Vec<EdgeIndex<usize>>,
|
||||||
|
) -> Result<Autoroute, AutorouterError> {
|
||||||
|
Autoroute::new(self, ratlines)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn undo_autoroute(&mut self, selection: &PinSelection) {
|
pub fn undo_autoroute(&mut self, selection: &PinSelection) {
|
||||||
for ratline in self.selected_ratlines(selection).iter() {
|
self.undo_autoroute_ratlines(self.selected_ratlines(selection))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(super) fn undo_autoroute_ratlines(&mut self, ratlines: Vec<EdgeIndex<usize>>) {
|
||||||
|
for ratline in ratlines.iter() {
|
||||||
let band = self
|
let band = self
|
||||||
.ratsnest
|
.ratsnest
|
||||||
.graph()
|
.graph()
|
||||||
|
|
@ -91,6 +88,23 @@ impl<M: AccessMesadata> Autorouter<M> {
|
||||||
todo!();
|
todo!();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn compare(&mut self, selection: &PinSelection) -> Result<Compare, AutorouterError> {
|
||||||
|
self.compare_ratlines(self.selected_ratlines(selection))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn compare_ratlines(
|
||||||
|
&mut self,
|
||||||
|
ratlines: Vec<EdgeIndex<usize>>,
|
||||||
|
) -> Result<Compare, AutorouterError> {
|
||||||
|
let ratline1 = *ratlines
|
||||||
|
.get(0)
|
||||||
|
.ok_or(AutorouterError::NeedExactlyTwoRatlines)?;
|
||||||
|
let ratline2 = *ratlines
|
||||||
|
.get(1)
|
||||||
|
.ok_or(AutorouterError::NeedExactlyTwoRatlines)?;
|
||||||
|
Compare::new(self, ratline1, ratline2)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn ratline_endpoints(
|
pub fn ratline_endpoints(
|
||||||
&mut self,
|
&mut self,
|
||||||
ratline: EdgeIndex<usize>,
|
ratline: EdgeIndex<usize>,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,120 @@
|
||||||
|
use petgraph::graph::EdgeIndex;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
board::mesadata::AccessMesadata,
|
||||||
|
drawing::graph::PrimitiveIndex,
|
||||||
|
geometry::{primitive::PrimitiveShape, shape::MeasureLength},
|
||||||
|
graph::MakeRef,
|
||||||
|
router::{navmesh::Navmesh, trace::Trace},
|
||||||
|
step::Step,
|
||||||
|
};
|
||||||
|
|
||||||
|
use super::{
|
||||||
|
autoroute::{Autoroute, AutorouteStatus},
|
||||||
|
invoker::{GetGhosts, GetMaybeNavmesh, GetMaybeTrace, GetObstacles},
|
||||||
|
Autorouter, AutorouterError,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub enum CompareStatus {
|
||||||
|
Running,
|
||||||
|
Finished(f64),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryInto<f64> for CompareStatus {
|
||||||
|
type Error = ();
|
||||||
|
fn try_into(self) -> Result<f64, ()> {
|
||||||
|
match self {
|
||||||
|
CompareStatus::Running => Err(()),
|
||||||
|
CompareStatus::Finished(delta) => Ok(delta),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Compare {
|
||||||
|
autoroute: Autoroute,
|
||||||
|
next_autoroute: Option<Autoroute>,
|
||||||
|
ratline1: EdgeIndex<usize>,
|
||||||
|
ratline2: EdgeIndex<usize>,
|
||||||
|
total_length1: Option<f64>,
|
||||||
|
total_length2: Option<f64>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Compare {
|
||||||
|
pub fn new(
|
||||||
|
autorouter: &mut Autorouter<impl AccessMesadata>,
|
||||||
|
ratline1: EdgeIndex<usize>,
|
||||||
|
ratline2: EdgeIndex<usize>,
|
||||||
|
) -> Result<Self, AutorouterError> {
|
||||||
|
Ok(Self {
|
||||||
|
autoroute: autorouter.autoroute_ratlines(vec![ratline1, ratline2])?,
|
||||||
|
next_autoroute: Some(autorouter.autoroute_ratlines(vec![ratline2, ratline1])?),
|
||||||
|
ratline1,
|
||||||
|
ratline2,
|
||||||
|
total_length1: None,
|
||||||
|
total_length2: None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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> {
|
||||||
|
match self.autoroute.step(autorouter)? {
|
||||||
|
AutorouteStatus::Running => Ok(CompareStatus::Running),
|
||||||
|
AutorouteStatus::Routed(band_termseg) => {
|
||||||
|
let length = band_termseg
|
||||||
|
.ref_(autorouter.board.layout().drawing())
|
||||||
|
.length();
|
||||||
|
|
||||||
|
if self.total_length1.is_none() {
|
||||||
|
self.total_length1 = Some(length);
|
||||||
|
} else if self.total_length2.is_none() {
|
||||||
|
self.total_length2 = Some(length);
|
||||||
|
} else {
|
||||||
|
panic!();
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(CompareStatus::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)
|
||||||
|
} else {
|
||||||
|
autorouter.undo_autoroute_ratlines(vec![self.ratline2, self.ratline1]);
|
||||||
|
|
||||||
|
Ok(CompareStatus::Finished(
|
||||||
|
self.total_length1.unwrap() - self.total_length2.unwrap(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GetMaybeNavmesh for Compare {
|
||||||
|
fn maybe_navmesh(&self) -> Option<&Navmesh> {
|
||||||
|
self.autoroute.maybe_navmesh()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GetMaybeTrace for Compare {
|
||||||
|
fn maybe_trace(&self) -> Option<&Trace> {
|
||||||
|
self.autoroute.maybe_trace()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GetGhosts for Compare {
|
||||||
|
fn ghosts(&self) -> &[PrimitiveShape] {
|
||||||
|
self.autoroute.ghosts()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GetObstacles for Compare {
|
||||||
|
fn obstacles(&self) -> &[PrimitiveIndex] {
|
||||||
|
self.autoroute.obstacles()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -13,12 +13,13 @@ use crate::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
autoroute::Autoroute,
|
autoroute::{Autoroute, AutorouteStatus},
|
||||||
|
compare::{Compare, CompareStatus},
|
||||||
history::{History, HistoryError},
|
history::{History, HistoryError},
|
||||||
place_via::PlaceVia,
|
place_via::PlaceVia,
|
||||||
remove_bands::RemoveBands,
|
remove_bands::RemoveBands,
|
||||||
selection::{BandSelection, PinSelection},
|
selection::{BandSelection, PinSelection},
|
||||||
Autorouter, AutorouterError, AutorouterStatus,
|
Autorouter, AutorouterError,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[enum_dispatch]
|
#[enum_dispatch]
|
||||||
|
|
@ -70,6 +71,7 @@ pub enum Command {
|
||||||
Autoroute(PinSelection),
|
Autoroute(PinSelection),
|
||||||
PlaceVia(ViaWeight),
|
PlaceVia(ViaWeight),
|
||||||
RemoveBands(BandSelection),
|
RemoveBands(BandSelection),
|
||||||
|
Compare(PinSelection),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[enum_dispatch(GetMaybeNavmesh, GetMaybeTrace, GetGhosts, GetObstacles)]
|
#[enum_dispatch(GetMaybeNavmesh, GetMaybeTrace, GetGhosts, GetObstacles)]
|
||||||
|
|
@ -77,6 +79,7 @@ pub enum Execute {
|
||||||
Autoroute(Autoroute),
|
Autoroute(Autoroute),
|
||||||
PlaceVia(PlaceVia),
|
PlaceVia(PlaceVia),
|
||||||
RemoveBands(RemoveBands),
|
RemoveBands(RemoveBands),
|
||||||
|
Compare(Compare),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Execute {
|
impl Execute {
|
||||||
|
|
@ -86,9 +89,9 @@ impl Execute {
|
||||||
) -> Result<InvokerStatus, InvokerError> {
|
) -> Result<InvokerStatus, InvokerError> {
|
||||||
match self {
|
match self {
|
||||||
Execute::Autoroute(autoroute) => match autoroute.step(&mut invoker.autorouter)? {
|
Execute::Autoroute(autoroute) => match autoroute.step(&mut invoker.autorouter)? {
|
||||||
AutorouterStatus::Running => Ok(InvokerStatus::Running),
|
AutorouteStatus::Running => Ok(InvokerStatus::Running),
|
||||||
AutorouterStatus::Routed(..) => Ok(InvokerStatus::Running),
|
AutorouteStatus::Routed(..) => Ok(InvokerStatus::Running),
|
||||||
AutorouterStatus::Finished => Ok(InvokerStatus::Finished),
|
AutorouteStatus::Finished => Ok(InvokerStatus::Finished),
|
||||||
},
|
},
|
||||||
Execute::PlaceVia(place_via) => {
|
Execute::PlaceVia(place_via) => {
|
||||||
place_via.doit(&mut invoker.autorouter)?;
|
place_via.doit(&mut invoker.autorouter)?;
|
||||||
|
|
@ -98,6 +101,10 @@ 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)? {
|
||||||
|
CompareStatus::Running => Ok(InvokerStatus::Running),
|
||||||
|
CompareStatus::Finished(delta) => Ok(InvokerStatus::Finished),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -197,7 +204,7 @@ impl<M: AccessMesadata> Invoker<M> {
|
||||||
|
|
||||||
//#[debug_requires(self.ongoing_command.is_none())]
|
//#[debug_requires(self.ongoing_command.is_none())]
|
||||||
pub fn execute(&mut self, command: Command) -> Result<(), InvokerError> {
|
pub fn execute(&mut self, command: Command) -> Result<(), InvokerError> {
|
||||||
let mut execute = self.execute_walk(command)?;
|
let mut execute = self.execute_stepper(command)?;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let status = match execute.step(self) {
|
let status = match execute.step(self) {
|
||||||
|
|
@ -213,7 +220,7 @@ impl<M: AccessMesadata> Invoker<M> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[debug_requires(self.ongoing_command.is_none())]
|
#[debug_requires(self.ongoing_command.is_none())]
|
||||||
pub fn execute_walk(&mut self, command: Command) -> Result<Execute, InvokerError> {
|
pub fn execute_stepper(&mut self, command: Command) -> Result<Execute, InvokerError> {
|
||||||
let execute = self.dispatch_command(&command);
|
let execute = self.dispatch_command(&command);
|
||||||
self.ongoing_command = Some(command);
|
self.ongoing_command = Some(command);
|
||||||
execute
|
execute
|
||||||
|
|
@ -231,6 +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) => {
|
||||||
|
Ok::<Execute, InvokerError>(Execute::Compare(self.autorouter.compare(selection)?))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -242,6 +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(..) => (),
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok::<(), InvokerError>(self.history.undo()?)
|
Ok::<(), InvokerError>(self.history.undo()?)
|
||||||
|
|
@ -250,7 +261,7 @@ impl<M: AccessMesadata> Invoker<M> {
|
||||||
//#[debug_requires(self.ongoing.is_none())]
|
//#[debug_requires(self.ongoing.is_none())]
|
||||||
pub fn redo(&mut self) -> Result<(), InvokerError> {
|
pub fn redo(&mut self) -> Result<(), InvokerError> {
|
||||||
let command = self.history.last_undone()?.clone();
|
let command = self.history.last_undone()?.clone();
|
||||||
let mut execute = self.execute_walk(command)?;
|
let mut execute = self.execute_stepper(command)?;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let status = match execute.step(self) {
|
let status = match execute.step(self) {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
pub mod autoroute;
|
pub mod autoroute;
|
||||||
mod autorouter;
|
mod autorouter;
|
||||||
|
pub mod compare;
|
||||||
pub mod history;
|
pub mod history;
|
||||||
pub mod invoker;
|
pub mod invoker;
|
||||||
pub mod place_via;
|
pub mod place_via;
|
||||||
|
|
|
||||||
|
|
@ -213,10 +213,10 @@ impl Top {
|
||||||
) {
|
) {
|
||||||
let selection = overlay.selection().clone();
|
let selection = overlay.selection().clone();
|
||||||
overlay.clear_selection();
|
overlay.clear_selection();
|
||||||
maybe_execute.insert(ExecuteWithStatus::new(
|
maybe_execute
|
||||||
invoker
|
.insert(ExecuteWithStatus::new(invoker.execute_stepper(
|
||||||
.execute_walk(Command::Autoroute(selection.pin_selection))?,
|
Command::Autoroute(selection.pin_selection),
|
||||||
));
|
)?));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if place_via.consume_key_enabled(ctx, ui, &mut self.is_placing_via) {
|
} else if place_via.consume_key_enabled(ctx, ui, &mut self.is_placing_via) {
|
||||||
|
|
@ -230,10 +230,9 @@ impl Top {
|
||||||
) {
|
) {
|
||||||
let selection = overlay.selection().clone();
|
let selection = overlay.selection().clone();
|
||||||
overlay.clear_selection();
|
overlay.clear_selection();
|
||||||
maybe_execute
|
maybe_execute.insert(ExecuteWithStatus::new(invoker.execute_stepper(
|
||||||
.insert(ExecuteWithStatus::new(invoker.execute_walk(
|
Command::RemoveBands(selection.band_selection),
|
||||||
Command::RemoveBands(selection.band_selection),
|
)?));
|
||||||
)?));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if undo.consume_key_triggered(ctx, ui) {
|
} else if undo.consume_key_triggered(ctx, ui) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue