From 783080683459e4a6b1a52f5efe453fea33ddc6b4 Mon Sep 17 00:00:00 2001 From: Mikolaj Wielgus Date: Sat, 3 Aug 2024 19:17:00 +0200 Subject: [PATCH] router: use `Step` and new `StepBack` traits in `Route` and `Trace` --- src/router/route.rs | 40 ++++++++++----------- src/router/router.rs | 20 ++++++++--- src/router/trace.rs | 86 +++++++++++++++++++++++++++----------------- src/router/tracer.rs | 32 +++++++++++++---- src/step.rs | 8 +++-- 5 files changed, 120 insertions(+), 66 deletions(-) diff --git a/src/router/route.rs b/src/router/route.rs index ccf8754..091a8f8 100644 --- a/src/router/route.rs +++ b/src/router/route.rs @@ -8,6 +8,7 @@ use crate::{ tracer::Tracer, Router, RouterAstarStrategy, RouterError, RouterStatus, }, + step::Step, }; pub struct Route { @@ -53,26 +54,6 @@ impl Route { } } - pub fn step( - &mut self, - router: &mut Router, - ) -> Result { - let tracer = Tracer::new(router.layout_mut()); - let target = self.astar.graph.destination(); - let mut strategy = RouterAstarStrategy::new(tracer, &mut self.trace, target); - - let result = match self.astar.step(&mut strategy)? { - AstarStatus::Probing | AstarStatus::Probed | AstarStatus::Visited => { - Ok(RouterStatus::Running) - } - AstarStatus::Finished(_cost, _path, band) => Ok(RouterStatus::Finished(band)), - }; - - self.ghosts = strategy.probe_ghosts; - self.obstacles = strategy.probe_obstacles; - result - } - pub fn navmesh(&self) -> &Navmesh { &self.astar.graph } @@ -89,3 +70,22 @@ impl Route { &self.obstacles } } + +impl<'a, R: AccessRules> Step, RouterStatus, RouterError> for Route { + fn step(&mut self, router: &mut Router) -> Result { + let tracer = Tracer::new(router.layout_mut()); + let target = self.astar.graph.destination(); + let mut strategy = RouterAstarStrategy::new(tracer, &mut self.trace, target); + + let result = match self.astar.step(&mut strategy)? { + AstarStatus::Probing | AstarStatus::Probed | AstarStatus::Visited => { + Ok(RouterStatus::Running) + } + AstarStatus::Finished(_cost, _path, band) => Ok(RouterStatus::Finished(band)), + }; + + self.ghosts = strategy.probe_ghosts; + self.obstacles = strategy.probe_obstacles; + result + } +} diff --git a/src/router/router.rs b/src/router/router.rs index 753c5f3..1e39cd9 100644 --- a/src/router/router.rs +++ b/src/router/router.rs @@ -18,6 +18,7 @@ use crate::{ }, graph::{GetPetgraphIndex, MakeRef}, layout::Layout, + step::{IsFinished, Step, StepBack}, }; use super::{ @@ -25,7 +26,7 @@ use super::{ draw::DrawException, navmesh::{Navmesh, NavmeshEdgeReference, NavmeshError, NavvertexIndex}, route::Route, - trace::Trace, + trace::{Trace, TraceStepInput}, tracer::{Tracer, TracerException}, }; @@ -42,6 +43,12 @@ pub enum RouterStatus { Finished(BandTermsegIndex), } +impl IsFinished for RouterStatus { + fn finished(&self) -> bool { + matches!(self, RouterStatus::Finished(..)) + } +} + #[derive(Debug)] pub struct RouterAstarStrategy<'a, R: AccessRules> { pub tracer: Tracer<'a, R>, @@ -107,9 +114,12 @@ impl<'a, R: AccessRules> AstarStrategy let prev_bihead_length = self.bihead_length(); let width = self.trace.width; - let result = self - .trace - .step(&mut self.tracer, navmesh, edge.target(), width); + let result = self.trace.step(&mut TraceStepInput { + tracer: &mut self.tracer, + navmesh, + to: edge.target(), + width, + }); let probe_length = self.bihead_length() - prev_bihead_length; @@ -141,7 +151,7 @@ impl<'a, R: AccessRules> AstarStrategy } fn remove_probe(&mut self, _navmesh: &Navmesh) { - self.trace.undo_step(&mut self.tracer); + self.trace.step_back(&mut self.tracer); } fn estimate_cost(&mut self, navmesh: &Navmesh, vertex: NavvertexIndex) -> f64 { diff --git a/src/router/trace.rs b/src/router/trace.rs index 126cd82..09d7fb0 100644 --- a/src/router/trace.rs +++ b/src/router/trace.rs @@ -9,11 +9,14 @@ use crate::{ head::{BareHead, CaneHead, Head}, rules::AccessRules, }, - router::{ - draw::Draw, - navmesh::{BinavvertexNodeIndex, Navmesh, NavvertexIndex}, - tracer::{Tracer, TracerException}, - }, + step::{Step, StepBack}, +}; + +use super::{ + draw::Draw, + navmesh::{BinavvertexNodeIndex, Navmesh, NavvertexIndex}, + tracer::TracerStatus, + tracer::{Tracer, TracerException}, }; #[derive(Debug)] @@ -32,33 +35,6 @@ impl Trace { } } - #[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( - &mut self, - tracer: &mut Tracer, - navmesh: &Navmesh, - to: NavvertexIndex, - width: f64, - ) -> Result<(), TracerException> { - self.head = self.wrap(tracer, navmesh, self.head, to, width)?.into(); - self.path.push(to); - - Ok::<(), TracerException>(()) - } - - #[debug_ensures(self.path.len() == old(self.path.len() - 1))] - pub fn undo_step(&mut self, tracer: &mut Tracer) { - if let Head::Cane(head) = self.head { - self.head = Draw::new(tracer.layout).undo_cane(head).unwrap(); - } else { - panic!(); - } - - self.path.pop(); - } - fn wrap( &mut self, tracer: &mut Tracer, @@ -116,3 +92,49 @@ impl Trace { navmesh.node_weight(navvertex).unwrap().maybe_cw } } + +pub struct TraceStepInput<'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, TracerStatus, TracerException> + for Trace +{ + #[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()))] + fn step( + &mut self, + input: &mut TraceStepInput<'a, 'b, R>, + ) -> Result { + self.head = self + .wrap( + input.tracer, + input.navmesh, + self.head, + input.to, + input.width, + )? + .into(); + self.path.push(input.to); + + Ok(TracerStatus::Running) + } +} + +impl<'a, R: AccessRules> StepBack, TracerStatus, TracerException> for Trace { + #[debug_ensures(self.path.len() == old(self.path.len() - 1))] + fn step_back(&mut self, tracer: &mut Tracer<'a, R>) -> Result { + if let Head::Cane(head) = self.head { + self.head = Draw::new(tracer.layout).undo_cane(head).unwrap(); + } else { + panic!(); + } + + self.path.pop(); + Ok(TracerStatus::Running) + } +} diff --git a/src/router/tracer.rs b/src/router/tracer.rs index 8165871..e9c13c2 100644 --- a/src/router/tracer.rs +++ b/src/router/tracer.rs @@ -4,11 +4,13 @@ use thiserror::Error; use crate::{ drawing::{band::BandTermsegIndex, dot::FixedDotIndex, rules::AccessRules}, layout::Layout, - router::{ - draw::{Draw, DrawException}, - navmesh::{Navmesh, NavvertexIndex}, - trace::Trace, - }, + step::{IsFinished, Step, StepBack}, +}; + +use super::{ + draw::{Draw, DrawException}, + navmesh::{Navmesh, NavvertexIndex}, + trace::{Trace, TraceStepInput}, }; #[derive(Error, Debug, Clone, Copy)] @@ -19,6 +21,17 @@ pub enum TracerException { CannotWrap, } +pub enum TracerStatus { + Running, + Finished, +} + +impl IsFinished for TracerStatus { + fn finished(&self) -> bool { + matches!(self, TracerStatus::Finished) + } +} + #[derive(Debug)] pub struct Tracer<'a, R: AccessRules> { pub layout: &'a mut Layout, @@ -78,7 +91,12 @@ impl<'a, R: AccessRules> Tracer<'a, R> { width: f64, ) -> Result<(), TracerException> { for (i, vertex) in path.iter().enumerate() { - if let Err(err) = trace.step(self, navmesh, *vertex, width) { + if let Err(err) = trace.step(&mut TraceStepInput { + tracer: self, + navmesh, + to: *vertex, + width, + }) { self.undo_path(trace, i); return Err(err.into()); } @@ -90,7 +108,7 @@ impl<'a, R: AccessRules> Tracer<'a, R> { #[debug_ensures(trace.path.len() == old(trace.path.len() - step_count))] pub fn undo_path(&mut self, trace: &mut Trace, step_count: usize) { for _ in 0..step_count { - trace.undo_step(self); + let _ = trace.step_back(self); } } } diff --git a/src/step.rs b/src/step.rs index 09e79e2..77a7cd6 100644 --- a/src/step.rs +++ b/src/step.rs @@ -2,6 +2,10 @@ pub trait IsFinished { fn finished(&self) -> bool; } -pub trait Step { - fn step(&mut self, context: &mut C) -> Result; +pub trait Step { + fn step(&mut self, input: &mut I) -> Result; +} + +pub trait StepBack { + fn step_back(&mut self, input: &mut I) -> Result; }