mirror of https://codeberg.org/topola/topola.git
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:
parent
02bfe1105b
commit
53fa89d02c
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
use core::fmt;
|
||||
use std::collections::HashSet;
|
||||
|
||||
use crate::{
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue