mirror of https://codeberg.org/topola/topola.git
refactor(router::navcorder): turn Navcorder into a trait
This commit is contained in:
parent
1d11011133
commit
90544c12ed
|
|
@ -13,12 +13,12 @@ use crate::{
|
|||
head::{BareHead, CaneHead, Head},
|
||||
rules::AccessRules,
|
||||
},
|
||||
layout::LayoutEdit,
|
||||
layout::{Layout, LayoutEdit},
|
||||
};
|
||||
|
||||
use super::{
|
||||
draw::Draw,
|
||||
navcorder::{Navcorder, NavcorderException},
|
||||
navcorder::NavcorderException,
|
||||
navmesh::{BinavvertexNodeIndex, Navmesh, NavvertexIndex},
|
||||
};
|
||||
|
||||
|
|
@ -56,7 +56,7 @@ impl NavcordStepper {
|
|||
|
||||
fn wrap(
|
||||
&mut self,
|
||||
navcorder: &mut Navcorder<impl AccessRules>,
|
||||
layout: &mut Layout<impl AccessRules>,
|
||||
navmesh: &Navmesh,
|
||||
head: Head,
|
||||
around: NavvertexIndex,
|
||||
|
|
@ -68,39 +68,35 @@ impl NavcordStepper {
|
|||
|
||||
match self.binavvertex(navmesh, around) {
|
||||
BinavvertexNodeIndex::FixedDot(dot) => {
|
||||
self.wrap_around_fixed_dot(navcorder, head, dot, cw, width)
|
||||
self.wrap_around_fixed_dot(layout, head, dot, cw, width)
|
||||
}
|
||||
BinavvertexNodeIndex::FixedBend(_fixed_bend) => todo!(),
|
||||
BinavvertexNodeIndex::LooseBend(loose_bend) => {
|
||||
self.wrap_around_loose_bend(navcorder, head, loose_bend, cw, width)
|
||||
self.wrap_around_loose_bend(layout, head, loose_bend, cw, width)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn wrap_around_fixed_dot(
|
||||
&mut self,
|
||||
navcorder: &mut Navcorder<impl AccessRules>,
|
||||
layout: &mut Layout<impl AccessRules>,
|
||||
head: Head,
|
||||
around: FixedDotIndex,
|
||||
cw: bool,
|
||||
width: f64,
|
||||
) -> Result<CaneHead, NavcorderException> {
|
||||
Ok(navcorder
|
||||
.layout
|
||||
.cane_around_dot(&mut self.recorder, head, around, cw, width)?)
|
||||
Ok(layout.cane_around_dot(&mut self.recorder, head, around, cw, width)?)
|
||||
}
|
||||
|
||||
fn wrap_around_loose_bend(
|
||||
&mut self,
|
||||
navcorder: &mut Navcorder<impl AccessRules>,
|
||||
layout: &mut Layout<impl AccessRules>,
|
||||
head: Head,
|
||||
around: LooseBendIndex,
|
||||
cw: bool,
|
||||
width: f64,
|
||||
) -> Result<CaneHead, NavcorderException> {
|
||||
Ok(navcorder
|
||||
.layout
|
||||
.cane_around_bend(&mut self.recorder, head, around.into(), cw, width)?)
|
||||
Ok(layout.cane_around_bend(&mut self.recorder, head, around.into(), cw, width)?)
|
||||
}
|
||||
|
||||
fn binavvertex(&self, navmesh: &Navmesh, navvertex: NavvertexIndex) -> BinavvertexNodeIndex {
|
||||
|
|
@ -116,9 +112,9 @@ impl NavcordStepper {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct NavcordStepContext<'a: 'b, 'b, R> {
|
||||
pub navcorder: &'b mut Navcorder<'a, R>,
|
||||
pub navmesh: &'b Navmesh,
|
||||
pub struct NavcordStepContext<'a, R> {
|
||||
pub layout: &'a mut Layout<R>,
|
||||
pub navmesh: &'a Navmesh,
|
||||
pub to: NavvertexIndex,
|
||||
pub width: f64,
|
||||
}
|
||||
|
|
@ -127,13 +123,13 @@ impl NavcordStepper {
|
|||
#[debug_ensures(ret.is_ok() -> matches!(self.head, Head::Cane(..)))]
|
||||
#[debug_ensures(ret.is_ok() -> self.path.len() == old(self.path.len() + 1))]
|
||||
#[debug_ensures(ret.is_err() -> self.path.len() == old(self.path.len()))]
|
||||
pub fn step<'a, 'b, R: AccessRules>(
|
||||
pub fn step<R: AccessRules>(
|
||||
&mut self,
|
||||
input: &mut NavcordStepContext<'a, 'b, R>,
|
||||
input: &mut NavcordStepContext<'_, R>,
|
||||
) -> Result<(), NavcorderException> {
|
||||
self.head = self
|
||||
.wrap(
|
||||
input.navcorder,
|
||||
input.layout,
|
||||
input.navmesh,
|
||||
self.head,
|
||||
input.to,
|
||||
|
|
@ -146,15 +142,12 @@ impl NavcordStepper {
|
|||
}
|
||||
|
||||
#[debug_ensures(self.path.len() == old(self.path.len() - 1))]
|
||||
pub fn step_back<'a, R: AccessRules>(
|
||||
pub fn step_back<R: AccessRules>(
|
||||
&mut self,
|
||||
navcorder: &mut Navcorder<'a, R>,
|
||||
layout: &mut Layout<R>,
|
||||
) -> Result<(), NavcorderException> {
|
||||
if let Head::Cane(head) = self.head {
|
||||
self.head = navcorder
|
||||
.layout
|
||||
.undo_cane(&mut self.recorder, head)
|
||||
.unwrap();
|
||||
self.head = layout.undo_cane(&mut self.recorder, head).unwrap();
|
||||
} else {
|
||||
panic!();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,19 +24,44 @@ pub enum NavcorderException {
|
|||
CannotWrap,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Navcorder<'a, R> {
|
||||
pub layout: &'a mut Layout<R>,
|
||||
pub trait Navcorder {
|
||||
fn start(
|
||||
&mut self,
|
||||
recorder: LayoutEdit,
|
||||
source: FixedDotIndex,
|
||||
source_navvertex: NavvertexIndex,
|
||||
width: f64,
|
||||
) -> NavcordStepper;
|
||||
|
||||
fn finish(
|
||||
&mut self,
|
||||
_navmesh: &Navmesh,
|
||||
navcord: &mut NavcordStepper,
|
||||
target: FixedDotIndex,
|
||||
width: f64,
|
||||
) -> Result<BandTermsegIndex, NavcorderException>;
|
||||
|
||||
fn rework_path(
|
||||
&mut self,
|
||||
navmesh: &Navmesh,
|
||||
navcord: &mut NavcordStepper,
|
||||
path: &[NavvertexIndex],
|
||||
width: f64,
|
||||
) -> Result<(), NavcorderException>;
|
||||
|
||||
fn path(
|
||||
&mut self,
|
||||
navmesh: &Navmesh,
|
||||
navcord: &mut NavcordStepper,
|
||||
path: &[NavvertexIndex],
|
||||
width: f64,
|
||||
) -> Result<(), NavcorderException>;
|
||||
|
||||
fn undo_path(&mut self, navcord: &mut NavcordStepper, step_count: usize);
|
||||
}
|
||||
|
||||
impl<'a, R> Navcorder<'a, R> {
|
||||
pub fn new(layout: &mut Layout<R>) -> Navcorder<R> {
|
||||
Navcorder { layout }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, R: AccessRules> Navcorder<'a, R> {
|
||||
pub fn start(
|
||||
impl<R: AccessRules> Navcorder for Layout<R> {
|
||||
fn start(
|
||||
&mut self,
|
||||
recorder: LayoutEdit,
|
||||
source: FixedDotIndex,
|
||||
|
|
@ -46,21 +71,19 @@ impl<'a, R: AccessRules> Navcorder<'a, R> {
|
|||
NavcordStepper::new(recorder, source, source_navvertex, width)
|
||||
}
|
||||
|
||||
pub fn finish(
|
||||
fn finish(
|
||||
&mut self,
|
||||
_navmesh: &Navmesh,
|
||||
navcord: &mut NavcordStepper,
|
||||
target: FixedDotIndex,
|
||||
width: f64,
|
||||
) -> Result<BandTermsegIndex, NavcorderException> {
|
||||
Ok(self
|
||||
.layout
|
||||
.finish_in_dot(&mut navcord.recorder, navcord.head, target, width)?)
|
||||
Ok(self.finish_in_dot(&mut navcord.recorder, navcord.head, target, width)?)
|
||||
}
|
||||
|
||||
#[debug_requires(path[0] == navcord.path[0])]
|
||||
#[debug_ensures(ret.is_ok() -> navcord.path.len() == path.len())]
|
||||
pub fn rework_path(
|
||||
fn rework_path(
|
||||
&mut self,
|
||||
navmesh: &Navmesh,
|
||||
navcord: &mut NavcordStepper,
|
||||
|
|
@ -80,7 +103,7 @@ impl<'a, R: AccessRules> Navcorder<'a, R> {
|
|||
}
|
||||
|
||||
#[debug_ensures(ret.is_ok() -> navcord.path.len() == old(navcord.path.len() + path.len()))]
|
||||
pub fn path(
|
||||
fn path(
|
||||
&mut self,
|
||||
navmesh: &Navmesh,
|
||||
navcord: &mut NavcordStepper,
|
||||
|
|
@ -89,7 +112,7 @@ impl<'a, R: AccessRules> Navcorder<'a, R> {
|
|||
) -> Result<(), NavcorderException> {
|
||||
for (i, vertex) in path.iter().enumerate() {
|
||||
if let Err(err) = navcord.step(&mut NavcordStepContext {
|
||||
navcorder: self,
|
||||
layout: self,
|
||||
navmesh,
|
||||
to: *vertex,
|
||||
width,
|
||||
|
|
@ -103,7 +126,7 @@ impl<'a, R: AccessRules> Navcorder<'a, R> {
|
|||
}
|
||||
|
||||
#[debug_ensures(navcord.path.len() == old(navcord.path.len() - step_count))]
|
||||
pub fn undo_path(&mut self, navcord: &mut NavcordStepper, step_count: usize) {
|
||||
fn undo_path(&mut self, navcord: &mut NavcordStepper, step_count: usize) {
|
||||
for _ in 0..step_count {
|
||||
let _ = navcord.step_back(self);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,10 +53,10 @@ impl RouteStepper {
|
|||
let source_navvertex = navmesh.origin_navvertex();
|
||||
let target = navmesh.destination();
|
||||
|
||||
let mut navcorder = Navcorder::new(router.layout_mut());
|
||||
let mut navcord = navcorder.start(recorder, source, source_navvertex, width);
|
||||
let layout = router.layout_mut();
|
||||
let mut navcord = layout.start(recorder, source, source_navvertex, width);
|
||||
|
||||
let mut strategy = RouterAstarStrategy::new(navcorder, &mut navcord, target);
|
||||
let mut strategy = RouterAstarStrategy::new(layout, &mut navcord, target);
|
||||
let astar = Astar::new(navmesh, source_navvertex, &mut strategy);
|
||||
let ghosts = vec![];
|
||||
let obstacles = vec![];
|
||||
|
|
@ -81,9 +81,9 @@ impl<'a, R: AccessRules> Step<Router<'a, R>, BandTermsegIndex> for RouteStepper
|
|||
&mut self,
|
||||
router: &mut Router<R>,
|
||||
) -> Result<ControlFlow<BandTermsegIndex>, AstarError> {
|
||||
let navcorder = Navcorder::new(router.layout_mut());
|
||||
let layout = router.layout_mut();
|
||||
let target = self.astar.graph.destination();
|
||||
let mut strategy = RouterAstarStrategy::new(navcorder, &mut self.navcord, target);
|
||||
let mut strategy = RouterAstarStrategy::new(layout, &mut self.navcord, target);
|
||||
|
||||
let result = match self.astar.step(&mut strategy)? {
|
||||
ControlFlow::Continue(..) => Ok(ControlFlow::Continue(())),
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ pub struct RouterOptions {
|
|||
|
||||
#[derive(Debug)]
|
||||
pub struct RouterAstarStrategy<'a, R> {
|
||||
pub navcorder: Navcorder<'a, R>,
|
||||
pub layout: &'a mut Layout<R>,
|
||||
pub navcord: &'a mut NavcordStepper,
|
||||
pub target: FixedDotIndex,
|
||||
pub probe_ghosts: Vec<PrimitiveShape>,
|
||||
|
|
@ -52,12 +52,12 @@ pub struct RouterAstarStrategy<'a, R> {
|
|||
|
||||
impl<'a, R> RouterAstarStrategy<'a, R> {
|
||||
pub fn new(
|
||||
navcorder: Navcorder<'a, R>,
|
||||
layout: &'a mut Layout<R>,
|
||||
navcord: &'a mut NavcordStepper,
|
||||
target: FixedDotIndex,
|
||||
) -> Self {
|
||||
Self {
|
||||
navcorder,
|
||||
layout,
|
||||
navcord,
|
||||
target,
|
||||
probe_ghosts: vec![],
|
||||
|
|
@ -68,19 +68,15 @@ impl<'a, R> RouterAstarStrategy<'a, R> {
|
|||
|
||||
impl<'a, R: AccessRules> RouterAstarStrategy<'a, R> {
|
||||
fn bihead_length(&self) -> f64 {
|
||||
self.navcord
|
||||
.head
|
||||
.ref_(self.navcorder.layout.drawing())
|
||||
.length()
|
||||
self.navcord.head.ref_(self.layout.drawing()).length()
|
||||
+ match self.navcord.head.face() {
|
||||
DotIndex::Fixed(..) => 0.0,
|
||||
DotIndex::Loose(face) => self
|
||||
.navcorder
|
||||
.layout
|
||||
.drawing()
|
||||
.guide()
|
||||
.rear_head(face)
|
||||
.ref_(self.navcorder.layout.drawing())
|
||||
.ref_(self.layout.drawing())
|
||||
.length(),
|
||||
}
|
||||
}
|
||||
|
|
@ -98,11 +94,11 @@ impl<'a, R: AccessRules> AstarStrategy<Navmesh, f64, BandTermsegIndex>
|
|||
let new_path = tracker.reconstruct_path_to(vertex);
|
||||
let width = self.navcord.width;
|
||||
|
||||
self.navcorder
|
||||
self.layout
|
||||
.rework_path(navmesh, self.navcord, &new_path[..], width)
|
||||
.unwrap();
|
||||
|
||||
self.navcorder
|
||||
self.layout
|
||||
.finish(navmesh, self.navcord, self.target, width)
|
||||
.ok()
|
||||
}
|
||||
|
|
@ -116,7 +112,7 @@ impl<'a, R: AccessRules> AstarStrategy<Navmesh, f64, BandTermsegIndex>
|
|||
|
||||
let width = self.navcord.width;
|
||||
let result = self.navcord.step(&mut NavcordStepContext {
|
||||
navcorder: &mut self.navcorder,
|
||||
layout: self.layout,
|
||||
navmesh,
|
||||
to: edge.target(),
|
||||
width,
|
||||
|
|
@ -154,16 +150,15 @@ impl<'a, R: AccessRules> AstarStrategy<Navmesh, f64, BandTermsegIndex>
|
|||
}
|
||||
|
||||
fn remove_probe(&mut self, _navmesh: &Navmesh) {
|
||||
self.navcord.step_back(&mut self.navcorder);
|
||||
self.navcord.step_back(&mut self.layout);
|
||||
}
|
||||
|
||||
fn estimate_cost(&mut self, navmesh: &Navmesh, vertex: NavvertexIndex) -> f64 {
|
||||
let start_point = PrimitiveIndex::from(navmesh.node_weight(vertex).unwrap().node)
|
||||
.primitive(self.navcorder.layout.drawing())
|
||||
.primitive(self.layout.drawing())
|
||||
.shape()
|
||||
.center();
|
||||
let end_point = self
|
||||
.navcorder
|
||||
.layout
|
||||
.drawing()
|
||||
.primitive(self.target)
|
||||
|
|
|
|||
Loading…
Reference in New Issue