router,autorouter: stop hiding layout behind an arc-mutex

This was preventing us from creating a new abstraction layer over
layout.
This commit is contained in:
Mikolaj Wielgus 2024-05-30 22:47:19 +02:00
parent dcbc5be5f3
commit b22e3dce1a
7 changed files with 85 additions and 83 deletions

View File

@ -54,7 +54,7 @@ pub struct Autoroute {
impl Autoroute {
pub fn new(
ratlines: impl IntoIterator<Item = EdgeIndex<usize>> + 'static,
autorouter: &Autorouter<impl RulesTrait>,
autorouter: &mut Autorouter<impl RulesTrait>,
) -> Result<Self, AutorouterError> {
let mut ratlines_iter = Box::new(ratlines.into_iter());
@ -63,8 +63,7 @@ impl Autoroute {
};
let (source, target) = Self::ratline_endpoints(autorouter, cur_ratline);
let layout = autorouter.layout.lock().unwrap();
let navmesh = Some(Navmesh::new(&layout, source, target)?);
let navmesh = Some(Navmesh::new(&autorouter.layout, source, target)?);
let this = Self {
ratlines_iter,
@ -83,9 +82,12 @@ impl Autoroute {
let (new_navmesh, new_ratline) = if let Some(cur_ratline) = self.ratlines_iter.next() {
let (source, target) = Self::ratline_endpoints(autorouter, cur_ratline);
let layout = autorouter.layout.lock().unwrap();
(
Some(Navmesh::new(&layout, source, target).ok().unwrap()),
Some(
Navmesh::new(&autorouter.layout, source, target)
.ok()
.unwrap(),
),
Some(cur_ratline),
)
} else {
@ -115,10 +117,9 @@ impl Autoroute {
}
fn ratline_endpoints<R: RulesTrait>(
autorouter: &Autorouter<R>,
autorouter: &mut Autorouter<R>,
ratline: EdgeIndex<usize>,
) -> (FixedDotIndex, FixedDotIndex) {
let mut layout = autorouter.layout.lock().unwrap();
let (source, target) = autorouter.ratsnest.graph().edge_endpoints(ratline).unwrap();
let source_dot = match autorouter
@ -129,7 +130,7 @@ impl Autoroute {
.vertex_index()
{
RatsnestVertexIndex::FixedDot(dot) => dot,
RatsnestVertexIndex::Zone(zone) => layout.zone_apex(zone),
RatsnestVertexIndex::Zone(zone) => autorouter.layout.zone_apex(zone),
};
let target_dot = match autorouter
@ -140,7 +141,7 @@ impl Autoroute {
.vertex_index()
{
RatsnestVertexIndex::FixedDot(dot) => dot,
RatsnestVertexIndex::Zone(zone) => layout.zone_apex(zone),
RatsnestVertexIndex::Zone(zone) => autorouter.layout.zone_apex(zone),
};
(source_dot, target_dot)
@ -152,13 +153,13 @@ impl Autoroute {
}
pub struct Autorouter<R: RulesTrait> {
layout: Arc<Mutex<Layout<R>>>,
layout: Layout<R>,
ratsnest: Ratsnest,
}
impl<R: RulesTrait> Autorouter<R> {
pub fn new(layout: Arc<Mutex<Layout<R>>>) -> Result<Self, InsertionError> {
let ratsnest = Ratsnest::new(&layout.lock().unwrap())?;
pub fn new(layout: Layout<R>) -> Result<Self, InsertionError> {
let ratsnest = Ratsnest::new(&layout)?;
Ok(Self { layout, ratsnest })
}
@ -181,7 +182,7 @@ impl<R: RulesTrait> Autorouter<R> {
}
}
pub fn autoroute_walk(&self, selection: &Selection) -> Result<Autoroute, AutorouterError> {
pub fn autoroute_walk(&mut self, selection: &Selection) -> Result<Autoroute, AutorouterError> {
Autoroute::new(self.selected_ratlines(selection), self)
}
@ -194,7 +195,7 @@ impl<R: RulesTrait> Autorouter<R> {
.unwrap()
.band
.unwrap();
self.layout.lock().unwrap().remove_band(band);
self.layout.remove_band(band);
}
}
@ -218,14 +219,13 @@ impl<R: RulesTrait> Autorouter<R> {
.unwrap()
.vertex_index();
let layout = self.layout.lock().unwrap();
selection.contains_node(&layout, source_vertex.into())
&& selection.contains_node(&layout, to_vertex.into())
selection.contains_node(&self.layout, source_vertex.into())
&& selection.contains_node(&self.layout, to_vertex.into())
})
.collect()
}
pub fn layout(&self) -> &Arc<Mutex<Layout<R>>> {
pub fn layout(&self) -> &Layout<R> {
&self.layout
}

View File

@ -26,7 +26,7 @@ pub enum InvokerStatus {
Finished,
}
#[derive(serde::Serialize, serde::Deserialize)]
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub enum Command {
Autoroute(Selection),
}
@ -91,7 +91,7 @@ impl<R: RulesTrait> Invoker<R> {
execute
}
fn dispatch_command(&self, command: &Command) -> Execute {
fn dispatch_command(&mut self, command: &Command) -> Execute {
match command {
Command::Autoroute(ref selection) => {
Execute::Autoroute(self.autorouter.autoroute_walk(selection).unwrap())
@ -110,8 +110,8 @@ impl<R: RulesTrait> Invoker<R> {
}
pub fn redo(&mut self) -> Result<(), InvokerError> {
let command = self.history.last_undone()?;
let mut execute = self.dispatch_command(command);
let command = self.history.last_undone()?.clone();
let mut execute = self.dispatch_command(&command);
loop {
let status = match execute.step(self, &mut EmptyRouterObserver) {

View File

@ -163,7 +163,7 @@ impl eframe::App for App {
let layout = design.make_layout();
self.overlay = Some(Overlay::new(&layout).unwrap());
self.invoker = Some(Arc::new(Mutex::new(Invoker::new(
Autorouter::new(Arc::new(Mutex::new(layout))).unwrap(),
Autorouter::new(layout).unwrap(),
))));
}
} else {
@ -172,7 +172,7 @@ impl eframe::App for App {
let layout = design.make_layout();
self.overlay = Some(Overlay::new(&layout).unwrap());
self.invoker = Some(Arc::new(Mutex::new(Invoker::new(
Autorouter::new(Arc::new(Mutex::new(layout))).unwrap(),
Autorouter::new(layout).unwrap(),
))));
}
}
@ -359,7 +359,7 @@ impl eframe::App for App {
self.shared_data.lock().unwrap(),
&mut self.overlay,
) {
let layout = &invoker.autorouter().layout().lock().unwrap();
let layout = &invoker.autorouter().layout();
if ctx.input(|i| i.pointer.any_click()) {
overlay.click(

View File

@ -28,7 +28,7 @@ use topola::layout::zone::MakePolyShape;
use topola::layout::Layout;
use topola::router::draw::DrawException;
use topola::router::navmesh::{Navmesh, NavmeshEdgeReference, VertexIndex};
use topola::router::tracer::{Trace, Tracer};
use topola::router::trace::{Trace, Tracer};
use topola::router::RouterObserverTrait;
use sdl2::event::Event;

View File

@ -62,19 +62,24 @@ impl<R: RulesTrait> RouterObserverTrait<R> for EmptyRouterObserver {
}
pub struct Router<'a, R: RulesTrait> {
layout: &'a mut Arc<Mutex<Layout<R>>>,
layout: &'a mut Layout<R>,
navmesh: Navmesh,
}
struct RouterAstarStrategy<'a, RO: RouterObserverTrait<R>, R: RulesTrait> {
tracer: Tracer<R>,
tracer: Tracer<'a, R>,
trace: Trace,
to: FixedDotIndex,
observer: &'a mut RO,
}
impl<'a, RO: RouterObserverTrait<R>, R: RulesTrait> RouterAstarStrategy<'a, RO, R> {
pub fn new(tracer: Tracer<R>, trace: Trace, to: FixedDotIndex, observer: &'a mut RO) -> Self {
pub fn new(
tracer: Tracer<'a, R>,
trace: Trace,
to: FixedDotIndex,
observer: &'a mut RO,
) -> Self {
Self {
tracer,
trace,
@ -109,24 +114,14 @@ impl<'a, RO: RouterObserverTrait<R>, R: RulesTrait> AstarStrategy<&Navmesh, f64,
return None;
}
let before_probe_length = self
.tracer
.layout
.lock()
.unwrap()
.band_length(self.trace.head.face());
let before_probe_length = self.tracer.layout.band_length(self.trace.head.face());
let width = self.trace.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 = self
.tracer
.layout
.lock()
.unwrap()
.band_length(self.trace.head.face());
let probe_length = self.tracer.layout.band_length(self.trace.head.face());
if result.is_ok() {
self.tracer.undo_step(&mut self.trace);
@ -139,12 +134,17 @@ impl<'a, RO: RouterObserverTrait<R>, R: RulesTrait> AstarStrategy<&Navmesh, f64,
fn estimate_cost(&mut self, vertex: VertexIndex) -> f64 {
self.observer.on_estimate(&self.tracer, vertex);
let layout = self.tracer.layout.lock().unwrap();
let start_point = PrimitiveIndex::from(vertex)
.primitive(layout.drawing())
.primitive(self.tracer.layout.drawing())
.shape()
.center();
let end_point = self
.tracer
.layout
.drawing()
.primitive(self.to)
.shape()
.center();
let end_point = layout.drawing().primitive(self.to).shape().center();
end_point.euclidean_distance(&start_point)
}
@ -152,18 +152,15 @@ impl<'a, RO: RouterObserverTrait<R>, R: RulesTrait> AstarStrategy<&Navmesh, f64,
impl<'a, R: RulesTrait> Router<'a, R> {
pub fn new(
layout: &'a mut Arc<Mutex<Layout<R>>>,
layout: &'a mut Layout<R>,
from: FixedDotIndex,
to: FixedDotIndex,
) -> Result<Self, RouterError> {
let navmesh = {
let layout = layout.lock().unwrap();
Navmesh::new(&layout, from, to)?
};
let navmesh = { Navmesh::new(layout, from, to)? };
Ok(Self::new_from_navmesh(layout, navmesh))
}
pub fn new_from_navmesh(layout: &'a mut Arc<Mutex<Layout<R>>>, navmesh: Navmesh) -> Self {
pub fn new_from_navmesh(layout: &'a mut Layout<R>, navmesh: Navmesh) -> Self {
Self { layout, navmesh }
}
@ -172,13 +169,16 @@ impl<'a, R: RulesTrait> Router<'a, R> {
width: f64,
observer: &mut impl RouterObserverTrait<R>,
) -> Result<BandIndex, RouterError> {
let mut tracer = self.tracer();
let trace = tracer.start(self.navmesh.from(), width);
let from = self.navmesh.from();
let to = self.navmesh.to();
//let mut tracer = self.tracer();
let mut tracer = Tracer::new(self.layout);
let trace = tracer.start(from, width);
let (_cost, _path, band) = astar(
&self.navmesh,
self.navmesh.from().into(),
&mut RouterAstarStrategy::new(tracer, trace, self.navmesh.to(), observer),
from.into(),
&mut RouterAstarStrategy::new(tracer, trace, to, observer),
)?;
Ok(band)
@ -201,11 +201,11 @@ impl<'a, R: RulesTrait> Router<'a, R> {
self.route_band(width, observer)
}*/
fn tracer(&mut self) -> Tracer<R> {
Tracer::new(self.layout.clone())
}
/*fn tracer(&mut self) -> Tracer<R> {
Tracer::new(self.layout)
}*/
pub fn layout(&self) -> Arc<Mutex<Layout<R>>> {
self.layout.clone()
pub fn layout(&mut self) -> &mut Layout<R> {
self.layout
}
}

View File

@ -25,12 +25,12 @@ pub struct Trace {
}
#[derive(Debug)]
pub struct Tracer<R: RulesTrait> {
pub layout: Arc<Mutex<Layout<R>>>,
pub struct Tracer<'a, R: RulesTrait> {
pub layout: &'a mut Layout<R>,
}
impl<R: RulesTrait> Tracer<R> {
pub fn new(layout: Arc<Mutex<Layout<R>>>) -> Self {
impl<'a, R: RulesTrait> Tracer<'a, R> {
pub fn new(layout: &mut Layout<R>) -> Tracer<R> {
Tracer { layout }
}
@ -48,7 +48,7 @@ impl<R: RulesTrait> Tracer<R> {
into: FixedDotIndex,
width: f64,
) -> Result<BandIndex, DrawException> {
Draw::new(&mut self.layout.lock().unwrap()).finish_in_dot(trace.head, into, width)
Draw::new(self.layout).finish_in_dot(trace.head, into, width)
}
#[debug_ensures(ret.is_ok() -> trace.path.len() == path.len())]
@ -129,11 +129,7 @@ impl<R: RulesTrait> Tracer<R> {
around: FixedDotIndex,
width: f64,
) -> Result<SegbendHead, DrawException> {
let head = Draw::new(&mut self.layout.lock().unwrap()).segbend_around_dot(
head,
around.into(),
width,
)?;
let head = Draw::new(self.layout).segbend_around_dot(head, around.into(), width)?;
Ok(head)
}
@ -143,11 +139,7 @@ impl<R: RulesTrait> Tracer<R> {
around: LooseBendIndex,
width: f64,
) -> Result<SegbendHead, DrawException> {
let head = Draw::new(&mut self.layout.lock().unwrap()).segbend_around_bend(
head,
around.into(),
width,
)?;
let head = Draw::new(self.layout).segbend_around_bend(head, around.into(), width)?;
Ok(head)
}
@ -155,9 +147,7 @@ impl<R: RulesTrait> Tracer<R> {
#[debug_ensures(trace.path.len() == old(trace.path.len() - 1))]
pub fn undo_step(&mut self, trace: &mut Trace) {
if let Head::Segbend(head) = trace.head {
trace.head = Draw::new(&mut self.layout.lock().unwrap())
.undo_segbend(head)
.unwrap();
trace.head = Draw::new(self.layout).undo_segbend(head).unwrap();
} else {
panic!();
}

View File

@ -18,16 +18,28 @@ use topola::{
#[test]
fn test() {
let design = DsnDesign::load_from_file("tests/data/0603_breakout/0603_breakout.dsn").unwrap();
let layout_arc_mutex = Arc::new(Mutex::new(design.make_layout()));
let mut invoker = Invoker::new(Autorouter::new(layout_arc_mutex.clone()).unwrap());
let mut invoker = Invoker::new(Autorouter::new(design.make_layout()).unwrap());
let file = File::open("tests/data/0603_breakout/autoroute_all.cmd").unwrap();
invoker.replay(serde_json::from_reader(file).unwrap());
let layout = layout_arc_mutex.lock().unwrap();
let mut unionfind = UnionFind::new(layout.drawing().geometry().graph().node_bound());
let mut unionfind = UnionFind::new(
invoker
.autorouter()
.layout()
.drawing()
.geometry()
.graph()
.node_bound(),
);
for edge in layout.drawing().geometry().graph().edge_references() {
for edge in invoker
.autorouter()
.layout()
.drawing()
.geometry()
.graph()
.edge_references()
{
unionfind.union(edge.source(), edge.target());
}