router: remove observers

The observer "pattern", arguably, is an anti-pattern that managed to get
into textbooks. It causes a lot of problems, it was a bad idea to use
it.
This commit is contained in:
Mikolaj Wielgus 2024-06-18 01:29:38 +02:00
parent d193ea6565
commit e15e1efe5e
11 changed files with 45 additions and 319 deletions

View File

@ -3,7 +3,7 @@ use petgraph::graph::EdgeIndex;
use crate::{ use crate::{
autorouter::{Autorouter, AutorouterError, AutorouterStatus}, autorouter::{Autorouter, AutorouterError, AutorouterStatus},
board::mesadata::MesadataTrait, board::mesadata::MesadataTrait,
router::{navmesh::Navmesh, RouterObserverTrait}, router::navmesh::Navmesh,
}; };
pub struct Autoroute { pub struct Autoroute {
@ -38,7 +38,6 @@ impl Autoroute {
pub fn step<M: MesadataTrait>( pub fn step<M: MesadataTrait>(
&mut self, &mut self,
autorouter: &mut Autorouter<M>, autorouter: &mut Autorouter<M>,
observer: &mut impl RouterObserverTrait<M>,
) -> Result<AutorouterStatus, AutorouterError> { ) -> Result<AutorouterStatus, AutorouterError> {
let (new_navmesh, new_ratline) = if let Some(cur_ratline) = self.ratlines_iter.next() { let (new_navmesh, new_ratline) = if let Some(cur_ratline) = self.ratlines_iter.next() {
let (source, target) = autorouter.ratline_endpoints(cur_ratline); let (source, target) = autorouter.ratline_endpoints(cur_ratline);
@ -58,7 +57,6 @@ impl Autoroute {
match autorouter.board.route_band( match autorouter.board.route_band(
std::mem::replace(&mut self.navmesh, new_navmesh).unwrap(), std::mem::replace(&mut self.navmesh, new_navmesh).unwrap(),
100.0, 100.0,
observer,
) { ) {
Ok(band) => { Ok(band) => {
autorouter autorouter

View File

@ -12,7 +12,7 @@ use crate::{
board::{mesadata::MesadataTrait, Board}, board::{mesadata::MesadataTrait, Board},
drawing::{dot::FixedDotIndex, Infringement}, drawing::{dot::FixedDotIndex, Infringement},
layout::via::ViaWeight, layout::via::ViaWeight,
router::{navmesh::NavmeshError, RouterError, RouterObserverTrait}, router::{navmesh::NavmeshError, RouterError},
triangulation::GetTrianvertexIndex, triangulation::GetTrianvertexIndex,
}; };
@ -44,15 +44,11 @@ impl<M: MesadataTrait> Autorouter<M> {
Ok(Self { board, ratsnest }) Ok(Self { board, ratsnest })
} }
pub fn autoroute( pub fn autoroute(&mut self, selection: &Selection) -> Result<(), AutorouterError> {
&mut self,
selection: &Selection,
observer: &mut impl RouterObserverTrait<M>,
) -> Result<(), AutorouterError> {
let mut autoroute = self.autoroute_walk(selection)?; let mut autoroute = self.autoroute_walk(selection)?;
loop { loop {
let status = match autoroute.step(self, observer) { let status = match autoroute.step(self) {
Ok(status) => status, Ok(status) => status,
Err(err) => return Err(err), Err(err) => return Err(err),
}; };

View File

@ -11,7 +11,6 @@ use crate::{
}, },
board::mesadata::MesadataTrait, board::mesadata::MesadataTrait,
layout::via::ViaWeight, layout::via::ViaWeight,
router::{EmptyRouterObserver, RouterObserverTrait},
}; };
#[derive(Error, Debug, Clone)] #[derive(Error, Debug, Clone)]
@ -42,15 +41,12 @@ impl Execute {
pub fn step<M: MesadataTrait>( pub fn step<M: MesadataTrait>(
&mut self, &mut self,
invoker: &mut Invoker<M>, invoker: &mut Invoker<M>,
observer: &mut impl RouterObserverTrait<M>,
) -> Result<InvokerStatus, InvokerError> { ) -> Result<InvokerStatus, InvokerError> {
match self { match self {
Execute::Autoroute(autoroute) => { Execute::Autoroute(autoroute) => match autoroute.step(&mut invoker.autorouter)? {
match autoroute.step(&mut invoker.autorouter, observer)? {
AutorouterStatus::Running => Ok(InvokerStatus::Running), AutorouterStatus::Running => Ok(InvokerStatus::Running),
AutorouterStatus::Finished => Ok(InvokerStatus::Finished), AutorouterStatus::Finished => Ok(InvokerStatus::Finished),
} },
}
Execute::PlaceVia(place_via) => { Execute::PlaceVia(place_via) => {
place_via.doit(&mut invoker.autorouter)?; place_via.doit(&mut invoker.autorouter)?;
Ok(InvokerStatus::Finished) Ok(InvokerStatus::Finished)
@ -80,15 +76,11 @@ impl<M: MesadataTrait> Invoker<M> {
(self.autorouter, self.history) (self.autorouter, self.history)
} }
pub fn execute( pub fn execute(&mut self, command: Command) -> Result<(), InvokerError> {
&mut self,
command: Command,
observer: &mut impl RouterObserverTrait<M>,
) -> Result<(), InvokerError> {
let mut execute = self.execute_walk(command); let mut execute = self.execute_walk(command);
loop { loop {
let status = match execute.step(self, observer) { let status = match execute.step(self) {
Ok(status) => status, Ok(status) => status,
Err(err) => return Err(err), Err(err) => return Err(err),
}; };
@ -133,7 +125,7 @@ impl<M: MesadataTrait> Invoker<M> {
let mut execute = self.dispatch_command(&command); let mut execute = self.dispatch_command(&command);
loop { loop {
let status = match execute.step(self, &mut EmptyRouterObserver) { let status = match execute.step(self) {
Ok(status) => status, Ok(status) => status,
Err(err) => return Err(err), Err(err) => return Err(err),
}; };
@ -148,7 +140,7 @@ impl<M: MesadataTrait> Invoker<M> {
let (done, undone) = history.destructure(); let (done, undone) = history.destructure();
for command in done { for command in done {
self.execute(command, &mut EmptyRouterObserver); self.execute(command);
} }
self.history.set_undone(undone.into_iter()); self.history.set_undone(undone.into_iter());

View File

@ -35,7 +35,6 @@ use topola::{
draw::DrawException, draw::DrawException,
navmesh::{Navmesh, NavmeshEdgeReference, NavvertexIndex}, navmesh::{Navmesh, NavmeshEdgeReference, NavvertexIndex},
tracer::{Trace, Tracer}, tracer::{Trace, Tracer},
EmptyRouterObserver, RouterObserverTrait,
}, },
specctra::{design::SpecctraDesign, mesadata::SpecctraMesadata}, specctra::{design::SpecctraDesign, mesadata::SpecctraMesadata},
}; };
@ -111,56 +110,6 @@ impl App {
} }
} }
pub struct DebugRouterObserver {
pub shared_data: Arc<Mutex<SharedData>>,
}
impl<R: RulesTrait + std::fmt::Debug> RouterObserverTrait<R> for DebugRouterObserver {
fn on_rework(&mut self, tracer: &Tracer<R>, trace: &Trace) {
//dbg!(_tracer, _trace);
let mut shared_data = self.shared_data.lock().unwrap();
shared_data.path = trace.path.clone();
shared_data.ghosts = vec![];
shared_data.highlighteds = vec![];
std::thread::sleep_ms(500);
}
fn before_probe(&mut self, tracer: &Tracer<R>, trace: &Trace, edge: NavmeshEdgeReference) {
//dbg!(_tracer, _trace, _edge);
let mut shared_data = self.shared_data.lock().unwrap();
shared_data.path = trace.path.clone();
shared_data.path.push(edge.target());
shared_data.ghosts = vec![];
shared_data.highlighteds = vec![];
std::thread::sleep_ms(100);
}
fn on_probe(
&mut self,
tracer: &Tracer<R>,
trace: &Trace,
edge: NavmeshEdgeReference,
result: Result<(), DrawException>,
) {
//dbg!(_tracer, _trace, _edge, _result);
let mut shared_data = self.shared_data.lock().unwrap();
let (ghosts, highlighteds, delay) = match result {
Err(DrawException::CannotWrapAround(
..,
LayoutException::Infringement(Infringement(shape1, infringee1)),
LayoutException::Infringement(Infringement(shape2, infringee2)),
)) => (vec![shape1, shape2], vec![infringee1, infringee2], 1500),
_ => (vec![], vec![], 300),
};
shared_data.path = trace.path.clone();
shared_data.ghosts = ghosts;
shared_data.highlighteds = highlighteds;
std::thread::sleep_ms(delay);
}
fn on_estimate(&mut self, _tracer: &Tracer<R>, _vertex: NavvertexIndex) {
//dbg!(_tracer, _vertex);
}
}
impl eframe::App for App { impl eframe::App for App {
/// Called to save state before shutdown. /// Called to save state before shutdown.
fn save(&mut self, storage: &mut dyn eframe::Storage) { fn save(&mut self, storage: &mut dyn eframe::Storage) {

View File

@ -9,7 +9,7 @@ use topola::{
}; };
use crate::{ use crate::{
app::{channel_text, execute, DebugRouterObserver, SharedData}, app::{channel_text, execute, SharedData},
overlay::Overlay, overlay::Overlay,
}; };
@ -124,12 +124,7 @@ impl Top {
} }
let _ = loop { let _ = loop {
let status = match execute.step( let status = match execute.step(&mut invoker) {
&mut invoker,
&mut DebugRouterObserver {
shared_data: shared_data_arc_mutex.clone(),
},
) {
Ok(status) => status, Ok(status) => status,
Err(err) => return, Err(err) => return,
}; };

View File

@ -9,7 +9,6 @@ use topola::{
geometry::{shape::ShapeTrait, GenericNode}, geometry::{shape::ShapeTrait, GenericNode},
layout::{via::ViaWeight, zone::MakePolyShape}, layout::{via::ViaWeight, zone::MakePolyShape},
math::Circle, math::Circle,
router::EmptyRouterObserver,
specctra::mesadata::SpecctraMesadata, specctra::mesadata::SpecctraMesadata,
}; };
@ -89,7 +88,6 @@ impl Viewport {
}, },
maybe_net: Some(1234), maybe_net: Some(1234),
}), }),
&mut EmptyRouterObserver,
); );
}); });
} else if let Some(overlay) = maybe_overlay { } else if let Some(overlay) = maybe_overlay {

View File

@ -27,7 +27,6 @@ use topola::layout::Layout;
use topola::router::draw::DrawException; use topola::router::draw::DrawException;
use topola::router::navmesh::{Navmesh, NavmeshEdgeReference, NavvertexIndex}; use topola::router::navmesh::{Navmesh, NavmeshEdgeReference, NavvertexIndex};
use topola::router::tracer::{Trace, Tracer}; use topola::router::tracer::{Trace, Tracer};
use topola::router::RouterObserverTrait;
use topola::specctra::design::SpecctraDesign; use topola::specctra::design::SpecctraDesign;
use topola::specctra::mesadata::SpecctraMesadata; use topola::specctra::mesadata::SpecctraMesadata;
@ -87,107 +86,6 @@ enum RouterOrLayout<'a, R: RulesTrait> {
Layout(&'a Layout<R>), Layout(&'a Layout<R>),
} }
struct DebugRouterObserver<'a> {
event_pump: &'a mut sdl2::EventPump,
window: &'a Window,
renderer: &'a mut Renderer<GLDevice>,
font_context: &'a CanvasFontContext,
view: &'a mut View,
navmesh: Option<Navmesh>,
}
impl<'a> DebugRouterObserver<'a> {
pub fn new(
event_pump: &'a mut sdl2::EventPump,
window: &'a Window,
renderer: &'a mut Renderer<GLDevice>,
font_context: &'a CanvasFontContext,
view: &'a mut View,
navmesh: Option<Navmesh>,
) -> Self {
Self {
event_pump,
window,
renderer,
font_context,
view,
navmesh,
}
}
}
impl<'a, R: RulesTrait> RouterObserverTrait<R> for DebugRouterObserver<'a> {
fn on_rework(&mut self, tracer: &Tracer<R>, trace: &Trace) {
render_times(
self.event_pump,
self.window,
self.renderer,
self.font_context,
self.view,
RouterOrLayout::Layout(tracer.layout),
None,
self.navmesh.clone(),
&trace.path,
&[],
&[],
40,
);
}
fn before_probe(&mut self, tracer: &Tracer<R>, trace: &Trace, edge: NavmeshEdgeReference) {
let mut path = trace.path.clone();
path.push(edge.target());
render_times(
self.event_pump,
self.window,
self.renderer,
self.font_context,
self.view,
RouterOrLayout::Layout(tracer.layout),
None,
self.navmesh.clone(),
&path,
&[],
&[],
10,
);
}
fn on_probe(
&mut self,
tracer: &Tracer<R>,
trace: &Trace,
_edge: NavmeshEdgeReference,
result: Result<(), DrawException>,
) {
let (ghosts, highlighteds, delay) = match result {
Err(DrawException::CannotWrapAround(
..,
LayoutException::Infringement(Infringement(shape1, infringee1)),
LayoutException::Infringement(Infringement(shape2, infringee2)),
)) => (vec![shape1, shape2], vec![infringee1, infringee2], 30),
_ => (vec![], vec![], 10),
};
render_times(
self.event_pump,
self.window,
self.renderer,
self.font_context,
self.view,
RouterOrLayout::Layout(tracer.layout),
None,
self.navmesh.clone(),
&trace.path,
&ghosts,
&highlighteds,
delay,
);
}
fn on_estimate(&mut self, _tracer: &Tracer<R>, _vertex: NavvertexIndex) {}
}
fn main() -> Result<(), anyhow::Error> { fn main() -> Result<(), anyhow::Error> {
let sdl_context = sdl2::init().unwrap(); let sdl_context = sdl2::init().unwrap();
let video_subsystem = sdl_context.video().unwrap(); let video_subsystem = sdl_context.video().unwrap();
@ -230,7 +128,7 @@ fn main() -> Result<(), anyhow::Error> {
let font_context = CanvasFontContext::from_system_source(); let font_context = CanvasFontContext::from_system_source();
// TODO: make a type like this wrapping the details of pathfinder // TODO: make a type like this wrapping the details of pathfinder
// so we don't pass so many arguments to render_times() and through the debug observer // so we don't pass so many arguments to render_times()
//let mut canvas = window.into_canvas().build().unwrap(); //let mut canvas = window.into_canvas().build().unwrap();
let mut event_pump = sdl_context.event_pump().unwrap(); let mut event_pump = sdl_context.event_pump().unwrap();
@ -276,32 +174,8 @@ fn main() -> Result<(), anyhow::Error> {
let mut autorouter = Autorouter::new(board).unwrap(); let mut autorouter = Autorouter::new(board).unwrap();
if let Ok(mut autoroute) = autorouter.autoroute_walk(&Selection::new()) { if let Ok(mut autoroute) = autorouter.autoroute_walk(&Selection::new()) {
/*while autoroute.step(
&mut autorouter,
&mut DebugRouterObserver::new(
&mut event_pump,
&window,
&mut renderer,
&font_context,
&mut view,
autoroute.navmesh().clone(),
),
) {
//
}*/
loop { loop {
let status = match autoroute.step( let status = match autoroute.step(&mut autorouter) {
&mut autorouter,
&mut DebugRouterObserver::new(
&mut event_pump,
&window,
&mut renderer,
&font_context,
&mut view,
autoroute.navmesh().clone(),
),
) {
Ok(status) => status, Ok(status) => status,
Err(err) => break, Err(err) => break,
}; };
@ -317,8 +191,6 @@ fn main() -> Result<(), anyhow::Error> {
dot_indices[1], dot_indices[1],
dot_indices[2], dot_indices[2],
3.0, 3.0,
//&mut EmptyRouterObserver,
&mut DebugRouterObserver::new(&mut event_pump, &window, &mut renderer, &font_context),
)?;*/ )?;*/
render_times( render_times(
@ -408,14 +280,6 @@ fn render_times(
band, band,
point! {x: state.x() as f64, y: state.y() as f64}, point! {x: state.x() as f64, y: state.y() as f64},
3.0, 3.0,
&mut DebugRouterObserver::new(
event_pump,
window,
renderer,
font_context,
view,
maybe_navmesh,
),
) )
.ok(); .ok();
maybe_navmesh = None; maybe_navmesh = None;

View File

@ -15,7 +15,7 @@ use crate::{
Layout, NodeIndex, Layout, NodeIndex,
}, },
math::Circle, math::Circle,
router::{navmesh::Navmesh, Router, RouterError, RouterObserverTrait}, router::{navmesh::Navmesh, Router, RouterError},
}; };
#[derive(Debug)] #[derive(Debug)]
@ -115,12 +115,7 @@ impl<M: MesadataTrait> Board<M> {
zone zone
} }
pub fn route_band( pub fn route_band(&mut self, navmesh: Navmesh, width: f64) -> Result<BandIndex, RouterError> {
&mut self,
navmesh: Navmesh,
width: f64,
observer: &mut impl RouterObserverTrait<M>,
) -> Result<BandIndex, RouterError> {
let source_pinname = self let source_pinname = self
.node_pinname(GenericNode::Primitive(navmesh.source().into())) .node_pinname(GenericNode::Primitive(navmesh.source().into()))
.unwrap() .unwrap()
@ -131,7 +126,7 @@ impl<M: MesadataTrait> Board<M> {
.to_string(); .to_string();
let mut router = Router::new_from_navmesh(self.layout_mut(), navmesh); let mut router = Router::new_from_navmesh(self.layout_mut(), navmesh);
let result = router.route_band(100.0, observer); let result = router.route_band(100.0);
if let Ok(band) = result { if let Ok(band) = result {
self.pinname_pair_to_band self.pinname_pair_to_band

View File

@ -27,66 +27,24 @@ pub enum RouterError {
Astar(#[from] AstarError), Astar(#[from] AstarError),
} }
pub trait RouterObserverTrait<R: RulesTrait> {
fn on_rework(&mut self, tracer: &Tracer<R>, trace: &Trace);
fn before_probe(&mut self, tracer: &Tracer<R>, trace: &Trace, edge: NavmeshEdgeReference);
fn on_probe(
&mut self,
tracer: &Tracer<R>,
trace: &Trace,
edge: NavmeshEdgeReference,
result: Result<(), DrawException>,
);
fn on_estimate(&mut self, tracer: &Tracer<R>, vertex: NavvertexIndex);
}
pub struct EmptyRouterObserver;
impl<R: RulesTrait> RouterObserverTrait<R> for EmptyRouterObserver {
fn on_rework(&mut self, _tracer: &Tracer<R>, _trace: &Trace) {}
fn before_probe(&mut self, _tracer: &Tracer<R>, _trace: &Trace, _edge: NavmeshEdgeReference) {}
fn on_probe(
&mut self,
_tracer: &Tracer<R>,
_trace: &Trace,
_edge: NavmeshEdgeReference,
_result: Result<(), DrawException>,
) {
}
fn on_estimate(&mut self, _tracer: &Tracer<R>, _vertex: NavvertexIndex) {}
}
pub struct Router<'a, R: RulesTrait> { pub struct Router<'a, R: RulesTrait> {
layout: &'a mut Layout<R>, layout: &'a mut Layout<R>,
navmesh: Navmesh, navmesh: Navmesh,
} }
struct RouterAstarStrategy<'a, RO: RouterObserverTrait<R>, R: RulesTrait> { struct RouterAstarStrategy<'a, R: RulesTrait> {
tracer: Tracer<'a, R>, tracer: Tracer<'a, R>,
trace: Trace, trace: Trace,
to: FixedDotIndex, to: FixedDotIndex,
observer: &'a mut RO,
} }
impl<'a, RO: RouterObserverTrait<R>, R: RulesTrait> RouterAstarStrategy<'a, RO, R> { impl<'a, R: RulesTrait> RouterAstarStrategy<'a, R> {
pub fn new( pub fn new(tracer: Tracer<'a, R>, trace: Trace, to: FixedDotIndex) -> Self {
tracer: Tracer<'a, R>, Self { tracer, trace, to }
trace: Trace,
to: FixedDotIndex,
observer: &'a mut RO,
) -> Self {
Self {
tracer,
trace,
to,
observer,
}
} }
} }
impl<'a, RO: RouterObserverTrait<R>, R: RulesTrait> AstarStrategy<&Navmesh, f64, BandIndex> impl<'a, R: RulesTrait> AstarStrategy<&Navmesh, f64, BandIndex> for RouterAstarStrategy<'a, R> {
for RouterAstarStrategy<'a, RO, R>
{
fn is_goal( fn is_goal(
&mut self, &mut self,
vertex: NavvertexIndex, vertex: NavvertexIndex,
@ -98,13 +56,11 @@ impl<'a, RO: RouterObserverTrait<R>, R: RulesTrait> AstarStrategy<&Navmesh, f64,
self.tracer self.tracer
.rework_path(&mut self.trace, &new_path, width) .rework_path(&mut self.trace, &new_path, width)
.unwrap(); .unwrap();
self.observer.on_rework(&self.tracer, &self.trace);
self.tracer.finish(&mut self.trace, self.to, width).ok() self.tracer.finish(&mut self.trace, self.to, width).ok()
} }
fn edge_cost(&mut self, edge: NavmeshEdgeReference) -> Option<f64> { fn edge_cost(&mut self, edge: NavmeshEdgeReference) -> Option<f64> {
self.observer.before_probe(&self.tracer, &self.trace, edge);
if edge.target() == self.to.into() { if edge.target() == self.to.into() {
return None; return None;
} }
@ -113,8 +69,6 @@ impl<'a, RO: RouterObserverTrait<R>, R: RulesTrait> AstarStrategy<&Navmesh, f64,
let width = self.trace.width; let width = self.trace.width;
let result = self.tracer.step(&mut self.trace, edge.target(), width); let result = self.tracer.step(&mut self.trace, edge.target(), width);
self.observer
.on_probe(&self.tracer, &self.trace, edge, result);
let probe_length = 0.0; //self.tracer.layout.band_length(self.trace.head.face()); let probe_length = 0.0; //self.tracer.layout.band_length(self.trace.head.face());
@ -127,8 +81,6 @@ impl<'a, RO: RouterObserverTrait<R>, R: RulesTrait> AstarStrategy<&Navmesh, f64,
} }
fn estimate_cost(&mut self, vertex: NavvertexIndex) -> f64 { fn estimate_cost(&mut self, vertex: NavvertexIndex) -> f64 {
self.observer.on_estimate(&self.tracer, vertex);
let start_point = PrimitiveIndex::from(vertex) let start_point = PrimitiveIndex::from(vertex)
.primitive(self.tracer.layout.drawing()) .primitive(self.tracer.layout.drawing())
.shape() .shape()
@ -159,11 +111,7 @@ impl<'a, R: RulesTrait> Router<'a, R> {
Self { layout, navmesh } Self { layout, navmesh }
} }
pub fn route_band( pub fn route_band(&mut self, width: f64) -> Result<BandIndex, RouterError> {
&mut self,
width: f64,
observer: &mut impl RouterObserverTrait<R>,
) -> Result<BandIndex, RouterError> {
let from = self.navmesh.source(); let from = self.navmesh.source();
let to = self.navmesh.target(); let to = self.navmesh.target();
let mut tracer = Tracer::new(self.layout); let mut tracer = Tracer::new(self.layout);
@ -172,7 +120,7 @@ impl<'a, R: RulesTrait> Router<'a, R> {
let (_cost, _path, band) = astar( let (_cost, _path, band) = astar(
&self.navmesh, &self.navmesh,
from.into(), from.into(),
&mut RouterAstarStrategy::new(tracer, trace, to, observer), &mut RouterAstarStrategy::new(tracer, trace, to),
)?; )?;
Ok(band) Ok(band)
@ -183,7 +131,6 @@ impl<'a, R: RulesTrait> Router<'a, R> {
band: BandIndex, band: BandIndex,
to: Point, to: Point,
width: f64, width: f64,
observer: &mut impl RouterObserverTrait<R>,
) -> Result<BandIndex, RoutingError> { ) -> Result<BandIndex, RoutingError> {
{ {
let mut layout = self.layout.lock().unwrap(); let mut layout = self.layout.lock().unwrap();
@ -192,7 +139,7 @@ impl<'a, R: RulesTrait> Router<'a, R> {
layout.move_dot(self.navmesh.to().into(), to).unwrap(); // TODO: Remove `.unwrap()`. layout.move_dot(self.navmesh.to().into(), to).unwrap(); // TODO: Remove `.unwrap()`.
} }
self.route_band(width, observer) self.route_band(width)
}*/ }*/
pub fn layout(&mut self) -> &mut Layout<R> { pub fn layout(&mut self) -> &mut Layout<R> {

View File

@ -6,7 +6,6 @@ use topola::{
board::mesadata::MesadataTrait, board::mesadata::MesadataTrait,
layout::via::ViaWeight, layout::via::ViaWeight,
math::Circle, math::Circle,
router::EmptyRouterObserver,
}; };
mod common; mod common;
@ -17,8 +16,7 @@ fn test_unrouted_lm317_breakout() {
"tests/multilayer/data/prerouted_lm317_breakout/unrouted_lm317_breakout.dsn", "tests/multilayer/data/prerouted_lm317_breakout/unrouted_lm317_breakout.dsn",
); );
let result = invoker.execute( let result = invoker.execute(Command::PlaceVia(ViaWeight {
Command::PlaceVia(ViaWeight {
from_layer: 0, from_layer: 0,
to_layer: 1, to_layer: 1,
circle: Circle { circle: Circle {
@ -26,9 +24,7 @@ fn test_unrouted_lm317_breakout() {
r: 1000.0, r: 1000.0,
}, },
maybe_net: Some(1234), maybe_net: Some(1234),
}), }));
&mut EmptyRouterObserver,
);
let result = dbg!(result); let result = dbg!(result);
assert!(matches!( assert!(matches!(
result, result,

View File

@ -5,7 +5,6 @@ use topola::{
}, },
layout::via::ViaWeight, layout::via::ViaWeight,
math::Circle, math::Circle,
router::EmptyRouterObserver,
}; };
mod common; mod common;
@ -42,8 +41,7 @@ fn test_tht_diode_bridge_rectifier() {
common::assert_band_length(autorouter.board(), "J2-2", "D4-2", 15500.0, 0.5); common::assert_band_length(autorouter.board(), "J2-2", "D4-2", 15500.0, 0.5);
let mut invoker = Invoker::new(autorouter); let mut invoker = Invoker::new(autorouter);
let result = invoker.execute( let result = invoker.execute(Command::PlaceVia(ViaWeight {
Command::PlaceVia(ViaWeight {
from_layer: 0, from_layer: 0,
to_layer: 1, to_layer: 1,
circle: Circle { circle: Circle {
@ -51,9 +49,7 @@ fn test_tht_diode_bridge_rectifier() {
r: 200000.0, r: 200000.0,
}, },
maybe_net: Some(1234), maybe_net: Some(1234),
}), }));
&mut EmptyRouterObserver,
);
assert!(matches!( assert!(matches!(
result, result,
Err(InvokerError::Autorouter(AutorouterError::CouldNotPlaceVia( Err(InvokerError::Autorouter(AutorouterError::CouldNotPlaceVia(