mirror of https://codeberg.org/topola/topola.git
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:
parent
d193ea6565
commit
e15e1efe5e
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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),
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -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());
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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> {
|
||||||
|
|
|
||||||
|
|
@ -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,18 +16,15 @@ 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 {
|
pos: [125000.0, -84000.0].into(),
|
||||||
pos: [125000.0, -84000.0].into(),
|
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,
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ use topola::{
|
||||||
},
|
},
|
||||||
layout::via::ViaWeight,
|
layout::via::ViaWeight,
|
||||||
math::Circle,
|
math::Circle,
|
||||||
router::EmptyRouterObserver,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
mod common;
|
mod common;
|
||||||
|
|
@ -42,18 +41,15 @@ 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 {
|
pos: [0.0, 0.0].into(),
|
||||||
pos: [0.0, 0.0].into(),
|
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(
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue