egui: implement loading the history (not functional yet)

Committing this non-functional and half-baked because loading the
history requires implementing stateful deserialization, which is quite
an effort to implement with Serde, as there are no applicable derive
macros.
This commit is contained in:
Mikolaj Wielgus 2024-05-23 18:59:29 +02:00
parent 02bfe1105b
commit 53fa89d02c
4 changed files with 42 additions and 1 deletions

View File

@ -16,6 +16,10 @@ impl History {
}
}
pub fn destructure(self) -> (Vec<Command>, Vec<Command>) {
(self.done, self.undone)
}
pub fn do_(&mut self, command: Command) {
self.done.push(command);
}
@ -30,6 +34,10 @@ impl History {
self.done.push(command);
}
pub fn set_undone(&mut self, iter: impl IntoIterator<Item = Command>) {
self.undone = Vec::from_iter(iter);
}
pub fn done(&self) -> &[Command] {
&self.done
}

View File

@ -1,6 +1,9 @@
use core::fmt;
use crate::{
autorouter::{history::History, selection::Selection, Autoroute, Autorouter},
drawing::rules::RulesTrait,
layout::Layout,
router::{EmptyRouterObserver, RouterObserverTrait},
};
@ -44,6 +47,8 @@ impl<R: RulesTrait> Invoker<R> {
while execute.next(self, observer) {
//
}
self.history.set_undone(std::iter::empty());
}
pub fn execute_walk(&mut self, command: Command) -> Execute {
@ -81,6 +86,16 @@ impl<R: RulesTrait> Invoker<R> {
self.history.redo();
}
pub fn replay(&mut self, history: History) {
let (done, undone) = history.destructure();
for command in done {
self.execute(command, &mut EmptyRouterObserver);
}
self.history.set_undone(undone.into_iter());
}
pub fn autorouter(&self) -> &Autorouter<R> {
&self.autorouter
}

View File

@ -1,3 +1,4 @@
use core::fmt;
use std::collections::HashSet;
use crate::{

View File

@ -197,6 +197,23 @@ impl eframe::App for App {
ui.separator();
if ui.button("Load 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().pick_file();
execute(async move {
if let Some(file_handle) = task.await {
let path = file_handle.path();
let mut file = File::open(path).unwrap();
let mut invoker = invoker_arc_mutex.lock().unwrap();
invoker.replay(serde_json::from_reader(file).unwrap());
}
});
}
}
if ui.button("Save history").clicked() {
if let Some(invoker_arc_mutex) = &self.invoker {
let invoker_arc_mutex = invoker_arc_mutex.clone();
@ -208,7 +225,7 @@ impl eframe::App for App {
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());
serde_json::to_writer_pretty(file, invoker.history());
}
});
}