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
G: IntoEdges,
K: Measure + Copy,
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 estimate_cost(&mut self, node: G::NodeId) -> K;
}
pub fn astar<G, K>(
pub fn astar<G, K, R>(
graph: G,
start: G::NodeId,
strategy: &mut impl AstarStrategy<G, K>,
) -> Option<(K, Vec<G::NodeId>)>
strategy: &mut impl AstarStrategy<G, K, R>,
) -> Option<(K, Vec<G::NodeId>, R)>
where
G: IntoEdges,
G::NodeId: Eq + Hash,
@ -125,10 +125,10 @@ where
visit_next.push(MinScored(strategy.estimate_cost(start), start));
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 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

View File

@ -4,6 +4,7 @@ use thiserror::Error;
use crate::{
drawing::{
band::BandIndex,
bend::{BendIndex, LooseBendWeight},
dot::{DotIndex, FixedDotIndex, LooseDotIndex, LooseDotWeight},
graph::{GetLayer, GetMaybeNet, MakePrimitive},
@ -50,7 +51,7 @@ impl<'a, R: RulesTrait> Draw<'a, R> {
head: Head,
into: FixedDotIndex,
width: f64,
) -> Result<(), DrawException> {
) -> Result<BandIndex, DrawException> {
let tangent = self
.guide()
.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 maybe_net = head.face().primitive(self.layout.drawing()).maybe_net();
match head.face() {
DotIndex::Fixed(dot) => {
Ok::<BandIndex, DrawException>(match head.face() {
DotIndex::Fixed(dot) => BandIndex::Straight(
self.layout
.add_lone_loose_seg(
dot,
@ -73,9 +74,9 @@ impl<'a, R: RulesTrait> Draw<'a, R> {
maybe_net,
},
)
.map_err(|err| DrawException::CannotFinishIn(into, err.into()))?;
}
DotIndex::Loose(dot) => {
.map_err(|err| DrawException::CannotFinishIn(into, err.into()))?,
),
DotIndex::Loose(dot) => BandIndex::Bended(
self.layout
.add_seq_loose_seg(
into.into(),
@ -86,10 +87,9 @@ impl<'a, R: RulesTrait> Draw<'a, R> {
maybe_net,
},
)
.map_err(|err| DrawException::CannotFinishIn(into, err.into()))?;
}
}
Ok::<(), DrawException>(())
.map_err(|err| DrawException::CannotFinishIn(into, err.into()))?,
),
})
}
#[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 thiserror::Error;
use crate::drawing::band::BandIndex;
use crate::drawing::graph::{GetLayer, GetMaybeNet};
use crate::drawing::guide::HeadTrait;
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>
{
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 width = self.trace.width;
@ -109,7 +114,7 @@ impl<'a, RO: RouterObserverTrait<R>, R: RulesTrait> AstarStrategy<&Navmesh, f64>
.unwrap();
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> {
@ -183,12 +188,12 @@ impl<'a, R: RulesTrait> Router<'a, R> {
&mut self,
width: f64,
observer: &mut impl RouterObserverTrait<R>,
) -> Result<(), RoutingError> {
) -> Result<BandIndex, RoutingError> {
let mut tracer = self.tracer();
let trace = tracer.start(self.navmesh.from(), width);
let (_cost, _path) = astar(
let (_cost, _path, band) = astar(
&self.navmesh,
self.navmesh.from().into(),
&mut RouterAstarStrategy::new(tracer, trace, self.navmesh.to(), observer),
@ -199,7 +204,7 @@ impl<'a, R: RulesTrait> Router<'a, R> {
source: RoutingErrorKind::AStar,
})?;
Ok(())
Ok(band)
}
/*pub fn reroute_band(

View File

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