mirror of https://codeberg.org/topola/topola.git
autorouter: create new command: Remove Selected Bands
This commit is contained in:
parent
b568f2d790
commit
fcffb76de4
|
|
@ -14,6 +14,7 @@ use super::{
|
||||||
autoroute::Autoroute,
|
autoroute::Autoroute,
|
||||||
place_via::PlaceVia,
|
place_via::PlaceVia,
|
||||||
ratsnest::{Ratsnest, RatvertexIndex},
|
ratsnest::{Ratsnest, RatvertexIndex},
|
||||||
|
remove_bands::RemoveBands,
|
||||||
selection::{BandSelection, PinSelection},
|
selection::{BandSelection, PinSelection},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -89,7 +90,27 @@ impl<M: AccessMesadata> Autorouter<M> {
|
||||||
PlaceVia::new(weight)
|
PlaceVia::new(weight)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn undo_place_via(&mut self, weight: ViaWeight) {
|
pub fn undo_place_via(&mut self, _weight: ViaWeight) {
|
||||||
|
todo!();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn remove_bands(&mut self, selection: &BandSelection) -> Result<(), AutorouterError> {
|
||||||
|
for selector in selection.selectors() {
|
||||||
|
let band = self.board.bandname_band(selector.band.clone()).unwrap().0;
|
||||||
|
self.board.layout_mut().remove_band(band);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn remove_bands_walk(
|
||||||
|
&self,
|
||||||
|
selection: &BandSelection,
|
||||||
|
) -> Result<RemoveBands, AutorouterError> {
|
||||||
|
RemoveBands::new(selection)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn undo_remove_bands(&mut self, _selection: &BandSelection) {
|
||||||
todo!();
|
todo!();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ use super::{
|
||||||
autoroute::Autoroute,
|
autoroute::Autoroute,
|
||||||
history::{History, HistoryError},
|
history::{History, HistoryError},
|
||||||
place_via::PlaceVia,
|
place_via::PlaceVia,
|
||||||
|
remove_bands::RemoveBands,
|
||||||
selection::{BandSelection, PinSelection},
|
selection::{BandSelection, PinSelection},
|
||||||
Autorouter, AutorouterError, AutorouterStatus,
|
Autorouter, AutorouterError, AutorouterStatus,
|
||||||
};
|
};
|
||||||
|
|
@ -57,12 +58,14 @@ pub enum InvokerStatus {
|
||||||
pub enum Command {
|
pub enum Command {
|
||||||
Autoroute(PinSelection),
|
Autoroute(PinSelection),
|
||||||
PlaceVia(ViaWeight),
|
PlaceVia(ViaWeight),
|
||||||
|
RemoveBands(BandSelection),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[enum_dispatch(GetMaybeNavmesh, GetMaybeTrace, GetGhosts, GetObstacles)]
|
#[enum_dispatch(GetMaybeNavmesh, GetMaybeTrace, GetGhosts, GetObstacles)]
|
||||||
pub enum Execute {
|
pub enum Execute {
|
||||||
Autoroute(Autoroute),
|
Autoroute(Autoroute),
|
||||||
PlaceVia(PlaceVia),
|
PlaceVia(PlaceVia),
|
||||||
|
RemoveBands(RemoveBands),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Execute {
|
impl Execute {
|
||||||
|
|
@ -99,6 +102,10 @@ impl Execute {
|
||||||
place_via.doit(&mut invoker.autorouter)?;
|
place_via.doit(&mut invoker.autorouter)?;
|
||||||
Ok(InvokerStatus::Finished)
|
Ok(InvokerStatus::Finished)
|
||||||
}
|
}
|
||||||
|
Execute::RemoveBands(remove_bands) => {
|
||||||
|
remove_bands.doit(&mut invoker.autorouter)?;
|
||||||
|
Ok(InvokerStatus::Finished)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -210,6 +217,9 @@ impl<M: AccessMesadata> Invoker<M> {
|
||||||
Command::PlaceVia(weight) => Ok::<Execute, InvokerError>(Execute::PlaceVia(
|
Command::PlaceVia(weight) => Ok::<Execute, InvokerError>(Execute::PlaceVia(
|
||||||
self.autorouter.place_via_walk(*weight)?,
|
self.autorouter.place_via_walk(*weight)?,
|
||||||
)),
|
)),
|
||||||
|
Command::RemoveBands(selection) => Ok::<Execute, InvokerError>(Execute::RemoveBands(
|
||||||
|
self.autorouter.remove_bands_walk(selection)?,
|
||||||
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -220,6 +230,7 @@ impl<M: AccessMesadata> Invoker<M> {
|
||||||
match command {
|
match command {
|
||||||
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),
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok::<(), InvokerError>(self.history.undo()?)
|
Ok::<(), InvokerError>(self.history.undo()?)
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ pub mod history;
|
||||||
pub mod invoker;
|
pub mod invoker;
|
||||||
pub mod place_via;
|
pub mod place_via;
|
||||||
pub mod ratsnest;
|
pub mod ratsnest;
|
||||||
|
pub mod remove_bands;
|
||||||
pub mod selection;
|
pub mod selection;
|
||||||
|
|
||||||
pub use autorouter::*;
|
pub use autorouter::*;
|
||||||
|
|
|
||||||
|
|
@ -14,18 +14,27 @@ use super::{
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct PlaceVia {
|
pub struct PlaceVia {
|
||||||
weight: ViaWeight,
|
weight: ViaWeight,
|
||||||
|
done: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PlaceVia {
|
impl PlaceVia {
|
||||||
pub fn new(weight: ViaWeight) -> Result<Self, AutorouterError> {
|
pub fn new(weight: ViaWeight) -> Result<Self, AutorouterError> {
|
||||||
Ok(Self { weight })
|
Ok(Self {
|
||||||
|
weight,
|
||||||
|
done: false,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn doit(
|
pub fn doit(
|
||||||
&mut self,
|
&mut self,
|
||||||
autorouter: &mut Autorouter<impl AccessMesadata>,
|
autorouter: &mut Autorouter<impl AccessMesadata>,
|
||||||
) -> Result<(), AutorouterError> {
|
) -> Result<(), AutorouterError> {
|
||||||
autorouter.place_via(self.weight)
|
if !self.done {
|
||||||
|
self.done = true;
|
||||||
|
autorouter.place_via(self.weight)
|
||||||
|
} else {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,63 @@
|
||||||
|
use crate::{
|
||||||
|
board::mesadata::AccessMesadata,
|
||||||
|
drawing::graph::PrimitiveIndex,
|
||||||
|
geometry::primitive::PrimitiveShape,
|
||||||
|
router::{navmesh::Navmesh, trace::Trace},
|
||||||
|
};
|
||||||
|
|
||||||
|
use super::{
|
||||||
|
invoker::{GetGhosts, GetMaybeNavmesh, GetMaybeTrace, GetObstacles},
|
||||||
|
selection::BandSelection,
|
||||||
|
Autorouter, AutorouterError,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct RemoveBands {
|
||||||
|
selection: BandSelection,
|
||||||
|
done: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RemoveBands {
|
||||||
|
pub fn new(selection: &BandSelection) -> Result<Self, AutorouterError> {
|
||||||
|
Ok(Self {
|
||||||
|
selection: selection.clone(),
|
||||||
|
done: false,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn doit(
|
||||||
|
&mut self,
|
||||||
|
autorouter: &mut Autorouter<impl AccessMesadata>,
|
||||||
|
) -> Result<(), AutorouterError> {
|
||||||
|
if !self.done {
|
||||||
|
self.done = true;
|
||||||
|
autorouter.remove_bands(&self.selection)
|
||||||
|
} else {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GetMaybeNavmesh for RemoveBands {
|
||||||
|
fn maybe_navmesh(&self) -> Option<&Navmesh> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GetMaybeTrace for RemoveBands {
|
||||||
|
fn maybe_trace(&self) -> Option<&Trace> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GetGhosts for RemoveBands {
|
||||||
|
fn ghosts(&self) -> &[PrimitiveShape] {
|
||||||
|
&[]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GetObstacles for RemoveBands {
|
||||||
|
fn obstacles(&self) -> &[PrimitiveIndex] {
|
||||||
|
&[]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -15,8 +15,8 @@ use crate::{
|
||||||
|
|
||||||
#[derive(Debug, Clone, Hash, Eq, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Hash, Eq, PartialEq, Serialize, Deserialize)]
|
||||||
pub struct PinSelector {
|
pub struct PinSelector {
|
||||||
pin: String,
|
pub pin: String,
|
||||||
layer: String,
|
pub layer: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
|
@ -78,11 +78,15 @@ impl PinSelection {
|
||||||
self.node_selector(board, node)
|
self.node_selector(board, node)
|
||||||
.map_or(false, |selector| self.selectors.contains(&selector))
|
.map_or(false, |selector| self.selectors.contains(&selector))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn selectors(&self) -> impl Iterator<Item = &PinSelector> {
|
||||||
|
self.selectors.iter()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Hash, Eq, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Hash, Eq, PartialEq, Serialize, Deserialize)]
|
||||||
pub struct BandSelector {
|
pub struct BandSelector {
|
||||||
band: BandName,
|
pub band: BandName,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
|
@ -133,6 +137,10 @@ impl BandSelection {
|
||||||
self.node_selector(board, node)
|
self.node_selector(board, node)
|
||||||
.map_or(false, |selector| self.selectors.contains(&selector))
|
.map_or(false, |selector| self.selectors.contains(&selector))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn selectors(&self) -> impl Iterator<Item = &BandSelector> {
|
||||||
|
self.selectors.iter()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
|
|
||||||
|
|
@ -75,6 +75,11 @@ impl Top {
|
||||||
egui::Modifiers::CTRL,
|
egui::Modifiers::CTRL,
|
||||||
egui::Key::P,
|
egui::Key::P,
|
||||||
));
|
));
|
||||||
|
let mut remove_bands = Trigger::new(Action::new(
|
||||||
|
"Remove Selected Bands",
|
||||||
|
egui::Modifiers::NONE,
|
||||||
|
egui::Key::Delete,
|
||||||
|
));
|
||||||
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));
|
||||||
|
|
||||||
|
|
@ -104,6 +109,8 @@ impl Top {
|
||||||
|
|
||||||
place_via.toggle_widget(ctx, ui, &mut self.is_placing_via);
|
place_via.toggle_widget(ctx, ui, &mut self.is_placing_via);
|
||||||
|
|
||||||
|
remove_bands.button(ctx, ui);
|
||||||
|
|
||||||
ui.separator();
|
ui.separator();
|
||||||
|
|
||||||
undo.button(ctx, ui);
|
undo.button(ctx, ui);
|
||||||
|
|
@ -213,6 +220,22 @@ impl Top {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} 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) {
|
||||||
|
} else if remove_bands.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_walk(
|
||||||
|
Command::RemoveBands(selection.band_selection),
|
||||||
|
)?));
|
||||||
|
}
|
||||||
|
}
|
||||||
} else if undo.consume_key_triggered(ctx, ui) {
|
} else if undo.consume_key_triggered(ctx, ui) {
|
||||||
if let Some(invoker) = arc_mutex_maybe_invoker.lock().unwrap().as_mut() {
|
if let Some(invoker) = arc_mutex_maybe_invoker.lock().unwrap().as_mut() {
|
||||||
invoker.undo();
|
invoker.undo();
|
||||||
|
|
|
||||||
|
|
@ -156,6 +156,10 @@ impl<M: AccessMesadata> Board<M> {
|
||||||
self.band_bandname.get_by_left(&band)
|
self.band_bandname.get_by_left(&band)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn bandname_band(&self, bandname: BandName) -> Option<&BandUid> {
|
||||||
|
self.band_bandname.get_by_right(&bandname)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn try_set_band_between_nodes(
|
pub fn try_set_band_between_nodes(
|
||||||
&mut self,
|
&mut self,
|
||||||
source: FixedDotIndex,
|
source: FixedDotIndex,
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ use super::{
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Hash, Clone, Copy)]
|
#[derive(Debug, Hash, Clone, Copy)]
|
||||||
pub struct BandUid(BandTermsegIndex, BandTermsegIndex);
|
pub struct BandUid(pub BandTermsegIndex, pub BandTermsegIndex);
|
||||||
|
|
||||||
impl BandUid {
|
impl BandUid {
|
||||||
pub fn new(first_seg1: BandTermsegIndex, first_seg2: BandTermsegIndex) -> Self {
|
pub fn new(first_seg1: BandTermsegIndex, first_seg2: BandTermsegIndex) -> Self {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue