Parametrize routing using `RouteStrategy` trait

This commit is contained in:
Mikolaj Wielgus 2023-09-02 06:05:13 +02:00
parent bea6d84878
commit c492bd1dda
3 changed files with 55 additions and 17 deletions

View File

@ -1,8 +1,6 @@
/**
*
* Copied from petgraph's scored.rs and algo/astar.rs. Renamed the `is_goal: IsGoal` callback to
* `reroute: Reroute` and made it pass a reference to `path_tracker` and return a value to be added
* to outgoing edge costs.
* Copied and substantially modified from petgraph's scored.rs and algo/astar.rs.
*
* Copyright (c) 2015
**/

View File

@ -24,6 +24,7 @@ mod segbend;
mod shape;
use graph::{Tag, TaggedIndex};
use router::DefaultRouteStrategy;
use sdl2::event::Event;
use sdl2::gfx::primitives::DrawRenderer;
use sdl2::keyboard::Keycode;
@ -218,7 +219,7 @@ fn main() {
let head = router.draw_around_dot(head, dot6, false, 5.0).unwrap();
let _ = router.draw_finish(head, dot7, 5.0);*/
router.enroute(dot1_1, dot1_2);
router.enroute(dot1_1, dot1_2, DefaultRouteStrategy::new());
render_times(&mut event_pump, &mut canvas, &mut router, None, -1);
render_times(

View File

@ -21,19 +21,53 @@ pub struct Router {
rules: Rules,
}
pub struct DefaultAstarStrategy<'a> {
route: Route<'a>,
trace: Trace,
to: VertexIndex,
pub trait RouteStrategy {
fn route_cost(&mut self, path: &[VertexIndex]) -> u64;
fn edge_cost(&mut self, edge: MeshEdgeReference) -> u64;
fn estimate_cost(&mut self, vertex: VertexIndex) -> u64;
}
impl<'a> DefaultAstarStrategy<'a> {
pub fn new(route: Route<'a>, trace: Trace, to: VertexIndex) -> Self {
Self { route, trace, to }
pub struct DefaultRouteStrategy {}
impl DefaultRouteStrategy {
pub fn new() -> Self {
Self {}
}
}
impl<'a> AstarStrategy<&Mesh, u64> for DefaultAstarStrategy<'a> {
impl RouteStrategy for DefaultRouteStrategy {
fn route_cost(&mut self, path: &[VertexIndex]) -> u64 {
0
}
fn edge_cost(&mut self, edge: MeshEdgeReference) -> u64 {
1
}
fn estimate_cost(&mut self, vertex: VertexIndex) -> u64 {
0
}
}
struct RouterAstarStrategy<'a, RS: RouteStrategy> {
route: Route<'a>,
trace: Trace,
to: VertexIndex,
route_strategy: RS,
}
impl<'a, RS: RouteStrategy> RouterAstarStrategy<'a, RS> {
pub fn new(route: Route<'a>, trace: Trace, to: VertexIndex, route_strategy: RS) -> Self {
Self {
route,
trace,
to,
route_strategy,
}
}
}
impl<'a, RS: RouteStrategy> AstarStrategy<&Mesh, u64> for RouterAstarStrategy<'a, RS> {
fn reroute(&mut self, vertex: VertexIndex, tracker: &PathTracker<&Mesh>) -> Option<u64> {
let new_path = tracker.reconstruct_path_to(vertex);
@ -47,16 +81,16 @@ impl<'a> AstarStrategy<&Mesh, u64> for DefaultAstarStrategy<'a> {
None
} else {
self.route.rework_path(&mut self.trace, &new_path, 5.0).ok();
Some(0)
Some(self.route_strategy.route_cost(&new_path))
}
}
fn edge_cost(&mut self, edge: MeshEdgeReference) -> u64 {
1
self.route_strategy.edge_cost(edge)
}
fn estimate_cost(&mut self, vertex: VertexIndex) -> u64 {
0
self.route_strategy.estimate_cost(vertex)
}
}
@ -68,7 +102,12 @@ impl Router {
}
}
pub fn enroute(&mut self, from: DotIndex, to: DotIndex) -> Result<(), InsertionError> {
pub fn enroute(
&mut self,
from: DotIndex,
to: DotIndex,
strategy: impl RouteStrategy,
) -> Result<(), InsertionError> {
// XXX: Should we actually store the mesh? May be useful for debugging, but doesn't look
// right.
//self.mesh.triangulate(&self.layout)?;
@ -81,7 +120,7 @@ impl Router {
let (_cost, path) = astar(
&mesh,
mesh.vertex(from),
&mut DefaultAstarStrategy::new(route, trace, mesh.vertex(to)),
&mut RouterAstarStrategy::new(route, trace, mesh.vertex(to), strategy),
)
.unwrap(); // TODO.
Ok(())