From 02bfe1105b8b6c1b7b9278cec08a36675cd1fb71 Mon Sep 17 00:00:00 2001 From: Mikolaj Wielgus Date: Wed, 22 May 2024 14:17:49 +0200 Subject: [PATCH] egui: Implement saving command file --- Cargo.toml | 1 + src/autorouter/history.rs | 3 +++ src/autorouter/invoker.rs | 9 ++++++--- src/bin/topola-egui/app.rs | 28 ++++++++++++++++++++++++---- 4 files changed, 34 insertions(+), 7 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 85347f3..a9793bc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,6 +26,7 @@ geo = "0.25.1" rstar = "0.11.0" petgraph = "0.6.3" spade = "2.2.0" +serde_json = "1.0.117" enum_dispatch = "0.3.12" itertools = "0.8.2" contracts = "0.6.3" diff --git a/src/autorouter/history.rs b/src/autorouter/history.rs index 63e6829..8f75972 100644 --- a/src/autorouter/history.rs +++ b/src/autorouter/history.rs @@ -1,5 +1,8 @@ +use serde::{Deserialize, Serialize}; + use crate::autorouter::invoker::Command; +#[derive(Serialize, Deserialize)] pub struct History { done: Vec, undone: Vec, diff --git a/src/autorouter/invoker.rs b/src/autorouter/invoker.rs index 3641b6c..3bd830b 100644 --- a/src/autorouter/invoker.rs +++ b/src/autorouter/invoker.rs @@ -62,10 +62,9 @@ impl Invoker { pub fn undo(&mut self) { let command = self.history.done().last().unwrap(); - let mut execute = self.dispatch_command(command); - while execute.next(self, &mut EmptyRouterObserver) { - // + match command { + Command::Autoroute(ref selection) => self.autorouter.undo_autoroute(selection), } self.history.undo(); @@ -85,4 +84,8 @@ impl Invoker { pub fn autorouter(&self) -> &Autorouter { &self.autorouter } + + pub fn history(&self) -> &History { + &self.history + } } diff --git a/src/bin/topola-egui/app.rs b/src/bin/topola-egui/app.rs index c100480..4166a38 100644 --- a/src/bin/topola-egui/app.rs +++ b/src/bin/topola-egui/app.rs @@ -2,6 +2,7 @@ use futures::executor; use geo::point; use petgraph::visit::{EdgeRef, IntoEdgeReferences}; use std::{ + fs::File, future::Future, sync::{ mpsc::{channel, Receiver, Sender}, @@ -187,15 +188,34 @@ impl eframe::App for App { let task = rfd::AsyncFileDialog::new().pick_file(); execute(async move { - let maybe_file_handle = task.await; - - if let Some(file_handle) = maybe_file_handle { - let _ = sender.send(channel_text(file_handle).await); + if let Some(file_handle) = task.await { + sender.send(channel_text(file_handle).await); ctx.request_repaint(); } }); } + ui.separator(); + + if ui.button("Save history").clicked() { + if let Some(invoker_arc_mutex) = &self.invoker { + let invoker_arc_mutex = invoker_arc_mutex.clone(); + let ctx = ui.ctx().clone(); + let task = rfd::AsyncFileDialog::new().save_file(); + + execute(async move { + if let Some(file_handle) = task.await { + let path = file_handle.path(); + let mut file = File::create(path).unwrap(); + let mut invoker = invoker_arc_mutex.lock().unwrap(); + serde_json::to_writer(file, invoker.history()); + } + }); + } + } + + ui.separator(); + // "Quit" button wouldn't work on a Web page. if !cfg!(target_arch = "wasm32") { if ui.button("Quit").clicked() {