From 36bc606401a0f96b54a2f08a006aa04949e65810 Mon Sep 17 00:00:00 2001 From: Mikolaj Wielgus Date: Sat, 11 May 2024 05:00:53 +0200 Subject: [PATCH] autorouter: fix off-by-one error when walking over ratlines --- src/autorouter/autorouter.rs | 42 ++++++++++++-------------------- src/bin/topola-egui/app.rs | 2 +- src/bin/topola-sdl2-demo/main.rs | 6 ++--- 3 files changed, 19 insertions(+), 31 deletions(-) diff --git a/src/autorouter/autorouter.rs b/src/autorouter/autorouter.rs index 8993279..248cce3 100644 --- a/src/autorouter/autorouter.rs +++ b/src/autorouter/autorouter.rs @@ -24,8 +24,7 @@ use crate::{ pub struct Autoroute { edge_indices: EdgeIndices, - cur_edge: EdgeIndex, - navmesh: Navmesh, // Useful for debugging. + navmesh: Option, // Useful for debugging. } impl Autoroute { @@ -39,11 +38,10 @@ impl Autoroute { let (from, to) = Self::edge_from_to(autorouter, cur_edge); let layout = autorouter.layout.lock().unwrap(); - let navmesh = Navmesh::new(&layout, from, to).ok()?; + let navmesh = Some(Navmesh::new(&layout, from, to).ok()?); let this = Self { edge_indices, - cur_edge, navmesh, }; @@ -54,33 +52,23 @@ impl Autoroute { &mut self, autorouter: &mut Autorouter, observer: &mut impl RouterObserverTrait, - ) -> Option<()> { - let navmesh = { - let (from, to) = self.from_to(autorouter); + ) -> bool { + let new_navmesh = if let Some(cur_edge) = self.edge_indices.next() { + let (from, to) = Self::edge_from_to(autorouter, cur_edge); + let layout = autorouter.layout.lock().unwrap(); - Navmesh::new(&layout, from, to).ok()? + Some(Navmesh::new(&layout, from, to).ok()?) + } else { + None }; let router = Router::new_from_navmesh( &mut autorouter.layout, - std::mem::replace(&mut self.navmesh, navmesh), + std::mem::replace(&mut self.navmesh, new_navmesh).unwrap(), ); router.unwrap().route_band(100.0, observer); - if let Some(cur_edge) = self.edge_indices.next() { - self.cur_edge = cur_edge; - } else { - return None; - } - - Some(()) - } - - pub fn from_to( - &self, - autorouter: &Autorouter, - ) -> (FixedDotIndex, FixedDotIndex) { - Self::edge_from_to(autorouter, self.cur_edge) + self.navmesh.is_some() } fn edge_from_to( @@ -115,7 +103,7 @@ impl Autoroute { (from_dot, to_dot) } - pub fn navmesh(&self) -> &Navmesh { + pub fn navmesh(&self) -> &Option { &self.navmesh } } @@ -132,14 +120,14 @@ impl Autorouter { } pub fn autoroute(&mut self, layer: u64, observer: &mut impl RouterObserverTrait) { - if let Some(mut it) = self.autoroute_iter() { - while let Some(()) = it.next(self, observer) { + if let Some(mut autoroute) = self.autoroute_walk() { + while autoroute.next(self, observer) { // } } } - pub fn autoroute_iter(&mut self) -> Option { + pub fn autoroute_walk(&mut self) -> Option { Autoroute::new(self.ratsnest.graph().edge_indices(), self) } diff --git a/src/bin/topola-egui/app.rs b/src/bin/topola-egui/app.rs index 15532e7..2eba2d8 100644 --- a/src/bin/topola-egui/app.rs +++ b/src/bin/topola-egui/app.rs @@ -202,7 +202,7 @@ impl eframe::App for App { execute(async move { let mut autorouter = Autorouter::new(layout).unwrap(); - if let Some(mut autoroute) = autorouter.autoroute_iter() { + if let Some(mut autoroute) = autorouter.autoroute_walk() { let from_to = autoroute.from_to(&autorouter); { diff --git a/src/bin/topola-sdl2-demo/main.rs b/src/bin/topola-sdl2-demo/main.rs index 67f4229..a0b8cc5 100644 --- a/src/bin/topola-sdl2-demo/main.rs +++ b/src/bin/topola-sdl2-demo/main.rs @@ -289,8 +289,8 @@ fn main() -> Result<(), anyhow::Error> { ); let mut autorouter = Autorouter::new(layout.clone()).unwrap(); - if let Some(mut autoroute) = autorouter.autoroute_iter() { - while let Some(()) = autoroute.next( + if let Some(mut autoroute) = autorouter.autoroute_walk() { + while autoroute.next( &mut autorouter, &mut DebugRouterObserver::new( &mut event_pump, @@ -298,7 +298,7 @@ fn main() -> Result<(), anyhow::Error> { &mut renderer, &font_context, &mut view, - Some(autoroute.navmesh().clone()), + autoroute.navmesh().clone(), ), ) { //