egui: implement loading history in WASM

This commit is contained in:
Mikolaj Wielgus 2024-07-06 00:08:35 +02:00
parent 0745604658
commit 3a7e504c29
4 changed files with 33 additions and 41 deletions

View File

@ -61,6 +61,9 @@ pub struct App {
#[serde(skip)]
content_channel: (Sender<String>, Receiver<String>),
#[serde(skip)]
history_channel: (Sender<String>, Receiver<String>),
#[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,

View File

@ -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<Cursor<Vec<u8>>, TryRecvError> {
Ok(Cursor::new(self.receiver.try_recv().unwrap().into()))
}
}

View File

@ -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()

View File

@ -32,7 +32,8 @@ impl Top {
pub fn update(
&mut self,
ctx: &egui::Context,
sender: Sender<String>,
content_sender: Sender<String>,
history_sender: Sender<String>,
arc_mutex_maybe_invoker: Arc<Mutex<Option<Invoker<SpecctraMesadata>>>>,
maybe_execute: &mut Option<ExecuteWithStatus>,
maybe_overlay: &Option<Overlay>,
@ -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();
}
});
}