From c2daf9fbfe91f56cb8dd2dc6a4d015a23a8b5233 Mon Sep 17 00:00:00 2001 From: Mikolaj Wielgus Date: Tue, 3 Dec 2024 08:35:11 +0100 Subject: [PATCH] feat(autorouter): use recorded edit applying for undo/redo --- src/autorouter/invoker.rs | 34 +++++++---------------- src/geometry/edit.rs | 30 +++++++++++++++++++++ src/geometry/recording_with_rtree.rs | 40 +++++++++++++++++----------- 3 files changed, 63 insertions(+), 41 deletions(-) diff --git a/src/autorouter/invoker.rs b/src/autorouter/invoker.rs index ad67bd6..5f07274 100644 --- a/src/autorouter/invoker.rs +++ b/src/autorouter/invoker.rs @@ -10,7 +10,7 @@ use thiserror::Error; use crate::{ board::mesadata::AccessMesadata, drawing::graph::PrimitiveIndex, - geometry::primitive::PrimitiveShape, + geometry::{edit::ApplyGeometryEdit, primitive::PrimitiveShape}, router::{navcord::NavcordStepper, navmesh::Navmesh}, stepper::Step, }; @@ -172,20 +172,10 @@ impl Invoker { #[debug_requires(self.ongoing_command.is_none())] /// Undo last command pub fn undo(&mut self) -> Result<(), InvokerError> { - let command = self.history.last_done()?.command(); + let last_done = self.history.last_done()?; - match command { - Command::Autoroute(ref selection, ..) => { - self.autorouter.undo_autoroute(selection)?; - } - Command::PlaceVia(weight) => { - self.autorouter.undo_place_via(*weight); - } - Command::RemoveBands(ref selection) => { - self.autorouter.undo_remove_bands(selection); - } - Command::CompareDetours(..) => {} - Command::MeasureLength(..) => {} + if let Some(edit) = last_done.edit() { + self.autorouter.board.apply(edit.reverse()); } Ok(self.history.undo()?) @@ -194,19 +184,13 @@ impl Invoker { //#[debug_requires(self.ongoing_command.is_none())] /// Redo last command pub fn redo(&mut self) -> Result<(), InvokerError> { - let command = self.history.last_undone()?.command().clone(); - let mut execute = self.execute_stepper(command)?; + let last_undone = self.history.last_undone()?; - loop { - let status = match execute.step(self) { - Ok(status) => status, - Err(err) => return Err(err), - }; - - if let ControlFlow::Break(..) = status { - return Ok(self.history.redo()?); - } + if let Some(edit) = last_undone.edit() { + self.autorouter.board.apply(edit.clone()); } + + Ok(self.history.redo()?) } #[debug_requires(self.ongoing_command.is_none())] diff --git a/src/geometry/edit.rs b/src/geometry/edit.rs index 0ff4308..d83cd9f 100644 --- a/src/geometry/edit.rs +++ b/src/geometry/edit.rs @@ -62,4 +62,34 @@ impl< primitive_weight_marker: PhantomData, } } + + pub fn reverse(&self) -> Self { + Self { + dots: self + .dots + .clone() + .into_iter() + .map(|(k, v)| (k, (v.1, v.0))) + .collect(), + segs: self + .segs + .clone() + .into_iter() + .map(|(k, v)| (k, (v.1, v.0))) + .collect(), + bends: self + .bends + .clone() + .into_iter() + .map(|(k, v)| (k, (v.1, v.0))) + .collect(), + compounds: self + .compounds + .clone() + .into_iter() + .map(|(k, v)| (k, (v.1, v.0))) + .collect(), + primitive_weight_marker: PhantomData, + } + } } diff --git a/src/geometry/recording_with_rtree.rs b/src/geometry/recording_with_rtree.rs index ad3bb35..4605955 100644 --- a/src/geometry/recording_with_rtree.rs +++ b/src/geometry/recording_with_rtree.rs @@ -396,44 +396,52 @@ impl< for RecordingGeometryWithRtree { fn apply(&mut self, edit: GeometryEdit) { - for (compound, ..) in &edit.compounds { - self.geometry_with_rtree.remove_compound(*compound); + for (compound, (maybe_old_data, ..)) in &edit.compounds { + if maybe_old_data.is_some() { + self.geometry_with_rtree.remove_compound(*compound); + } } - for (bend, ..) in &edit.bends { - self.geometry_with_rtree.remove_bend(*bend); + for (bend, (maybe_old_data, ..)) in &edit.bends { + if maybe_old_data.is_some() { + self.geometry_with_rtree.remove_bend(*bend); + } } - for (seg, ..) in &edit.segs { - self.geometry_with_rtree.remove_seg(*seg); + for (seg, (maybe_old_data, ..)) in &edit.segs { + if maybe_old_data.is_some() { + self.geometry_with_rtree.remove_seg(*seg); + } } - for (dot, ..) in &edit.dots { - self.geometry_with_rtree.remove_dot(*dot); + for (dot, (maybe_old_data, ..)) in &edit.dots { + if maybe_old_data.is_some() { + self.geometry_with_rtree.remove_dot(*dot); + } } - for (dot, (.., maybe_weight)) in &edit.dots { - if let Some(weight) = maybe_weight { + for (dot, (.., maybe_new_data)) in &edit.dots { + if let Some(weight) = maybe_new_data { self.geometry_with_rtree.add_dot_at_index(*dot, *weight); } } - for (seg, (.., maybe_data)) in &edit.segs { - if let Some(((from, to), weight)) = maybe_data { + for (seg, (.., maybe_new_data)) in &edit.segs { + if let Some(((from, to), weight)) = maybe_new_data { self.geometry_with_rtree .add_seg_at_index(*seg, *from, *to, *weight); } } - for (bend, (.., maybe_data)) in &edit.bends { - if let Some(((from, to, core), weight)) = maybe_data { + for (bend, (.., maybe_new_data)) in &edit.bends { + if let Some(((from, to, core), weight)) = maybe_new_data { self.geometry_with_rtree .add_bend_at_index(*bend, *from, *to, *core, *weight); } } - for (compound, (.., maybe_data)) in &edit.compounds { - if let Some((members, weight)) = maybe_data { + for (compound, (.., maybe_new_data)) in &edit.compounds { + if let Some((members, weight)) = maybe_new_data { self.geometry_with_rtree .add_compound_at_index(*compound, *weight);