router: Rename `Route` to `Tracer` and simplify related code

This commit is contained in:
Mikolaj Wielgus 2023-10-11 22:23:18 +00:00
parent cc3b537b5c
commit af61a6b120
4 changed files with 91 additions and 138 deletions

View File

@ -100,7 +100,7 @@ where
K: Measure + Copy,
G::NodeId: Eq + Hash,
{
fn reroute(&mut self, node: G::NodeId, tracker: &PathTracker<G>) -> Option<K>;
fn is_goal(&mut self, node: G::NodeId, tracker: &PathTracker<G>) -> bool;
fn edge_cost(&mut self, edge: G::EdgeRef) -> K;
fn estimate_cost(&mut self, node: G::NodeId) -> K;
}
@ -125,13 +125,12 @@ where
visit_next.push(MinScored(strategy.estimate_cost(start), start));
while let Some(MinScored(estimate_score, node)) = visit_next.pop() {
match strategy.reroute(node, &path_tracker) {
None => {
if strategy.is_goal(node, &path_tracker) {
let path = path_tracker.reconstruct_path_to(node);
let cost = scores[&node];
return Some((cost, path));
}
Some(route_cost) => {
// This lookup can be unwrapped without fear of panic since the node was
// necessarily scored before adding it to `visit_next`.
let node_score = scores[&node];
@ -152,7 +151,7 @@ where
for edge in graph.edges(node) {
let next = edge.target();
let next_score = node_score + route_cost + strategy.edge_cost(edge);
let next_score = node_score + strategy.edge_cost(edge);
match scores.entry(next) {
Occupied(mut entry) => {
@ -173,8 +172,6 @@ where
visit_next.push(MinScored(next_estimate_score, next));
}
}
}
}
None
}

View File

@ -18,19 +18,18 @@ mod layout;
mod math;
mod mesh;
mod primitive;
mod route;
mod router;
mod rules;
mod segbend;
mod shape;
mod tracer;
use geo::point;
use graph::{DotIndex, SegWeight, Tag, TaggedIndex};
use graph::{DotIndex, SegWeight};
use layout::Layout;
use mesh::{Mesh, MeshEdgeReference, VertexIndex};
use petgraph::visit::{EdgeRef, IntoEdgeReferences};
use route::Route;
use router::{DefaultRouteStrategy, RouteStrategy};
use router::RouterObserver;
use sdl2::event::Event;
use sdl2::gfx::primitives::DrawRenderer;
use sdl2::keyboard::Keycode;
@ -41,6 +40,7 @@ use sdl2::EventPump;
use shape::Shape;
use std::panic;
use std::time::Duration;
use tracer::Tracer;
use crate::graph::DotWeight;
use crate::math::Circle;
@ -52,48 +52,36 @@ enum RouterOrLayout<'a> {
Layout(&'a Layout),
}
struct DebugRouteStrategy<'a, RS: RouteStrategy> {
strategy: RS,
struct DebugRouterObserver<'a> {
event_pump: &'a mut sdl2::EventPump,
canvas: &'a mut sdl2::render::Canvas<Window>,
}
impl<'a, RS: RouteStrategy> DebugRouteStrategy<'a, RS> {
impl<'a> DebugRouterObserver<'a> {
pub fn new(
strategy: RS,
event_pump: &'a mut sdl2::EventPump,
canvas: &'a mut sdl2::render::Canvas<Window>,
) -> Self {
Self {
strategy,
event_pump,
canvas,
}
Self { event_pump, canvas }
}
}
impl<'a, RS: RouteStrategy> RouteStrategy for DebugRouteStrategy<'a, RS> {
fn route_cost(&mut self, route: &Route, path: &[VertexIndex]) -> u64 {
impl<'a> RouterObserver for DebugRouterObserver<'a> {
fn on_rework(&mut self, tracer: &Tracer, path: &[VertexIndex]) {
render_times(
self.event_pump,
self.canvas,
RouterOrLayout::Layout(route.layout),
RouterOrLayout::Layout(tracer.layout),
None,
None,
Some(route.mesh.clone()),
Some(tracer.mesh.clone()),
path,
10,
);
self.strategy.route_cost(route, path)
}
fn edge_cost(&mut self, route: &Route, edge: MeshEdgeReference) -> u64 {
self.strategy.edge_cost(route, edge)
}
fn estimate_cost(&mut self, route: &Route, vertex: VertexIndex) -> u64 {
self.strategy.estimate_cost(route, vertex)
}
fn on_probe(&mut self, _tracer: &Tracer, _edge: MeshEdgeReference) {}
fn on_estimate(&mut self, _tracer: &Tracer, _vertex: VertexIndex) {}
}
fn main() {
@ -304,11 +292,7 @@ fn render_times(
.reroute(
from,
point! {x: state.x() as f64, y: state.y() as f64},
&mut DebugRouteStrategy::new(
DefaultRouteStrategy::new(),
event_pump,
canvas,
),
&mut DebugRouterObserver::new(event_pump, canvas),
)
.ok();
}

View File

@ -1,91 +1,63 @@
use geo::geometry::Point;
use petgraph::visit::{EdgeRef, IntoEdgeReferences};
use petgraph::visit::EdgeRef;
use spade::InsertionError;
use crate::astar::{astar, AstarStrategy, PathTracker};
use crate::bow::Bow;
use crate::draw::{Draw, Head};
use crate::graph::{BendIndex, DotIndex, Ends, SegIndex, TaggedIndex};
use crate::graph::{BendWeight, DotWeight, SegWeight};
use crate::guide::Guide;
use crate::graph::{DotIndex, DotWeight, Ends};
use crate::layout::Layout;
use crate::math::Circle;
use crate::mesh::{Mesh, MeshEdgeReference, VertexIndex};
use crate::route::{Route, Trace};
use crate::rules::{Conditions, Rules};
use crate::segbend::Segbend;
use crate::rules::Rules;
use crate::tracer::{Trace, Tracer};
pub trait RouterObserver {
fn on_rework(&mut self, tracer: &Tracer, path: &[VertexIndex]);
fn on_probe(&mut self, tracer: &Tracer, edge: MeshEdgeReference);
fn on_estimate(&mut self, tracer: &Tracer, vertex: VertexIndex);
}
pub struct Router {
pub layout: Layout,
rules: Rules,
}
pub trait RouteStrategy {
fn route_cost(&mut self, route: &Route, path: &[VertexIndex]) -> u64;
fn edge_cost(&mut self, route: &Route, edge: MeshEdgeReference) -> u64;
fn estimate_cost(&mut self, route: &Route, vertex: VertexIndex) -> u64;
}
pub struct DefaultRouteStrategy {}
impl DefaultRouteStrategy {
pub fn new() -> Self {
Self {}
}
}
impl RouteStrategy for DefaultRouteStrategy {
fn route_cost(&mut self, route: &Route, path: &[VertexIndex]) -> u64 {
0
}
fn edge_cost(&mut self, route: &Route, edge: MeshEdgeReference) -> u64 {
1
}
fn estimate_cost(&mut self, route: &Route, vertex: VertexIndex) -> u64 {
0
}
}
struct RouterAstarStrategy<'a, RS: RouteStrategy> {
route: Route<'a>,
struct RouterAstarStrategy<'a, RO: RouterObserver> {
tracer: Tracer<'a>,
trace: Trace,
to: VertexIndex,
strategy: &'a mut RS,
observer: &'a mut RO,
}
impl<'a, RS: RouteStrategy> RouterAstarStrategy<'a, RS> {
pub fn new(route: Route<'a>, trace: Trace, to: VertexIndex, strategy: &'a mut RS) -> Self {
impl<'a, RO: RouterObserver> RouterAstarStrategy<'a, RO> {
pub fn new(tracer: Tracer<'a>, trace: Trace, to: VertexIndex, observer: &'a mut RO) -> Self {
Self {
route,
tracer,
trace,
to,
strategy,
observer,
}
}
}
impl<'a, RS: RouteStrategy> AstarStrategy<&Mesh, u64> for RouterAstarStrategy<'a, RS> {
fn reroute(&mut self, vertex: VertexIndex, tracker: &PathTracker<&Mesh>) -> Option<u64> {
impl<'a, RO: RouterObserver> AstarStrategy<&Mesh, u64> for RouterAstarStrategy<'a, RO> {
fn is_goal(&mut self, vertex: VertexIndex, tracker: &PathTracker<&Mesh>) -> bool {
let new_path = tracker.reconstruct_path_to(vertex);
self.route.rework_path(&mut self.trace, &new_path, 5.0);
self.tracer.rework_path(&mut self.trace, &new_path, 5.0);
self.observer.on_rework(&self.tracer, &new_path);
if self.route.finish(&mut self.trace, self.to, 5.0).is_ok() {
return None;
}
Some(self.strategy.route_cost(&self.route, &new_path))
self.tracer.finish(&mut self.trace, self.to, 5.0).is_ok()
}
fn edge_cost(&mut self, edge: MeshEdgeReference) -> u64 {
self.strategy.edge_cost(&self.route, edge)
self.observer.on_probe(&self.tracer, edge);
1
}
fn estimate_cost(&mut self, vertex: VertexIndex) -> u64 {
self.strategy.estimate_cost(&self.route, vertex)
self.observer.on_estimate(&self.tracer, vertex);
0
}
}
@ -101,7 +73,7 @@ impl Router {
&mut self,
from: DotIndex,
to: DotIndex,
strategy: &mut impl RouteStrategy,
observer: &mut impl RouterObserver,
) -> Result<Mesh, InsertionError> {
// XXX: Should we actually store the mesh? May be useful for debugging, but doesn't look
// right.
@ -109,13 +81,13 @@ impl Router {
let mut mesh = Mesh::new();
mesh.triangulate(&self.layout)?;
let mut route = self.route(&mesh);
let trace = route.start(mesh.vertex(from));
let mut tracer = self.tracer(&mesh);
let trace = tracer.start(mesh.vertex(from));
let (_cost, path) = astar(
&mesh,
mesh.vertex(from),
&mut RouterAstarStrategy::new(route, trace, mesh.vertex(to), strategy),
&mut RouterAstarStrategy::new(tracer, trace, mesh.vertex(to), observer),
)
.unwrap(); // TODO.
@ -126,7 +98,7 @@ impl Router {
&mut self,
from: DotIndex,
to: Point,
strategy: &mut impl RouteStrategy,
observer: &mut impl RouterObserver,
) -> Result<Mesh, InsertionError> {
let to_dot = if let Some(band) = self.layout.next_band(from) {
let to_dot = band.ends().1;
@ -144,7 +116,7 @@ impl Router {
.unwrap() // TODO.
};
self.enroute(from, to_dot, strategy)
self.enroute(from, to_dot, observer)
}
/*pub fn squeeze_around_dot(
@ -259,8 +231,8 @@ impl Router {
Ok(())
}*/
pub fn route<'a>(&'a mut self, mesh: &'a Mesh) -> Route {
Route::new(&mut self.layout, &self.rules, mesh)
pub fn tracer<'a>(&'a mut self, mesh: &'a Mesh) -> Tracer {
Tracer::new(&mut self.layout, &self.rules, mesh)
}
/*pub fn routeedges(&self) -> impl Iterator<Item = (Point, Point)> + '_ {

View File

@ -3,7 +3,7 @@ use contracts::debug_ensures;
use crate::{
draw::{BareHead, Draw, Head},
layout::Layout,
mesh::{Mesh, VertexIndex},
mesh::{Mesh, MeshEdgeReference, VertexIndex},
rules::Rules,
};
@ -13,15 +13,15 @@ pub struct Trace {
head: Head,
}
pub struct Route<'a> {
pub struct Tracer<'a> {
pub layout: &'a mut Layout,
pub rules: &'a Rules,
pub mesh: &'a Mesh,
}
impl<'a> Route<'a> {
impl<'a> Tracer<'a> {
pub fn new(layout: &'a mut Layout, rules: &'a Rules, mesh: &'a Mesh) -> Self {
Route {
Tracer {
layout,
rules,
mesh,