From 43b48e78e31ddfe2b0841da6a09e15fdcdb46907 Mon Sep 17 00:00:00 2001 From: Mikolaj Wielgus Date: Sun, 4 Aug 2024 18:50:58 +0200 Subject: [PATCH] router: use `Step` trait for `Astar` too --- src/autorouter/autorouter.rs | 12 +++++--- src/autorouter/invoker.rs | 12 +++++--- src/router/astar.rs | 59 ++++++++++++++++++------------------ src/router/route.rs | 8 +++-- src/router/router.rs | 18 +++++++---- src/router/trace.rs | 6 ++-- src/router/tracer.rs | 16 ++++++---- src/step.rs | 10 ++---- 8 files changed, 80 insertions(+), 61 deletions(-) diff --git a/src/autorouter/autorouter.rs b/src/autorouter/autorouter.rs index 707efcf..1219f73 100644 --- a/src/autorouter/autorouter.rs +++ b/src/autorouter/autorouter.rs @@ -7,7 +7,6 @@ use crate::{ drawing::{band::BandTermsegIndex, dot::FixedDotIndex, Infringement}, layout::via::ViaWeight, router::{navmesh::NavmeshError, RouterError}, - step::{GetMaybeOutcome, Step}, triangulation::GetTrianvertexNodeIndex, }; @@ -37,9 +36,14 @@ pub enum AutorouterStatus { Finished, } -impl GetMaybeOutcome<()> for AutorouterStatus { - fn maybe_outcome(&self) -> Option<()> { - matches!(self, AutorouterStatus::Finished).then(|| ()) +impl TryInto<()> for AutorouterStatus { + type Error = (); + fn try_into(self) -> Result<(), ()> { + match self { + AutorouterStatus::Running => Err(()), + AutorouterStatus::Routed(..) => Err(()), + AutorouterStatus::Finished => Ok(()), + } } } diff --git a/src/autorouter/invoker.rs b/src/autorouter/invoker.rs index 9807da3..311fa2c 100644 --- a/src/autorouter/invoker.rs +++ b/src/autorouter/invoker.rs @@ -9,7 +9,7 @@ use crate::{ geometry::primitive::PrimitiveShape, layout::via::ViaWeight, router::{navmesh::Navmesh, trace::Trace}, - step::{GetMaybeOutcome, Step}, + step::Step, }; use super::{ @@ -55,9 +55,13 @@ pub enum InvokerStatus { Finished, } -impl GetMaybeOutcome<()> for InvokerStatus { - fn maybe_outcome(&self) -> Option<()> { - matches!(self, InvokerStatus::Finished).then(|| ()) +impl TryInto<()> for InvokerStatus { + type Error = (); + fn try_into(self) -> Result<(), ()> { + match self { + InvokerStatus::Running => Err(()), + InvokerStatus::Finished => Ok(()), + } } } diff --git a/src/router/astar.rs b/src/router/astar.rs index 7bff639..4afbeb9 100644 --- a/src/router/astar.rs +++ b/src/router/astar.rs @@ -15,6 +15,8 @@ use thiserror::Error; use std::cmp::Ordering; +use crate::step::Step; + #[derive(Copy, Clone, Debug)] pub struct MinScored(pub K, pub T); @@ -156,6 +158,24 @@ where Finished(K, Vec, R), } +impl TryInto<(K, Vec, R)> for AstarStatus +where + G: GraphBase, + G::NodeId: Eq + Hash, + for<'a> &'a G: IntoEdges + MakeEdgeRef, + K: Measure + Copy, +{ + type Error = (); + fn try_into(self) -> Result<(K, Vec, R), ()> { + match self { + AstarStatus::Probing => Err(()), + AstarStatus::Probed => Err(()), + AstarStatus::Visited => Err(()), + AstarStatus::Finished(cost, path, result) => Ok((cost, path, result)), + } + } +} + impl Astar where G: GraphBase, @@ -183,11 +203,17 @@ where )); this } +} - pub fn step( - &mut self, - strategy: &mut impl AstarStrategy, - ) -> Result, AstarError> { +impl> + Step, AstarError, (K, Vec, R)> for Astar +where + G: GraphBase, + G::NodeId: Eq + Hash, + for<'a> &'a G: IntoEdges + MakeEdgeRef, + K: Measure + Copy, +{ + fn step(&mut self, strategy: &mut S) -> Result, AstarError> { if let Some(curr_node) = self.maybe_curr_node { if self.is_probing { strategy.remove_probe(&self.graph); @@ -263,28 +289,3 @@ where Ok(AstarStatus::Visited) } } - -pub fn astar( - graph: G, - start: G::NodeId, - strategy: &mut impl AstarStrategy, -) -> Result<(K, Vec, R), AstarError> -where - G: GraphBase, - G::NodeId: Eq + Hash, - for<'a> &'a G: IntoEdges + MakeEdgeRef, - K: Measure + Copy, -{ - let mut astar = Astar::new(graph, start, strategy); - - loop { - let status = match astar.step(strategy) { - Ok(status) => status, - Err(err) => return Err(err), - }; - - if let AstarStatus::Finished(cost, path, band) = status { - return Ok((cost, path, band)); - } - } -} diff --git a/src/router/route.rs b/src/router/route.rs index 7f14b1f..7ae2e3f 100644 --- a/src/router/route.rs +++ b/src/router/route.rs @@ -1,5 +1,7 @@ use crate::{ - drawing::{dot::FixedDotIndex, graph::PrimitiveIndex, rules::AccessRules}, + drawing::{ + band::BandTermsegIndex, dot::FixedDotIndex, graph::PrimitiveIndex, rules::AccessRules, + }, geometry::primitive::PrimitiveShape, router::{ astar::{Astar, AstarStatus}, @@ -71,7 +73,9 @@ impl Route { } } -impl<'a, R: AccessRules> Step, RouterStatus, RouterError, ()> for Route { +impl<'a, R: AccessRules> Step, RouterStatus, RouterError, BandTermsegIndex> + for Route +{ fn step(&mut self, router: &mut Router) -> Result { let tracer = Tracer::new(router.layout_mut()); let target = self.astar.graph.destination(); diff --git a/src/router/router.rs b/src/router/router.rs index 31f8979..1d25cd6 100644 --- a/src/router/router.rs +++ b/src/router/router.rs @@ -1,3 +1,5 @@ +use std::convert::Infallible; + use geo::EuclideanDistance; use petgraph::{data::DataMap, visit::EdgeRef}; use thiserror::Error; @@ -18,7 +20,7 @@ use crate::{ }, graph::{GetPetgraphIndex, MakeRef}, layout::Layout, - step::{GetMaybeOutcome, Step, StepBack}, + step::{Step, StepBack}, }; use super::{ @@ -26,7 +28,7 @@ use super::{ draw::DrawException, navmesh::{Navmesh, NavmeshEdgeReference, NavmeshError, NavvertexIndex}, route::Route, - trace::{Trace, TraceStepInput}, + trace::{Trace, TraceStepContext}, tracer::{Tracer, TracerException}, }; @@ -43,9 +45,13 @@ pub enum RouterStatus { Finished(BandTermsegIndex), } -impl GetMaybeOutcome<()> for RouterStatus { - fn maybe_outcome(&self) -> Option<()> { - matches!(self, RouterStatus::Finished(..)).then(|| ()) +impl TryInto for RouterStatus { + type Error = (); + fn try_into(self) -> Result { + match self { + RouterStatus::Running => Err(()), + RouterStatus::Finished(band_termseg) => Ok(band_termseg), + } } } @@ -114,7 +120,7 @@ impl<'a, R: AccessRules> AstarStrategy let prev_bihead_length = self.bihead_length(); let width = self.trace.width; - let result = self.trace.step(&mut TraceStepInput { + let result = self.trace.step(&mut TraceStepContext { tracer: &mut self.tracer, navmesh, to: edge.target(), diff --git a/src/router/trace.rs b/src/router/trace.rs index 12d909b..bc06407 100644 --- a/src/router/trace.rs +++ b/src/router/trace.rs @@ -93,14 +93,14 @@ impl Trace { } } -pub struct TraceStepInput<'a: 'b, 'b, R: AccessRules> { +pub struct TraceStepContext<'a: 'b, 'b, R: AccessRules> { pub tracer: &'b mut Tracer<'a, R>, pub navmesh: &'b Navmesh, pub to: NavvertexIndex, pub width: f64, } -impl<'a, 'b, R: AccessRules> Step, TracerStatus, TracerException, ()> +impl<'a, 'b, R: AccessRules> Step, TracerStatus, TracerException, ()> for Trace { #[debug_ensures(ret.is_ok() -> matches!(self.head, Head::Cane(..)))] @@ -108,7 +108,7 @@ impl<'a, 'b, R: AccessRules> Step, TracerStatus, Trace #[debug_ensures(ret.is_err() -> self.path.len() == old(self.path.len()))] fn step( &mut self, - input: &mut TraceStepInput<'a, 'b, R>, + input: &mut TraceStepContext<'a, 'b, R>, ) -> Result { self.head = self .wrap( diff --git a/src/router/tracer.rs b/src/router/tracer.rs index 5e8eb0b..6351a76 100644 --- a/src/router/tracer.rs +++ b/src/router/tracer.rs @@ -4,13 +4,13 @@ use thiserror::Error; use crate::{ drawing::{band::BandTermsegIndex, dot::FixedDotIndex, rules::AccessRules}, layout::Layout, - step::{GetMaybeOutcome, Step, StepBack}, + step::{Step, StepBack}, }; use super::{ draw::{Draw, DrawException}, navmesh::{Navmesh, NavvertexIndex}, - trace::{Trace, TraceStepInput}, + trace::{Trace, TraceStepContext}, }; #[derive(Error, Debug, Clone, Copy)] @@ -26,9 +26,13 @@ pub enum TracerStatus { Finished, } -impl GetMaybeOutcome<()> for TracerStatus { - fn maybe_outcome(&self) -> Option<()> { - matches!(self, TracerStatus::Finished).then(|| ()) +impl TryInto<()> for TracerStatus { + type Error = (); + fn try_into(self) -> Result<(), ()> { + match self { + TracerStatus::Running => Err(()), + TracerStatus::Finished => Ok(()), + } } } @@ -91,7 +95,7 @@ impl<'a, R: AccessRules> Tracer<'a, R> { width: f64, ) -> Result<(), TracerException> { for (i, vertex) in path.iter().enumerate() { - if let Err(err) = trace.step(&mut TraceStepInput { + if let Err(err) = trace.step(&mut TraceStepContext { tracer: self, navmesh, to: *vertex, diff --git a/src/step.rs b/src/step.rs index f9009ee..e4a5171 100644 --- a/src/step.rs +++ b/src/step.rs @@ -1,19 +1,15 @@ -pub trait GetMaybeOutcome { - fn maybe_outcome(&self) -> Option; -} - -pub trait Step, E, O> { +pub trait Step, E, O> { fn step(&mut self, context: &mut C) -> Result; fn finish(&mut self, context: &mut C) -> Result { loop { - if let Some(outcome) = self.step(context)?.maybe_outcome() { + if let Ok(outcome) = self.step(context)?.try_into() { return Ok(outcome); } } } } -pub trait StepBack, E, O> { +pub trait StepBack, E, O> { fn step_back(&mut self, context: &mut C) -> Result; }