diff --git a/src/router/navcord.rs b/src/router/navcord.rs index 83c5d79..978f2a9 100644 --- a/src/router/navcord.rs +++ b/src/router/navcord.rs @@ -20,13 +20,18 @@ use super::{ navmesh::{BinavvertexNodeIndex, Navmesh, NavvertexIndex}, }; -/// The navcord is a structure that holds the movable non-borrowing -/// data of the currently running routing process. +/// The navcord is a data structure that holds the movable non-borrowing data of +/// the currently running routing process. +/// +/// Note that this data structure is not a stepper, since steppers always +/// progress linearly, whereas `Navcord` branches out to different states +/// depending on the value of the `to` argument of the `.step_to(...)` method. /// /// The name "navcord" is a shortening of "navigation cord", by analogy to /// "navmesh" being a shortening of "navigation mesh". #[derive(Debug)] pub struct Navcord { + /// The layout edit which we are currently recording. pub recorder: LayoutEdit, /// The currently attempted path. pub path: Vec, @@ -37,7 +42,7 @@ pub struct Navcord { } impl Navcord { - /// Creates a new navcord. + /// Create a new navcord. pub fn new( recorder: LayoutEdit, source: FixedDotIndex, @@ -52,6 +57,7 @@ impl Navcord { } } + /// From the current head `head` wrap a new head around the navvertex `around`. fn wrap( &mut self, layout: &mut Layout, @@ -86,6 +92,8 @@ impl Navcord { .map_err(NavcorderException::CannotDraw) } + /// Advance the navcord and the currently routed band by one step to the + /// navvertex `to`. #[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()))] @@ -96,11 +104,17 @@ impl Navcord { to: NavvertexIndex, ) -> Result<(), NavcorderException> { self.head = self.wrap(layout, navmesh, self.head, to)?.into(); + + // Now that the new head has been created, push the navvertex + // `to` onto the currently attempted path to start from it on + // the next `.step_to(...)` call or retreat from it later using + // `.step_back(...)`. self.path.push(to); Ok(()) } + /// Retreat the navcord and the currently routed band by one step. #[debug_ensures(self.path.len() == old(self.path.len() - 1))] pub fn step_back( &mut self, @@ -113,6 +127,9 @@ impl Navcord { return Err(NavcorderException::CannotWrap); } + // Now that the last head of the currently routed band was deleted, pop + // the last navvertex from the currently attempted path so that it is up + // to date. self.path.pop(); Ok(()) } diff --git a/src/stepper.rs b/src/stepper.rs index 4b15931..f4a6df0 100644 --- a/src/stepper.rs +++ b/src/stepper.rs @@ -4,11 +4,31 @@ use std::ops::ControlFlow; +/// This trait represents a linearly advanceable state whose advancement may +/// break or fail with many different return values, and to which part of +/// the information, called the context, has to be supplied on each call as a +/// mutable reference argument. +/// +/// An object that implements this trait is called a "stepper". +/// +/// Steppers always progress linearly, that is, it is presumed that the context +/// does not change between calls in a way that can affect the stepper's future +/// states. Advanceable data structures designed for uses where the future state +/// intentionally *may* change from the information supplied as arguments are +/// not considered steppers. An example of such an advanceable non-stepper is +/// the [`navcord::Navcord`] struct, as it does not progress linearly because +/// it branches out by on each call taking in a changeable `to` argument that +/// affects the future states. +/// +/// Petgraph's counterpart of this trait is its +/// [`petgraph::visit::Walker`] trait. pub trait Step { type Error; + /// Advance the stepper's state by one step. fn step(&mut self, context: &mut Ctx) -> Result, Self::Error>; + /// Advance the stepper step-by-step in a loop until it fails or breaks. fn finish(&mut self, context: &mut Ctx) -> Result { loop { if let ControlFlow::Break(outcome) = self.step(context)? { @@ -18,10 +38,17 @@ pub trait Step { } } +/// Steppers that may be stepped backwards implement this trait. pub trait StepBack { + /// Retreat the stepper's state by one step. fn step_back(&mut self, context: &mut C) -> Result; } +/// Steppers that may be aborted implement this trait. +/// +/// Aborting a stepper puts it in a state where stepping or stepping back always +/// fails. pub trait Abort { + /// Abort the stepper. fn abort(&mut self, context: &mut C); }