diff --git a/src/autorouter/autorouter.rs b/src/autorouter/autorouter.rs index a606fd5..ca878d0 100644 --- a/src/autorouter/autorouter.rs +++ b/src/autorouter/autorouter.rs @@ -54,7 +54,7 @@ pub struct Autoroute { impl Autoroute { pub fn new( ratlines: impl IntoIterator> + 'static, - autorouter: &Autorouter, + autorouter: &mut Autorouter, ) -> Result { 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( - autorouter: &Autorouter, + autorouter: &mut Autorouter, ratline: EdgeIndex, ) -> (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 { - layout: Arc>>, + layout: Layout, ratsnest: Ratsnest, } impl Autorouter { - pub fn new(layout: Arc>>) -> Result { - let ratsnest = Ratsnest::new(&layout.lock().unwrap())?; + pub fn new(layout: Layout) -> Result { + let ratsnest = Ratsnest::new(&layout)?; Ok(Self { layout, ratsnest }) } @@ -181,7 +182,7 @@ impl Autorouter { } } - pub fn autoroute_walk(&self, selection: &Selection) -> Result { + pub fn autoroute_walk(&mut self, selection: &Selection) -> Result { Autoroute::new(self.selected_ratlines(selection), self) } @@ -194,7 +195,7 @@ impl Autorouter { .unwrap() .band .unwrap(); - self.layout.lock().unwrap().remove_band(band); + self.layout.remove_band(band); } } @@ -218,14 +219,13 @@ impl Autorouter { .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>> { + pub fn layout(&self) -> &Layout { &self.layout } diff --git a/src/autorouter/invoker.rs b/src/autorouter/invoker.rs index 1454577..e11f086 100644 --- a/src/autorouter/invoker.rs +++ b/src/autorouter/invoker.rs @@ -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 Invoker { 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 Invoker { } 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) { diff --git a/src/bin/topola-egui/app.rs b/src/bin/topola-egui/app.rs index f670b18..13ca75c 100644 --- a/src/bin/topola-egui/app.rs +++ b/src/bin/topola-egui/app.rs @@ -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( diff --git a/src/bin/topola-sdl2-demo/main.rs b/src/bin/topola-sdl2-demo/main.rs index 1b050a5..8c7343c 100644 --- a/src/bin/topola-sdl2-demo/main.rs +++ b/src/bin/topola-sdl2-demo/main.rs @@ -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; diff --git a/src/router/router.rs b/src/router/router.rs index 0b09b48..ff7d94f 100644 --- a/src/router/router.rs +++ b/src/router/router.rs @@ -62,19 +62,24 @@ impl RouterObserverTrait for EmptyRouterObserver { } pub struct Router<'a, R: RulesTrait> { - layout: &'a mut Arc>>, + layout: &'a mut Layout, navmesh: Navmesh, } struct RouterAstarStrategy<'a, RO: RouterObserverTrait, R: RulesTrait> { - tracer: Tracer, + tracer: Tracer<'a, R>, trace: Trace, to: FixedDotIndex, observer: &'a mut RO, } impl<'a, RO: RouterObserverTrait, R: RulesTrait> RouterAstarStrategy<'a, RO, R> { - pub fn new(tracer: Tracer, 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: 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: 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: RulesTrait> AstarStrategy<&Navmesh, f64, impl<'a, R: RulesTrait> Router<'a, R> { pub fn new( - layout: &'a mut Arc>>, + layout: &'a mut Layout, from: FixedDotIndex, to: FixedDotIndex, ) -> Result { - 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>>, navmesh: Navmesh) -> Self { + pub fn new_from_navmesh(layout: &'a mut Layout, navmesh: Navmesh) -> Self { Self { layout, navmesh } } @@ -172,13 +169,16 @@ impl<'a, R: RulesTrait> Router<'a, R> { width: f64, observer: &mut impl RouterObserverTrait, ) -> Result { - 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 { - Tracer::new(self.layout.clone()) - } + /*fn tracer(&mut self) -> Tracer { + Tracer::new(self.layout) + }*/ - pub fn layout(&self) -> Arc>> { - self.layout.clone() + pub fn layout(&mut self) -> &mut Layout { + self.layout } } diff --git a/src/router/tracer.rs b/src/router/tracer.rs index ef1769a..4083696 100644 --- a/src/router/tracer.rs +++ b/src/router/tracer.rs @@ -25,12 +25,12 @@ pub struct Trace { } #[derive(Debug)] -pub struct Tracer { - pub layout: Arc>>, +pub struct Tracer<'a, R: RulesTrait> { + pub layout: &'a mut Layout, } -impl Tracer { - pub fn new(layout: Arc>>) -> Self { +impl<'a, R: RulesTrait> Tracer<'a, R> { + pub fn new(layout: &mut Layout) -> Tracer { Tracer { layout } } @@ -48,7 +48,7 @@ impl Tracer { into: FixedDotIndex, width: f64, ) -> Result { - 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 Tracer { around: FixedDotIndex, width: f64, ) -> Result { - 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 Tracer { around: LooseBendIndex, width: f64, ) -> Result { - 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 Tracer { #[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!(); } diff --git a/tests/0603_breakout.rs b/tests/0603_breakout.rs index db222ee..82a50ec 100644 --- a/tests/0603_breakout.rs +++ b/tests/0603_breakout.rs @@ -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()); }