autorouter: move `Execute` and `ExecuteWithStatus` to own file

This commit is contained in:
Mikolaj Wielgus 2024-09-29 01:35:25 +02:00
parent eb0f45e3fb
commit 1c7042c8c3
11 changed files with 179 additions and 178 deletions

View File

@ -1,21 +1,18 @@
use std::fs::File; use std::fs::File;
use std::io::BufReader; use std::io::BufReader;
use topola::autorouter::history::History;
use topola::autorouter::invoker::Command;
use topola::autorouter::invoker::Invoker; use topola::autorouter::invoker::Invoker;
use topola::autorouter::selection::PinSelection;
use topola::autorouter::Autorouter; use topola::autorouter::Autorouter;
use topola::specctra::design::SpecctraDesign; use topola::specctra::design::SpecctraDesign;
fn main() -> Result<(), std::io::Error> { fn main() -> Result<(), std::io::Error> {
let design_file = File::open("example.dsn")?; 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 design = SpecctraDesign::load(design_bufread).unwrap();
let board = design.make_board(); 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(); let mut file = File::create("example.ses").unwrap();
design.write_ses(invoker.autorouter().board(), &mut file); design.write_ses(invoker.autorouter().board(), &mut file);

144
src/autorouter/execute.rs Normal file
View File

@ -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<M: AccessMesadata>(
&mut self,
invoker: &mut Invoker<M>,
) -> Result<InvokerStatus, InvokerError> {
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<M: AccessMesadata> Step<Invoker<M>, InvokerStatus, InvokerError, ()> for Execute {
fn step(&mut self, invoker: &mut Invoker<M>) -> Result<InvokerStatus, InvokerError> {
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<InvokerStatus>,
}
impl ExecuteWithStatus {
pub fn new(execute: Execute) -> ExecuteWithStatus {
Self {
execute,
maybe_status: None,
}
}
pub fn step<M: AccessMesadata>(
&mut self,
invoker: &mut Invoker<M>,
) -> Result<InvokerStatus, InvokerError> {
let status = self.execute.step(invoker)?;
self.maybe_status = Some(status.clone());
Ok(status)
}
pub fn maybe_status(&self) -> Option<InvokerStatus> {
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()
}
}

View File

@ -1,7 +1,7 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use thiserror::Error; use thiserror::Error;
use crate::autorouter::invoker::Command; use crate::autorouter::execute::Command;
#[derive(Error, Debug, Clone)] #[derive(Error, Debug, Clone)]
pub enum HistoryError { pub enum HistoryError {

View File

@ -2,27 +2,25 @@ use std::cmp::Ordering;
use contracts::debug_requires; use contracts::debug_requires;
use enum_dispatch::enum_dispatch; use enum_dispatch::enum_dispatch;
use serde::{Deserialize, Serialize};
use thiserror::Error; use thiserror::Error;
use crate::{ use crate::{
board::mesadata::AccessMesadata, board::mesadata::AccessMesadata,
drawing::graph::PrimitiveIndex, drawing::graph::PrimitiveIndex,
geometry::primitive::PrimitiveShape, geometry::primitive::PrimitiveShape,
layout::via::ViaWeight,
router::{navmesh::Navmesh, trace::Trace}, router::{navmesh::Navmesh, trace::Trace},
step::Step, step::Step,
}; };
use super::{ use super::{
autoroute::{Autoroute, AutorouteStatus}, autoroute::Autoroute,
compare_detours::{CompareDetours, CompareDetoursStatus}, compare_detours::CompareDetours,
execute::{Command, Execute},
history::{History, HistoryError}, history::{History, HistoryError},
measure_length::MeasureLength, measure_length::MeasureLength,
place_via::PlaceVia, place_via::PlaceVia,
remove_bands::RemoveBands, remove_bands::RemoveBands,
selection::{BandSelection, PinSelection}, Autorouter, AutorouterError,
Autorouter, AutorouterError, AutorouterOptions,
}; };
#[enum_dispatch] #[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<M: AccessMesadata>(
&mut self,
invoker: &mut Invoker<M>,
) -> Result<InvokerStatus, InvokerError> {
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<M: AccessMesadata> Step<Invoker<M>, InvokerStatus, InvokerError, ()> for Execute {
fn step(&mut self, invoker: &mut Invoker<M>) -> Result<InvokerStatus, InvokerError> {
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<InvokerStatus>,
}
impl ExecuteWithStatus {
pub fn new(execute: Execute) -> ExecuteWithStatus {
Self {
execute,
maybe_status: None,
}
}
pub fn step<M: AccessMesadata>(
&mut self,
invoker: &mut Invoker<M>,
) -> Result<InvokerStatus, InvokerError> {
let status = self.execute.step(invoker)?;
self.maybe_status = Some(status.clone());
Ok(status)
}
pub fn maybe_status(&self) -> Option<InvokerStatus> {
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<M: AccessMesadata> { pub struct Invoker<M: AccessMesadata> {
autorouter: Autorouter<M>, pub(super) autorouter: Autorouter<M>,
history: History, pub(super) history: History,
ongoing_command: Option<Command>, pub(super) ongoing_command: Option<Command>,
} }
impl<M: AccessMesadata> Invoker<M> { impl<M: AccessMesadata> Invoker<M> {
@ -271,22 +134,18 @@ impl<M: AccessMesadata> Invoker<M> {
}); });
} }
Execute::Autoroute( Execute::Autoroute(self.autorouter.autoroute_ratlines(ratlines, *options)?)
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)?,
),
}) })
} }

View File

@ -1,6 +1,7 @@
pub mod autoroute; pub mod autoroute;
mod autorouter; mod autorouter;
pub mod compare_detours; pub mod compare_detours;
pub mod execute;
pub mod history; pub mod history;
pub mod invoker; pub mod invoker;
pub mod measure_length; pub mod measure_length;

View File

@ -14,7 +14,8 @@ use unic_langid::{langid, LanguageIdentifier};
use topola::{ use topola::{
autorouter::{ autorouter::{
invoker::{Command, Execute, ExecuteWithStatus, Invoker, InvokerStatus}, execute::ExecuteWithStatus,
invoker::{Invoker, InvokerStatus},
Autorouter, Autorouter,
}, },
drawing::{ drawing::{

View File

@ -1,4 +1,4 @@
use topola::autorouter::invoker::{Execute, ExecuteWithStatus, InvokerStatus}; use topola::autorouter::{execute::ExecuteWithStatus, invoker::InvokerStatus};
use crate::{translator::Translator, viewport::Viewport}; use crate::{translator::Translator, viewport::Viewport};

View File

@ -6,7 +6,8 @@ use std::{
use topola::{ use topola::{
autorouter::{ autorouter::{
invoker::{Command, Execute, ExecuteWithStatus, Invoker, InvokerError, InvokerStatus}, execute::{Command, ExecuteWithStatus},
invoker::{Invoker, InvokerError, InvokerStatus},
AutorouterOptions, AutorouterOptions,
}, },
router::RouterOptions, router::RouterOptions,

View File

@ -5,9 +5,9 @@ use petgraph::{
}; };
use rstar::{Envelope, AABB}; use rstar::{Envelope, AABB};
use topola::{ use topola::{
autorouter::invoker::{ autorouter::{
Command, ExecuteWithStatus, GetGhosts, GetMaybeNavmesh, GetMaybeTrace, GetObstacles, execute::{Command, ExecuteWithStatus},
Invoker, invoker::{GetGhosts, GetMaybeNavmesh, GetMaybeTrace, GetObstacles, Invoker},
}, },
board::mesadata::AccessMesadata, board::mesadata::AccessMesadata,
drawing::{ drawing::{

View File

@ -1,8 +1,5 @@
use topola::{ use topola::{
autorouter::{ autorouter::{execute::Command, invoker::InvokerError, AutorouterError},
invoker::{Command, InvokerError},
AutorouterError,
},
board::mesadata::AccessMesadata, board::mesadata::AccessMesadata,
layout::via::ViaWeight, layout::via::ViaWeight,
math::Circle, math::Circle,

View File

@ -1,6 +1,7 @@
use topola::{ use topola::{
autorouter::{ autorouter::{
invoker::{Command, Invoker, InvokerError}, execute::Command,
invoker::{Invoker, InvokerError},
AutorouterError, AutorouterError,
}, },
layout::via::ViaWeight, layout::via::ViaWeight,