mirror of https://codeberg.org/topola/topola.git
router: use `Step` trait for `Astar` too
This commit is contained in:
parent
ece9c4aa5a
commit
43b48e78e3
|
|
@ -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(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@ use thiserror::Error;
|
|||
|
||||
use std::cmp::Ordering;
|
||||
|
||||
use crate::step::Step;
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct MinScored<K, T>(pub K, pub T);
|
||||
|
||||
|
|
@ -156,6 +158,24 @@ where
|
|||
Finished(K, Vec<G::NodeId>, R),
|
||||
}
|
||||
|
||||
impl<G, K, R> TryInto<(K, Vec<G::NodeId>, R)> for AstarStatus<G, K, R>
|
||||
where
|
||||
G: GraphBase,
|
||||
G::NodeId: Eq + Hash,
|
||||
for<'a> &'a G: IntoEdges<NodeId = G::NodeId, EdgeId = G::EdgeId> + MakeEdgeRef,
|
||||
K: Measure + Copy,
|
||||
{
|
||||
type Error = ();
|
||||
fn try_into(self) -> Result<(K, Vec<G::NodeId>, R), ()> {
|
||||
match self {
|
||||
AstarStatus::Probing => Err(()),
|
||||
AstarStatus::Probed => Err(()),
|
||||
AstarStatus::Visited => Err(()),
|
||||
AstarStatus::Finished(cost, path, result) => Ok((cost, path, result)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<G, K> Astar<G, K>
|
||||
where
|
||||
G: GraphBase,
|
||||
|
|
@ -183,11 +203,17 @@ where
|
|||
));
|
||||
this
|
||||
}
|
||||
}
|
||||
|
||||
pub fn step<R>(
|
||||
&mut self,
|
||||
strategy: &mut impl AstarStrategy<G, K, R>,
|
||||
) -> Result<AstarStatus<G, K, R>, AstarError> {
|
||||
impl<G, K, R, S: AstarStrategy<G, K, R>>
|
||||
Step<S, AstarStatus<G, K, R>, AstarError, (K, Vec<G::NodeId>, R)> for Astar<G, K>
|
||||
where
|
||||
G: GraphBase,
|
||||
G::NodeId: Eq + Hash,
|
||||
for<'a> &'a G: IntoEdges<NodeId = G::NodeId, EdgeId = G::EdgeId> + MakeEdgeRef,
|
||||
K: Measure + Copy,
|
||||
{
|
||||
fn step(&mut self, strategy: &mut S) -> Result<AstarStatus<G, K, R>, 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<G, K, R>(
|
||||
graph: G,
|
||||
start: G::NodeId,
|
||||
strategy: &mut impl AstarStrategy<G, K, R>,
|
||||
) -> Result<(K, Vec<G::NodeId>, R), AstarError>
|
||||
where
|
||||
G: GraphBase,
|
||||
G::NodeId: Eq + Hash,
|
||||
for<'a> &'a G: IntoEdges<NodeId = G::NodeId, EdgeId = G::EdgeId> + 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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<Router<'a, R>, RouterStatus, RouterError, ()> for Route {
|
||||
impl<'a, R: AccessRules> Step<Router<'a, R>, RouterStatus, RouterError, BandTermsegIndex>
|
||||
for Route
|
||||
{
|
||||
fn step(&mut self, router: &mut Router<R>) -> Result<RouterStatus, RouterError> {
|
||||
let tracer = Tracer::new(router.layout_mut());
|
||||
let target = self.astar.graph.destination();
|
||||
|
|
|
|||
|
|
@ -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<BandTermsegIndex> for RouterStatus {
|
||||
type Error = ();
|
||||
fn try_into(self) -> Result<BandTermsegIndex, ()> {
|
||||
match self {
|
||||
RouterStatus::Running => Err(()),
|
||||
RouterStatus::Finished(band_termseg) => Ok(band_termseg),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -114,7 +120,7 @@ impl<'a, R: AccessRules> AstarStrategy<Navmesh, f64, BandTermsegIndex>
|
|||
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(),
|
||||
|
|
|
|||
|
|
@ -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<TraceStepInput<'a, 'b, R>, TracerStatus, TracerException, ()>
|
||||
impl<'a, 'b, R: AccessRules> Step<TraceStepContext<'a, 'b, R>, TracerStatus, TracerException, ()>
|
||||
for Trace
|
||||
{
|
||||
#[debug_ensures(ret.is_ok() -> matches!(self.head, Head::Cane(..)))]
|
||||
|
|
@ -108,7 +108,7 @@ impl<'a, 'b, R: AccessRules> Step<TraceStepInput<'a, 'b, R>, 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<TracerStatus, TracerException> {
|
||||
self.head = self
|
||||
.wrap(
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
10
src/step.rs
10
src/step.rs
|
|
@ -1,19 +1,15 @@
|
|||
pub trait GetMaybeOutcome<O> {
|
||||
fn maybe_outcome(&self) -> Option<O>;
|
||||
}
|
||||
|
||||
pub trait Step<C, S: GetMaybeOutcome<O>, E, O> {
|
||||
pub trait Step<C, S: TryInto<O>, E, O> {
|
||||
fn step(&mut self, context: &mut C) -> Result<S, E>;
|
||||
|
||||
fn finish(&mut self, context: &mut C) -> Result<O, E> {
|
||||
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<C, S: GetMaybeOutcome<O>, E, O> {
|
||||
pub trait StepBack<C, S: TryInto<O>, E, O> {
|
||||
fn step_back(&mut self, context: &mut C) -> Result<S, E>;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue