From 1c7042c8c36ef77335f65021728d93b0a7bb06c2 Mon Sep 17 00:00:00 2001 From: Mikolaj Wielgus Date: Sun, 29 Sep 2024 01:35:25 +0200 Subject: [PATCH] autorouter: move `Execute` and `ExecuteWithStatus` to own file --- examples/specctra.rs | 11 +- src/autorouter/execute.rs | 144 ++++++++++++++++++++++++++ src/autorouter/history.rs | 2 +- src/autorouter/invoker.rs | 177 ++++---------------------------- src/autorouter/mod.rs | 1 + src/bin/topola-egui/app.rs | 3 +- src/bin/topola-egui/bottom.rs | 2 +- src/bin/topola-egui/top.rs | 3 +- src/bin/topola-egui/viewport.rs | 6 +- tests/multilayer.rs | 5 +- tests/single_layer.rs | 3 +- 11 files changed, 179 insertions(+), 178 deletions(-) create mode 100644 src/autorouter/execute.rs diff --git a/examples/specctra.rs b/examples/specctra.rs index 882526b..f316067 100644 --- a/examples/specctra.rs +++ b/examples/specctra.rs @@ -1,21 +1,18 @@ use std::fs::File; use std::io::BufReader; -use topola::autorouter::history::History; -use topola::autorouter::invoker::Command; use topola::autorouter::invoker::Invoker; -use topola::autorouter::selection::PinSelection; use topola::autorouter::Autorouter; use topola::specctra::design::SpecctraDesign; fn main() -> Result<(), std::io::Error> { let design_file = File::open("example.dsn")?; - let mut design_bufread = BufReader::new(design_file); + let design_bufread = BufReader::new(design_file); let design = SpecctraDesign::load(design_bufread).unwrap(); let board = design.make_board(); - - let mut invoker = Invoker::new(Autorouter::new(board).unwrap()); - + + let invoker = Invoker::new(Autorouter::new(board).unwrap()); + let mut file = File::create("example.ses").unwrap(); design.write_ses(invoker.autorouter().board(), &mut file); diff --git a/src/autorouter/execute.rs b/src/autorouter/execute.rs new file mode 100644 index 0000000..7554919 --- /dev/null +++ b/src/autorouter/execute.rs @@ -0,0 +1,144 @@ +use enum_dispatch::enum_dispatch; +use serde::{Deserialize, Serialize}; + +use crate::{board::mesadata::AccessMesadata, drawing::graph::PrimitiveIndex, geometry::primitive::PrimitiveShape, layout::via::ViaWeight, router::{navmesh::Navmesh, trace::Trace}, step::Step}; + +use super::{autoroute::{Autoroute, AutorouteStatus}, compare_detours::{CompareDetours, CompareDetoursStatus}, invoker::{GetGhosts, GetMaybeNavmesh, GetMaybeTrace, GetObstacles, Invoker, InvokerError, InvokerStatus}, measure_length::MeasureLength, place_via::PlaceVia, remove_bands::RemoveBands, selection::{BandSelection, PinSelection}, AutorouterOptions}; + + +type Type = PinSelection; + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum Command { + Autoroute(PinSelection, AutorouterOptions), + PlaceVia(ViaWeight), + RemoveBands(BandSelection), + CompareDetours(Type, AutorouterOptions), + MeasureLength(BandSelection), +} + +#[enum_dispatch(GetMaybeNavmesh, GetMaybeTrace, GetGhosts, GetObstacles)] +pub enum Execute { + Autoroute(Autoroute), + PlaceVia(PlaceVia), + RemoveBands(RemoveBands), + CompareDetours(CompareDetours), + MeasureLength(MeasureLength), +} + +impl Execute { + fn step_catch_err( + &mut self, + invoker: &mut Invoker, + ) -> Result { + match self { + Execute::Autoroute(autoroute) => match autoroute.step(&mut invoker.autorouter)? { + AutorouteStatus::Running => Ok(InvokerStatus::Running), + AutorouteStatus::Routed(..) => Ok(InvokerStatus::Running), + AutorouteStatus::Finished => Ok(InvokerStatus::Finished(String::from( + "finished autorouting", + ))), + }, + Execute::PlaceVia(place_via) => { + place_via.doit(&mut invoker.autorouter)?; + Ok(InvokerStatus::Finished(String::from( + "finished placing via", + ))) + } + Execute::RemoveBands(remove_bands) => { + remove_bands.doit(&mut invoker.autorouter)?; + Ok(InvokerStatus::Finished(String::from( + "finished removing bands", + ))) + } + Execute::CompareDetours(compare_detours) => { + match compare_detours.step(&mut invoker.autorouter)? { + CompareDetoursStatus::Running => Ok(InvokerStatus::Running), + CompareDetoursStatus::Finished(total_length1, total_length2) => { + Ok(InvokerStatus::Finished(String::from(format!( + "total detour lengths are {} and {}", + total_length1, total_length2 + )))) + } + } + } + Execute::MeasureLength(measure_length) => { + let length = measure_length.doit(&mut invoker.autorouter)?; + Ok(InvokerStatus::Finished(format!( + "Total length of selected bands: {}", + length + ))) + } + } + } +} + +impl Step, InvokerStatus, InvokerError, ()> for Execute { + fn step(&mut self, invoker: &mut Invoker) -> Result { + match self.step_catch_err(invoker) { + Ok(InvokerStatus::Running) => Ok(InvokerStatus::Running), + Ok(InvokerStatus::Finished(msg)) => { + if let Some(command) = invoker.ongoing_command.take() { + invoker.history.do_(command); + } + + Ok(InvokerStatus::Finished(msg)) + } + Err(err) => { + invoker.ongoing_command = None; + Err(err) + } + } + } +} + +pub struct ExecuteWithStatus { + execute: Execute, + maybe_status: Option, +} + +impl ExecuteWithStatus { + pub fn new(execute: Execute) -> ExecuteWithStatus { + Self { + execute, + maybe_status: None, + } + } + + pub fn step( + &mut self, + invoker: &mut Invoker, + ) -> Result { + let status = self.execute.step(invoker)?; + self.maybe_status = Some(status.clone()); + Ok(status) + } + + pub fn maybe_status(&self) -> Option { + self.maybe_status.clone() + } +} + +impl GetMaybeNavmesh for ExecuteWithStatus { + fn maybe_navmesh(&self) -> Option<&Navmesh> { + self.execute.maybe_navmesh() + } +} + +impl GetMaybeTrace for ExecuteWithStatus { + fn maybe_trace(&self) -> Option<&Trace> { + self.execute.maybe_trace() + } +} + +impl GetGhosts for ExecuteWithStatus { + fn ghosts(&self) -> &[PrimitiveShape] { + self.execute.ghosts() + } +} + +impl GetObstacles for ExecuteWithStatus { + fn obstacles(&self) -> &[PrimitiveIndex] { + self.execute.obstacles() + } +} diff --git a/src/autorouter/history.rs b/src/autorouter/history.rs index d9f9db5..90a3426 100644 --- a/src/autorouter/history.rs +++ b/src/autorouter/history.rs @@ -1,7 +1,7 @@ use serde::{Deserialize, Serialize}; use thiserror::Error; -use crate::autorouter::invoker::Command; +use crate::autorouter::execute::Command; #[derive(Error, Debug, Clone)] pub enum HistoryError { diff --git a/src/autorouter/invoker.rs b/src/autorouter/invoker.rs index 0a5f6d6..0245d5d 100644 --- a/src/autorouter/invoker.rs +++ b/src/autorouter/invoker.rs @@ -2,27 +2,25 @@ use std::cmp::Ordering; use contracts::debug_requires; use enum_dispatch::enum_dispatch; -use serde::{Deserialize, Serialize}; use thiserror::Error; use crate::{ board::mesadata::AccessMesadata, drawing::graph::PrimitiveIndex, geometry::primitive::PrimitiveShape, - layout::via::ViaWeight, router::{navmesh::Navmesh, trace::Trace}, step::Step, }; use super::{ - autoroute::{Autoroute, AutorouteStatus}, - compare_detours::{CompareDetours, CompareDetoursStatus}, + autoroute::Autoroute, + compare_detours::CompareDetours, + execute::{Command, Execute}, history::{History, HistoryError}, measure_length::MeasureLength, place_via::PlaceVia, remove_bands::RemoveBands, - selection::{BandSelection, PinSelection}, - Autorouter, AutorouterError, AutorouterOptions, + Autorouter, AutorouterError, }; #[enum_dispatch] @@ -69,145 +67,10 @@ impl TryInto<()> for InvokerStatus { } } -#[derive(Debug, Clone, Serialize, Deserialize)] -pub enum Command { - Autoroute(PinSelection, AutorouterOptions), - PlaceVia(ViaWeight), - RemoveBands(BandSelection), - CompareDetours(PinSelection, AutorouterOptions), - MeasureLength(BandSelection), -} - -#[enum_dispatch(GetMaybeNavmesh, GetMaybeTrace, GetGhosts, GetObstacles)] -pub enum Execute { - Autoroute(Autoroute), - PlaceVia(PlaceVia), - RemoveBands(RemoveBands), - CompareDetours(CompareDetours), - MeasureLength(MeasureLength), -} - -impl Execute { - fn step_catch_err( - &mut self, - invoker: &mut Invoker, - ) -> Result { - match self { - Execute::Autoroute(autoroute) => match autoroute.step(&mut invoker.autorouter)? { - AutorouteStatus::Running => Ok(InvokerStatus::Running), - AutorouteStatus::Routed(..) => Ok(InvokerStatus::Running), - AutorouteStatus::Finished => Ok(InvokerStatus::Finished(String::from( - "finished autorouting", - ))), - }, - Execute::PlaceVia(place_via) => { - place_via.doit(&mut invoker.autorouter)?; - Ok(InvokerStatus::Finished(String::from( - "finished placing via", - ))) - } - Execute::RemoveBands(remove_bands) => { - remove_bands.doit(&mut invoker.autorouter)?; - Ok(InvokerStatus::Finished(String::from( - "finished removing bands", - ))) - } - Execute::CompareDetours(compare_detours) => { - match compare_detours.step(&mut invoker.autorouter)? { - CompareDetoursStatus::Running => Ok(InvokerStatus::Running), - CompareDetoursStatus::Finished(total_length1, total_length2) => { - Ok(InvokerStatus::Finished(String::from(format!( - "total detour lengths are {} and {}", - total_length1, total_length2 - )))) - } - } - } - Execute::MeasureLength(measure_length) => { - let length = measure_length.doit(&mut invoker.autorouter)?; - Ok(InvokerStatus::Finished(format!( - "Total length of selected bands: {}", - length - ))) - } - } - } -} - -impl Step, InvokerStatus, InvokerError, ()> for Execute { - fn step(&mut self, invoker: &mut Invoker) -> Result { - match self.step_catch_err(invoker) { - Ok(InvokerStatus::Running) => Ok(InvokerStatus::Running), - Ok(InvokerStatus::Finished(msg)) => { - if let Some(command) = invoker.ongoing_command.take() { - invoker.history.do_(command); - } - - Ok(InvokerStatus::Finished(msg)) - } - Err(err) => { - invoker.ongoing_command = None; - Err(err) - } - } - } -} - -pub struct ExecuteWithStatus { - execute: Execute, - maybe_status: Option, -} - -impl ExecuteWithStatus { - pub fn new(execute: Execute) -> ExecuteWithStatus { - Self { - execute, - maybe_status: None, - } - } - - pub fn step( - &mut self, - invoker: &mut Invoker, - ) -> Result { - let status = self.execute.step(invoker)?; - self.maybe_status = Some(status.clone()); - Ok(status) - } - - pub fn maybe_status(&self) -> Option { - self.maybe_status.clone() - } -} - -impl GetMaybeNavmesh for ExecuteWithStatus { - fn maybe_navmesh(&self) -> Option<&Navmesh> { - self.execute.maybe_navmesh() - } -} - -impl GetMaybeTrace for ExecuteWithStatus { - fn maybe_trace(&self) -> Option<&Trace> { - self.execute.maybe_trace() - } -} - -impl GetGhosts for ExecuteWithStatus { - fn ghosts(&self) -> &[PrimitiveShape] { - self.execute.ghosts() - } -} - -impl GetObstacles for ExecuteWithStatus { - fn obstacles(&self) -> &[PrimitiveIndex] { - self.execute.obstacles() - } -} - pub struct Invoker { - autorouter: Autorouter, - history: History, - ongoing_command: Option, + pub(super) autorouter: Autorouter, + pub(super) history: History, + pub(super) ongoing_command: Option, } impl Invoker { @@ -271,22 +134,18 @@ impl Invoker { }); } - Execute::Autoroute( - self.autorouter.autoroute_ratlines(ratlines, *options)?, - ) + Execute::Autoroute(self.autorouter.autoroute_ratlines(ratlines, *options)?) + } + Command::PlaceVia(weight) => Execute::PlaceVia(self.autorouter.place_via(*weight)?), + Command::RemoveBands(selection) => { + Execute::RemoveBands(self.autorouter.remove_bands(selection)?) + } + Command::CompareDetours(selection, options) => { + Execute::CompareDetours(self.autorouter.compare_detours(selection, *options)?) + } + Command::MeasureLength(selection) => { + Execute::MeasureLength(self.autorouter.measure_length(selection)?) } - Command::PlaceVia(weight) => Execute::PlaceVia( - self.autorouter.place_via(*weight)? - ), - Command::RemoveBands(selection) => Execute::RemoveBands( - self.autorouter.remove_bands(selection)?, - ), - Command::CompareDetours(selection, options) => Execute::CompareDetours( - self.autorouter.compare_detours(selection, *options)?, - ), - Command::MeasureLength(selection) => Execute::MeasureLength( - self.autorouter.measure_length(selection)?, - ), }) } diff --git a/src/autorouter/mod.rs b/src/autorouter/mod.rs index b7f8d98..7ce1a4e 100644 --- a/src/autorouter/mod.rs +++ b/src/autorouter/mod.rs @@ -1,6 +1,7 @@ pub mod autoroute; mod autorouter; pub mod compare_detours; +pub mod execute; pub mod history; pub mod invoker; pub mod measure_length; diff --git a/src/bin/topola-egui/app.rs b/src/bin/topola-egui/app.rs index b6f1095..a0b0eb1 100644 --- a/src/bin/topola-egui/app.rs +++ b/src/bin/topola-egui/app.rs @@ -14,7 +14,8 @@ use unic_langid::{langid, LanguageIdentifier}; use topola::{ autorouter::{ - invoker::{Command, Execute, ExecuteWithStatus, Invoker, InvokerStatus}, + execute::ExecuteWithStatus, + invoker::{Invoker, InvokerStatus}, Autorouter, }, drawing::{ diff --git a/src/bin/topola-egui/bottom.rs b/src/bin/topola-egui/bottom.rs index a93fe31..aebcdce 100644 --- a/src/bin/topola-egui/bottom.rs +++ b/src/bin/topola-egui/bottom.rs @@ -1,4 +1,4 @@ -use topola::autorouter::invoker::{Execute, ExecuteWithStatus, InvokerStatus}; +use topola::autorouter::{execute::ExecuteWithStatus, invoker::InvokerStatus}; use crate::{translator::Translator, viewport::Viewport}; diff --git a/src/bin/topola-egui/top.rs b/src/bin/topola-egui/top.rs index 634f501..896dc03 100644 --- a/src/bin/topola-egui/top.rs +++ b/src/bin/topola-egui/top.rs @@ -6,7 +6,8 @@ use std::{ use topola::{ autorouter::{ - invoker::{Command, Execute, ExecuteWithStatus, Invoker, InvokerError, InvokerStatus}, + execute::{Command, ExecuteWithStatus}, + invoker::{Invoker, InvokerError, InvokerStatus}, AutorouterOptions, }, router::RouterOptions, diff --git a/src/bin/topola-egui/viewport.rs b/src/bin/topola-egui/viewport.rs index 36c8a73..26f9bff 100644 --- a/src/bin/topola-egui/viewport.rs +++ b/src/bin/topola-egui/viewport.rs @@ -5,9 +5,9 @@ use petgraph::{ }; use rstar::{Envelope, AABB}; use topola::{ - autorouter::invoker::{ - Command, ExecuteWithStatus, GetGhosts, GetMaybeNavmesh, GetMaybeTrace, GetObstacles, - Invoker, + autorouter::{ + execute::{Command, ExecuteWithStatus}, + invoker::{GetGhosts, GetMaybeNavmesh, GetMaybeTrace, GetObstacles, Invoker}, }, board::mesadata::AccessMesadata, drawing::{ diff --git a/tests/multilayer.rs b/tests/multilayer.rs index e14dcf5..cbbb09f 100644 --- a/tests/multilayer.rs +++ b/tests/multilayer.rs @@ -1,8 +1,5 @@ use topola::{ - autorouter::{ - invoker::{Command, InvokerError}, - AutorouterError, - }, + autorouter::{execute::Command, invoker::InvokerError, AutorouterError}, board::mesadata::AccessMesadata, layout::via::ViaWeight, math::Circle, diff --git a/tests/single_layer.rs b/tests/single_layer.rs index e7350eb..f6c837a 100644 --- a/tests/single_layer.rs +++ b/tests/single_layer.rs @@ -1,6 +1,7 @@ use topola::{ autorouter::{ - invoker::{Command, Invoker, InvokerError}, + execute::Command, + invoker::{Invoker, InvokerError}, AutorouterError, }, layout::via::ViaWeight,