mirror of https://codeberg.org/topola/topola.git
feat(router/navcord): Make it possible to visit leap navnodes
Closes https://codeberg.org/topola/topola/issues/121
This commit is contained in:
parent
a27b263288
commit
aef5c6471e
|
|
@ -18,7 +18,7 @@ use crate::{
|
|||
use super::{
|
||||
draw::Draw,
|
||||
navcorder::{Navcorder, NavcorderException},
|
||||
navmesh::{NavigableNodeIndex, Navmesh, NavnodeIndex},
|
||||
navmesh::{NavigableNodeIndex, Navmesh, NavnodeIndex, NavnodeWeight},
|
||||
};
|
||||
|
||||
/// The `Navcord` is a data structure that holds the movable non-borrowing data
|
||||
|
|
@ -106,17 +106,20 @@ impl Navcord {
|
|||
navmesh: &Navmesh,
|
||||
to: NavnodeIndex,
|
||||
) -> Result<(), NavcorderException> {
|
||||
if to == navmesh.destination_navnode() {
|
||||
let to_node_weight = navmesh.node_weight(to).unwrap();
|
||||
|
||||
if to == navmesh.destination_navnode() {
|
||||
let NavigableNodeIndex::FixedDot(to_dot) = to_node_weight.node() else {
|
||||
unreachable!();
|
||||
};
|
||||
|
||||
self.final_termseg = Some(layout.finish(navmesh, self, to_dot).unwrap());
|
||||
self.final_termseg = Some(layout.finish(navmesh, self, to_dot)?);
|
||||
|
||||
// NOTE: We don't update the head here because there is currently
|
||||
// no head variant that consists only of a seg, and I'm not sure if
|
||||
// there should be one.
|
||||
} else if matches!(to_node_weight, NavnodeWeight::Leap(..)) {
|
||||
// Nothing to do beyond pushing the navnode onto the path.
|
||||
} else {
|
||||
self.head = self.wrap(layout, navmesh, self.head, to)?.into();
|
||||
}
|
||||
|
|
@ -134,10 +137,15 @@ impl Navcord {
|
|||
pub fn step_back<R: AccessRules>(
|
||||
&mut self,
|
||||
layout: &mut Layout<R>,
|
||||
navmesh: &Navmesh,
|
||||
) -> Result<(), NavcorderException> {
|
||||
let last_node_weight = navmesh.node_weight(*self.path.last().unwrap());
|
||||
|
||||
if let Some(final_termseg) = self.final_termseg {
|
||||
layout.remove_termseg(&mut self.recorder, final_termseg);
|
||||
self.final_termseg = None;
|
||||
} else if matches!(last_node_weight, Some(NavnodeWeight::Leap(..))) {
|
||||
// Nothing to do beyond popping the navnode from the path.
|
||||
} else {
|
||||
if let Head::Cane(head) = self.head {
|
||||
self.head = layout.undo_cane(&mut self.recorder, head).unwrap();
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ pub trait Navcorder {
|
|||
path: &[NavnodeIndex],
|
||||
) -> Result<(), NavcorderException>;
|
||||
|
||||
fn undo_path(&mut self, navcord: &mut Navcord, step_count: usize);
|
||||
fn undo_path(&mut self, navmesh: &Navmesh, navcord: &mut Navcord, step_count: usize);
|
||||
}
|
||||
|
||||
impl<R: AccessRules> Navcorder for Layout<R> {
|
||||
|
|
@ -93,7 +93,7 @@ impl<R: AccessRules> Navcorder for Layout<R> {
|
|||
.count();
|
||||
|
||||
let length = navcord.path.len();
|
||||
self.undo_path(navcord, length - prefix_length);
|
||||
self.undo_path(navmesh, navcord, length - prefix_length);
|
||||
self.path(navmesh, navcord, &path[prefix_length..])
|
||||
}
|
||||
|
||||
|
|
@ -106,7 +106,7 @@ impl<R: AccessRules> Navcorder for Layout<R> {
|
|||
) -> Result<(), NavcorderException> {
|
||||
for (i, vertex) in path.iter().enumerate() {
|
||||
if let Err(err) = navcord.step_to(self, navmesh, *vertex) {
|
||||
self.undo_path(navcord, i);
|
||||
self.undo_path(navmesh, navcord, i);
|
||||
return Err(err);
|
||||
}
|
||||
}
|
||||
|
|
@ -115,9 +115,9 @@ impl<R: AccessRules> Navcorder for Layout<R> {
|
|||
}
|
||||
|
||||
#[debug_ensures(navcord.path.len() == old(navcord.path.len() - step_count))]
|
||||
fn undo_path(&mut self, navcord: &mut Navcord, step_count: usize) {
|
||||
fn undo_path(&mut self, navmesh: &Navmesh, navcord: &mut Navcord, step_count: usize) {
|
||||
for _ in 0..step_count {
|
||||
let _ = navcord.step_back(self);
|
||||
let _ = navcord.step_back(self, navmesh);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ impl<R: AccessRules> Step<Router<'_, R>, BandTermsegIndex> for RouteStepper {
|
|||
// NOTE(fogti): The 1 instead 0 is because the first element in the path
|
||||
// is the source navnode. See also: `NavcordStepper::new`.
|
||||
for _ in 1..self.navcord.path.len() {
|
||||
self.navcord.step_back(layout);
|
||||
self.navcord.step_back(layout, &self.astar.graph);
|
||||
}
|
||||
Err(e)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -136,8 +136,8 @@ impl<R: AccessRules> AstarStrategy<Navmesh, f64, BandTermsegIndex> for RouterAst
|
|||
}
|
||||
}
|
||||
|
||||
fn remove_probe(&mut self, _navmesh: &Navmesh) {
|
||||
self.navcord.step_back(self.layout);
|
||||
fn remove_probe(&mut self, navmesh: &Navmesh) {
|
||||
self.navcord.step_back(self.layout, navmesh);
|
||||
}
|
||||
|
||||
fn estimate_cost(&mut self, navmesh: &Navmesh, vertex: NavnodeIndex) -> f64 {
|
||||
|
|
|
|||
Loading…
Reference in New Issue