router: return band index once the routing finishes

This commit is contained in:
Mikolaj Wielgus 2024-05-15 01:45:36 +02:00
parent 1c09483873
commit 114fb747c8
4 changed files with 31 additions and 26 deletions

View File

@ -94,22 +94,22 @@ where
} }
} }
pub trait AstarStrategy<G, K> pub trait AstarStrategy<G, K, R>
where where
G: IntoEdges, G: IntoEdges,
K: Measure + Copy, K: Measure + Copy,
G::NodeId: Eq + Hash, G::NodeId: Eq + Hash,
{ {
fn is_goal(&mut self, node: G::NodeId, tracker: &PathTracker<G>) -> bool; fn is_goal(&mut self, node: G::NodeId, tracker: &PathTracker<G>) -> Option<R>;
fn edge_cost(&mut self, edge: G::EdgeRef) -> Option<K>; fn edge_cost(&mut self, edge: G::EdgeRef) -> Option<K>;
fn estimate_cost(&mut self, node: G::NodeId) -> K; fn estimate_cost(&mut self, node: G::NodeId) -> K;
} }
pub fn astar<G, K>( pub fn astar<G, K, R>(
graph: G, graph: G,
start: G::NodeId, start: G::NodeId,
strategy: &mut impl AstarStrategy<G, K>, strategy: &mut impl AstarStrategy<G, K, R>,
) -> Option<(K, Vec<G::NodeId>)> ) -> Option<(K, Vec<G::NodeId>, R)>
where where
G: IntoEdges, G: IntoEdges,
G::NodeId: Eq + Hash, G::NodeId: Eq + Hash,
@ -125,10 +125,10 @@ where
visit_next.push(MinScored(strategy.estimate_cost(start), start)); visit_next.push(MinScored(strategy.estimate_cost(start), start));
while let Some(MinScored(estimate_score, node)) = visit_next.pop() { while let Some(MinScored(estimate_score, node)) = visit_next.pop() {
if strategy.is_goal(node, &path_tracker) { if let Some(result) = strategy.is_goal(node, &path_tracker) {
let path = path_tracker.reconstruct_path_to(node); let path = path_tracker.reconstruct_path_to(node);
let cost = scores[&node]; let cost = scores[&node];
return Some((cost, path)); return Some((cost, path, result));
} }
// This lookup can be unwrapped without fear of panic since the node was // This lookup can be unwrapped without fear of panic since the node was

View File

@ -4,6 +4,7 @@ use thiserror::Error;
use crate::{ use crate::{
drawing::{ drawing::{
band::BandIndex,
bend::{BendIndex, LooseBendWeight}, bend::{BendIndex, LooseBendWeight},
dot::{DotIndex, FixedDotIndex, LooseDotIndex, LooseDotWeight}, dot::{DotIndex, FixedDotIndex, LooseDotIndex, LooseDotWeight},
graph::{GetLayer, GetMaybeNet, MakePrimitive}, graph::{GetLayer, GetMaybeNet, MakePrimitive},
@ -50,7 +51,7 @@ impl<'a, R: RulesTrait> Draw<'a, R> {
head: Head, head: Head,
into: FixedDotIndex, into: FixedDotIndex,
width: f64, width: f64,
) -> Result<(), DrawException> { ) -> Result<BandIndex, DrawException> {
let tangent = self let tangent = self
.guide() .guide()
.head_into_dot_segment(&head, into, width) .head_into_dot_segment(&head, into, width)
@ -61,8 +62,8 @@ impl<'a, R: RulesTrait> Draw<'a, R> {
let layer = head.face().primitive(self.layout.drawing()).layer(); let layer = head.face().primitive(self.layout.drawing()).layer();
let maybe_net = head.face().primitive(self.layout.drawing()).maybe_net(); let maybe_net = head.face().primitive(self.layout.drawing()).maybe_net();
match head.face() { Ok::<BandIndex, DrawException>(match head.face() {
DotIndex::Fixed(dot) => { DotIndex::Fixed(dot) => BandIndex::Straight(
self.layout self.layout
.add_lone_loose_seg( .add_lone_loose_seg(
dot, dot,
@ -73,9 +74,9 @@ impl<'a, R: RulesTrait> Draw<'a, R> {
maybe_net, maybe_net,
}, },
) )
.map_err(|err| DrawException::CannotFinishIn(into, err.into()))?; .map_err(|err| DrawException::CannotFinishIn(into, err.into()))?,
} ),
DotIndex::Loose(dot) => { DotIndex::Loose(dot) => BandIndex::Bended(
self.layout self.layout
.add_seq_loose_seg( .add_seq_loose_seg(
into.into(), into.into(),
@ -86,10 +87,9 @@ impl<'a, R: RulesTrait> Draw<'a, R> {
maybe_net, maybe_net,
}, },
) )
.map_err(|err| DrawException::CannotFinishIn(into, err.into()))?; .map_err(|err| DrawException::CannotFinishIn(into, err.into()))?,
} ),
} })
Ok::<(), DrawException>(())
} }
#[debug_ensures(ret.is_ok() -> self.layout.drawing().node_count() == old(self.layout.drawing().node_count() + 4))] #[debug_ensures(ret.is_ok() -> self.layout.drawing().node_count() == old(self.layout.drawing().node_count() + 4))]

View File

@ -6,6 +6,7 @@ use petgraph::visit::EdgeRef;
use spade::InsertionError; use spade::InsertionError;
use thiserror::Error; use thiserror::Error;
use crate::drawing::band::BandIndex;
use crate::drawing::graph::{GetLayer, GetMaybeNet}; use crate::drawing::graph::{GetLayer, GetMaybeNet};
use crate::drawing::guide::HeadTrait; use crate::drawing::guide::HeadTrait;
use crate::geometry::primitive::PrimitiveShapeTrait; use crate::geometry::primitive::PrimitiveShapeTrait;
@ -97,10 +98,14 @@ impl<'a, RO: RouterObserverTrait<R>, R: RulesTrait> RouterAstarStrategy<'a, RO,
} }
} }
impl<'a, RO: RouterObserverTrait<R>, R: RulesTrait> AstarStrategy<&Navmesh, f64> impl<'a, RO: RouterObserverTrait<R>, R: RulesTrait> AstarStrategy<&Navmesh, f64, BandIndex>
for RouterAstarStrategy<'a, RO, R> for RouterAstarStrategy<'a, RO, R>
{ {
fn is_goal(&mut self, vertex: VertexIndex, tracker: &PathTracker<&Navmesh>) -> bool { fn is_goal(
&mut self,
vertex: VertexIndex,
tracker: &PathTracker<&Navmesh>,
) -> Option<BandIndex> {
let new_path = tracker.reconstruct_path_to(vertex); let new_path = tracker.reconstruct_path_to(vertex);
let width = self.trace.width; let width = self.trace.width;
@ -109,7 +114,7 @@ impl<'a, RO: RouterObserverTrait<R>, R: RulesTrait> AstarStrategy<&Navmesh, f64>
.unwrap(); .unwrap();
self.observer.on_rework(&self.tracer, &self.trace); self.observer.on_rework(&self.tracer, &self.trace);
self.tracer.finish(&mut self.trace, self.to, width).is_ok() self.tracer.finish(&mut self.trace, self.to, width).ok()
} }
fn edge_cost(&mut self, edge: NavmeshEdgeReference) -> Option<f64> { fn edge_cost(&mut self, edge: NavmeshEdgeReference) -> Option<f64> {
@ -183,12 +188,12 @@ impl<'a, R: RulesTrait> Router<'a, R> {
&mut self, &mut self,
width: f64, width: f64,
observer: &mut impl RouterObserverTrait<R>, observer: &mut impl RouterObserverTrait<R>,
) -> Result<(), RoutingError> { ) -> Result<BandIndex, RoutingError> {
let mut tracer = self.tracer(); let mut tracer = self.tracer();
let trace = tracer.start(self.navmesh.from(), width); let trace = tracer.start(self.navmesh.from(), width);
let (_cost, _path) = astar( let (_cost, _path, band) = astar(
&self.navmesh, &self.navmesh,
self.navmesh.from().into(), self.navmesh.from().into(),
&mut RouterAstarStrategy::new(tracer, trace, self.navmesh.to(), observer), &mut RouterAstarStrategy::new(tracer, trace, self.navmesh.to(), observer),
@ -199,7 +204,7 @@ impl<'a, R: RulesTrait> Router<'a, R> {
source: RoutingErrorKind::AStar, source: RoutingErrorKind::AStar,
})?; })?;
Ok(()) Ok(band)
} }
/*pub fn reroute_band( /*pub fn reroute_band(

View File

@ -4,6 +4,7 @@ use contracts::debug_ensures;
use crate::{ use crate::{
drawing::{ drawing::{
band::BandIndex,
bend::LooseBendIndex, bend::LooseBendIndex,
dot::FixedDotIndex, dot::FixedDotIndex,
guide::{BareHead, Head, SegbendHead}, guide::{BareHead, Head, SegbendHead},
@ -46,9 +47,8 @@ impl<R: RulesTrait> Tracer<R> {
trace: &mut Trace, trace: &mut Trace,
into: FixedDotIndex, into: FixedDotIndex,
width: f64, width: f64,
) -> Result<(), DrawException> { ) -> Result<BandIndex, DrawException> {
Draw::new(&mut self.layout.lock().unwrap()).finish_in_dot(trace.head, into, width)?; Draw::new(&mut self.layout.lock().unwrap()).finish_in_dot(trace.head, into, width)
Ok(())
} }
#[debug_ensures(ret.is_ok() -> trace.path.len() == path.len())] #[debug_ensures(ret.is_ok() -> trace.path.len() == path.len())]