autorouter: don't save in history until command is successfully finished

This commit is contained in:
Mikolaj Wielgus 2024-06-20 12:14:51 +02:00
parent ae2a862e0e
commit c24d748bea
1 changed files with 30 additions and 4 deletions

View File

@ -1,3 +1,4 @@
use contracts::debug_requires;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use thiserror::Error; use thiserror::Error;
@ -41,6 +42,23 @@ impl Execute {
pub fn step<M: MesadataTrait>( pub fn step<M: MesadataTrait>(
&mut self, &mut self,
invoker: &mut Invoker<M>, invoker: &mut Invoker<M>,
) -> Result<InvokerStatus, InvokerError> {
match self.step_catch_err(invoker) {
Ok(InvokerStatus::Running) => Ok(InvokerStatus::Running),
Ok(InvokerStatus::Finished) => {
invoker.history.do_(invoker.ongoing.take().unwrap());
Ok(InvokerStatus::Finished)
}
Err(err) => {
invoker.ongoing = None;
Err(err)
}
}
}
fn step_catch_err<M: MesadataTrait>(
&mut self,
invoker: &mut Invoker<M>,
) -> Result<InvokerStatus, InvokerError> { ) -> Result<InvokerStatus, InvokerError> {
match self { match self {
Execute::Autoroute(autoroute) => match autoroute.step(&mut invoker.autorouter)? { Execute::Autoroute(autoroute) => match autoroute.step(&mut invoker.autorouter)? {
@ -58,6 +76,7 @@ impl Execute {
pub struct Invoker<M: MesadataTrait> { pub struct Invoker<M: MesadataTrait> {
autorouter: Autorouter<M>, autorouter: Autorouter<M>,
history: History, history: History,
ongoing: Option<Command>,
} }
impl<M: MesadataTrait> Invoker<M> { impl<M: MesadataTrait> Invoker<M> {
@ -69,13 +88,15 @@ impl<M: MesadataTrait> Invoker<M> {
Self { Self {
autorouter, autorouter,
history, history,
ongoing: None,
} }
} }
pub fn destruct(self) -> (Autorouter<M>, History) { pub fn destruct(self) -> (Autorouter<M>, History, Option<Command>) {
(self.autorouter, self.history) (self.autorouter, self.history, self.ongoing)
} }
#[debug_requires(self.ongoing.is_none())]
pub fn execute(&mut self, command: Command) -> Result<(), InvokerError> { pub fn execute(&mut self, command: Command) -> Result<(), InvokerError> {
let mut execute = self.execute_walk(command); let mut execute = self.execute_walk(command);
@ -92,12 +113,14 @@ impl<M: MesadataTrait> Invoker<M> {
} }
} }
#[debug_requires(self.ongoing.is_none())]
pub fn execute_walk(&mut self, command: Command) -> Execute { pub fn execute_walk(&mut self, command: Command) -> Execute {
let execute = self.dispatch_command(&command); let execute = self.dispatch_command(&command);
self.history.do_(command); self.ongoing = Some(command);
execute execute
} }
#[debug_requires(self.ongoing.is_none())]
fn dispatch_command(&mut self, command: &Command) -> Execute { fn dispatch_command(&mut self, command: &Command) -> Execute {
match command { match command {
Command::Autoroute(selection) => { Command::Autoroute(selection) => {
@ -109,6 +132,7 @@ impl<M: MesadataTrait> Invoker<M> {
} }
} }
#[debug_requires(self.ongoing.is_none())]
pub fn undo(&mut self) -> Result<(), InvokerError> { pub fn undo(&mut self) -> Result<(), InvokerError> {
let command = self.history.last_done()?; let command = self.history.last_done()?;
@ -117,9 +141,10 @@ impl<M: MesadataTrait> Invoker<M> {
Command::PlaceVia(weight) => self.autorouter.undo_place_via(*weight), Command::PlaceVia(weight) => self.autorouter.undo_place_via(*weight),
} }
Ok(self.history.undo()?) Ok::<(), InvokerError>(self.history.undo()?)
} }
//#[debug_requires(self.ongoing.is_none())]
pub fn redo(&mut self) -> Result<(), InvokerError> { pub fn redo(&mut self) -> Result<(), InvokerError> {
let command = self.history.last_undone()?.clone(); let command = self.history.last_undone()?.clone();
let mut execute = self.dispatch_command(&command); let mut execute = self.dispatch_command(&command);
@ -136,6 +161,7 @@ impl<M: MesadataTrait> Invoker<M> {
} }
} }
#[debug_requires(self.ongoing.is_none())]
pub fn replay(&mut self, history: History) { pub fn replay(&mut self, history: History) {
let (done, undone) = history.destructure(); let (done, undone) = history.destructure();