From 3a7e504c290ef8cb2fdebc84a498923dcc9ecf2b Mon Sep 17 00:00:00 2001 From: Mikolaj Wielgus Date: Sat, 6 Jul 2024 00:08:35 +0200 Subject: [PATCH] egui: implement loading history in WASM --- src/bin/topola-egui/app.rs | 17 ++++++++-- src/bin/topola-egui/file_receiver.rs | 6 ++-- src/bin/topola-egui/file_sender.rs | 2 +- src/bin/topola-egui/top.rs | 49 ++++++++-------------------- 4 files changed, 33 insertions(+), 41 deletions(-) diff --git a/src/bin/topola-egui/app.rs b/src/bin/topola-egui/app.rs index a74a54d..0dc40d1 100644 --- a/src/bin/topola-egui/app.rs +++ b/src/bin/topola-egui/app.rs @@ -61,6 +61,9 @@ pub struct App { #[serde(skip)] content_channel: (Sender, Receiver), + #[serde(skip)] + history_channel: (Sender, Receiver), + #[serde(skip)] viewport: Viewport, @@ -84,6 +87,7 @@ impl Default for App { arc_mutex_maybe_invoker: Arc::new(Mutex::new(None)), maybe_execute: None, content_channel: channel(), + history_channel: channel(), viewport: Viewport::new(), top: Top::new(), bottom: Bottom::new(), @@ -113,9 +117,9 @@ impl App { self.update_counter = 0.0; - let mut file_receiver = FileReceiver::new(&self.content_channel.1); + let mut content_file_receiver = FileReceiver::new(&self.content_channel.1); - if let Ok(bufread) = file_receiver.try_recv() { + if let Ok(bufread) = content_file_receiver.try_recv() { let design = SpecctraDesign::load(bufread).unwrap(); let board = design.make_board(); self.maybe_overlay = Some(Overlay::new(&board).unwrap()); @@ -126,6 +130,14 @@ impl App { } if let Some(invoker) = self.arc_mutex_maybe_invoker.lock().unwrap().as_mut() { + let mut history_file_receiver = FileReceiver::new(&self.history_channel.1); + + if let Ok(bufread) = history_file_receiver.try_recv() { + invoker.replay(serde_json::from_reader(bufread).unwrap()) + } + + // TODO: Make Save History work too. + if let Some(ref mut execute) = self.maybe_execute { let status = match execute.step(invoker) { Ok(status) => status, @@ -149,6 +161,7 @@ impl eframe::App for App { self.top.update( ctx, self.content_channel.0.clone(), + self.history_channel.0.clone(), self.arc_mutex_maybe_invoker.clone(), &mut self.maybe_execute, &mut self.maybe_overlay, diff --git a/src/bin/topola-egui/file_receiver.rs b/src/bin/topola-egui/file_receiver.rs index d70ef35..2a892d3 100644 --- a/src/bin/topola-egui/file_receiver.rs +++ b/src/bin/topola-egui/file_receiver.rs @@ -1,4 +1,4 @@ -use std::io::BufReader; +use std::io::{BufReader, Cursor}; use std::sync::mpsc::{Receiver, TryRecvError}; pub struct FileReceiver<'a> { @@ -18,7 +18,7 @@ impl<'a> FileReceiver<'a> { } #[cfg(target_arch = "wasm32")] - pub fn try_recv(&mut self) -> Result<&[u8], TryRecvError> { - self.receiver.try_recv().unwrap().as_bytes() + pub fn try_recv(&mut self) -> Result>, TryRecvError> { + Ok(Cursor::new(self.receiver.try_recv().unwrap().into())) } } diff --git a/src/bin/topola-egui/file_sender.rs b/src/bin/topola-egui/file_sender.rs index a48681b..c1ed29a 100644 --- a/src/bin/topola-egui/file_sender.rs +++ b/src/bin/topola-egui/file_sender.rs @@ -19,7 +19,7 @@ impl FileSender { } #[cfg(target_arch = "wasm32")] - async fn handle_text(&self, file_handle: &rfd::FileHandle) { + async fn handle_text(&self, file_handle: &rfd::FileHandle) -> String { std::str::from_utf8(&file_handle.read().await) .unwrap() .to_string() diff --git a/src/bin/topola-egui/top.rs b/src/bin/topola-egui/top.rs index ec3fd69..a1d0057 100644 --- a/src/bin/topola-egui/top.rs +++ b/src/bin/topola-egui/top.rs @@ -32,7 +32,8 @@ impl Top { pub fn update( &mut self, ctx: &egui::Context, - sender: Sender, + content_sender: Sender, + history_sender: Sender, arc_mutex_maybe_invoker: Arc>>>, maybe_execute: &mut Option, maybe_overlay: &Option, @@ -48,7 +49,7 @@ impl Top { execute(async move { if let Some(file_handle) = task.await { - let file_sender = FileSender::new(sender); + let file_sender = FileSender::new(content_sender); file_sender.send(file_handle).await; ctx.request_repaint(); } @@ -63,45 +64,23 @@ impl Top { let task = rfd::AsyncFileDialog::new().pick_file(); execute(async move { - let Some(file_handle) = task.await else { - return; - }; - - let path = file_handle.path(); - let Ok(mut file) = File::open(path) else { - return; - }; - - let mut locked_invoker = invoker_arc_mutex.lock().unwrap(); - let Some(mut invoker) = locked_invoker.as_mut() else { - return; - }; - - invoker.replay(serde_json::from_reader(file).unwrap()); + if let Some(file_handle) = task.await { + let file_sender = FileSender::new(history_sender); + file_sender.send(file_handle).await; + ctx.request_repaint(); + } }); - } - - if ui.button("Save history").clicked() { + } else if ui.button("Save history").clicked() { let invoker_arc_mutex = arc_mutex_maybe_invoker.clone(); let ctx = ui.ctx().clone(); let task = rfd::AsyncFileDialog::new().save_file(); execute(async move { - let Some(file_handle) = task.await else { - return; - }; - - let path = file_handle.path(); - let Ok(mut file) = File::create(path) else { - return; - }; - - let mut locked_invoker = invoker_arc_mutex.lock().unwrap(); - let Some(mut invoker) = locked_invoker.as_mut() else { - return; - }; - - serde_json::to_writer_pretty(file, invoker.history()); + if let Some(file_handle) = task.await { + let file_sender = FileSender::new(history_sender); + file_sender.send(file_handle).await; + ctx.request_repaint(); + } }); }