autorouter: create new command: Remove Selected Bands

This commit is contained in:
Mikolaj Wielgus 2024-07-25 01:46:54 +02:00
parent b568f2d790
commit fcffb76de4
9 changed files with 147 additions and 7 deletions

View File

@ -14,6 +14,7 @@ use super::{
autoroute::Autoroute,
place_via::PlaceVia,
ratsnest::{Ratsnest, RatvertexIndex},
remove_bands::RemoveBands,
selection::{BandSelection, PinSelection},
};
@ -89,7 +90,27 @@ impl<M: AccessMesadata> Autorouter<M> {
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!();
}

View File

@ -15,6 +15,7 @@ use super::{
autoroute::Autoroute,
history::{History, HistoryError},
place_via::PlaceVia,
remove_bands::RemoveBands,
selection::{BandSelection, PinSelection},
Autorouter, AutorouterError, AutorouterStatus,
};
@ -57,12 +58,14 @@ pub enum InvokerStatus {
pub enum Command {
Autoroute(PinSelection),
PlaceVia(ViaWeight),
RemoveBands(BandSelection),
}
#[enum_dispatch(GetMaybeNavmesh, GetMaybeTrace, GetGhosts, GetObstacles)]
pub enum Execute {
Autoroute(Autoroute),
PlaceVia(PlaceVia),
RemoveBands(RemoveBands),
}
impl Execute {
@ -99,6 +102,10 @@ impl Execute {
place_via.doit(&mut invoker.autorouter)?;
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(
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 {
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),
}
Ok::<(), InvokerError>(self.history.undo()?)

View File

@ -4,6 +4,7 @@ pub mod history;
pub mod invoker;
pub mod place_via;
pub mod ratsnest;
pub mod remove_bands;
pub mod selection;
pub use autorouter::*;

View File

@ -14,18 +14,27 @@ use super::{
#[derive(Debug)]
pub struct PlaceVia {
weight: ViaWeight,
done: bool,
}
impl PlaceVia {
pub fn new(weight: ViaWeight) -> Result<Self, AutorouterError> {
Ok(Self { weight })
Ok(Self {
weight,
done: false,
})
}
pub fn doit(
&mut self,
autorouter: &mut Autorouter<impl AccessMesadata>,
) -> Result<(), AutorouterError> {
if !self.done {
self.done = true;
autorouter.place_via(self.weight)
} else {
Ok(())
}
}
}

View File

@ -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] {
&[]
}
}

View File

@ -15,8 +15,8 @@ use crate::{
#[derive(Debug, Clone, Hash, Eq, PartialEq, Serialize, Deserialize)]
pub struct PinSelector {
pin: String,
layer: String,
pub pin: String,
pub layer: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
@ -78,11 +78,15 @@ impl PinSelection {
self.node_selector(board, node)
.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)]
pub struct BandSelector {
band: BandName,
pub band: BandName,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
@ -133,6 +137,10 @@ impl BandSelection {
self.node_selector(board, node)
.map_or(false, |selector| self.selectors.contains(&selector))
}
pub fn selectors(&self) -> impl Iterator<Item = &BandSelector> {
self.selectors.iter()
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]

View File

@ -75,6 +75,11 @@ impl Top {
egui::Modifiers::CTRL,
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 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);
remove_bands.button(ctx, ui);
ui.separator();
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 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) {
if let Some(invoker) = arc_mutex_maybe_invoker.lock().unwrap().as_mut() {
invoker.undo();

View File

@ -156,6 +156,10 @@ impl<M: AccessMesadata> Board<M> {
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(
&mut self,
source: FixedDotIndex,

View File

@ -16,7 +16,7 @@ use super::{
};
#[derive(Debug, Hash, Clone, Copy)]
pub struct BandUid(BandTermsegIndex, BandTermsegIndex);
pub struct BandUid(pub BandTermsegIndex, pub BandTermsegIndex);
impl BandUid {
pub fn new(first_seg1: BandTermsegIndex, first_seg2: BandTermsegIndex) -> Self {