mirror of https://codeberg.org/topola/topola.git
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:
parent
dcbc5be5f3
commit
b22e3dce1a
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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!();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue