mirror of https://codeberg.org/topola/topola.git
egui/file_handler: run parsing in file loader thread
- also embed I/O errors with other errors
This commit is contained in:
parent
1a46504dd5
commit
25a692aab9
|
|
@ -9,8 +9,11 @@ use std::{
|
|||
use unic_langid::{langid, LanguageIdentifier};
|
||||
|
||||
use topola::{
|
||||
autorouter::{invoker::Invoker, Autorouter},
|
||||
specctra::{design::SpecctraDesign, mesadata::SpecctraMesadata},
|
||||
autorouter::{history::History, invoker::Invoker, Autorouter},
|
||||
specctra::{
|
||||
design::{LoadingError as SpecctraLoadingError, SpecctraDesign},
|
||||
mesadata::SpecctraMesadata,
|
||||
},
|
||||
stepper::Step,
|
||||
};
|
||||
|
||||
|
|
@ -38,12 +41,12 @@ pub struct App {
|
|||
maybe_activity: Option<ActivityStepperWithStatus>,
|
||||
|
||||
content_channel: (
|
||||
Sender<std::io::Result<FileHandlerData>>,
|
||||
Receiver<std::io::Result<FileHandlerData>>,
|
||||
Sender<Result<SpecctraDesign, SpecctraLoadingError>>,
|
||||
Receiver<Result<SpecctraDesign, SpecctraLoadingError>>,
|
||||
),
|
||||
history_channel: (
|
||||
Sender<std::io::Result<FileHandlerData>>,
|
||||
Receiver<std::io::Result<FileHandlerData>>,
|
||||
Sender<std::io::Result<Result<History, serde_json::Error>>>,
|
||||
Receiver<std::io::Result<Result<History, serde_json::Error>>>,
|
||||
),
|
||||
|
||||
viewport: Viewport,
|
||||
|
|
@ -109,13 +112,23 @@ impl App {
|
|||
fn update_state(&mut self) -> bool {
|
||||
if let Ok(data) = self.content_channel.1.try_recv() {
|
||||
match data {
|
||||
Ok(data) => match self.load_specctra_dsn(data) {
|
||||
Ok(design) => match self.load_specctra_dsn(design) {
|
||||
Ok(()) => {}
|
||||
Err(err) => {
|
||||
self.error_dialog.push_error("tr-module-specctra-dsn-file-loader", err);
|
||||
}
|
||||
},
|
||||
Err(err) => {
|
||||
Err(SpecctraLoadingError::Parse(err)) => {
|
||||
self.error_dialog.push_error(
|
||||
"tr-module-specctra-dsn-file-loader",
|
||||
format!(
|
||||
"{}; {}",
|
||||
self.translator.text("tr-error_failed-to-parse-as-specctra-dsn"),
|
||||
err
|
||||
),
|
||||
);
|
||||
}
|
||||
Err(SpecctraLoadingError::Io(err)) => {
|
||||
self.error_dialog.push_error(
|
||||
"tr-module-specctra-dsn-file-loader",
|
||||
format!("{}; {}", self.translator.text("tr-error_unable-to-read-file"), err),
|
||||
|
|
@ -125,18 +138,18 @@ impl App {
|
|||
}
|
||||
|
||||
if let Some(invoker) = self.arc_mutex_maybe_invoker.lock().unwrap().as_mut() {
|
||||
if let Ok(input) = self.history_channel.1.try_recv() {
|
||||
if let Ok(data) = self.history_channel.1.try_recv() {
|
||||
let tr = &self.translator;
|
||||
match input {
|
||||
Ok(bufread) => match serde_json::from_reader(bufread) {
|
||||
Ok(res) => invoker.replay(res),
|
||||
Err(err) => {
|
||||
match data {
|
||||
Ok(Ok(data)) => {
|
||||
invoker.replay(data);
|
||||
}
|
||||
Ok(Err(err)) => {
|
||||
self.error_dialog.push_error(
|
||||
"tr-module-history-file-loader",
|
||||
format!("{}; {}", tr.text("tr-error_failed-to-parse-as-history-json"), err),
|
||||
);
|
||||
}
|
||||
},
|
||||
Err(err) => {
|
||||
self.error_dialog.push_error(
|
||||
"tr-module-history-file-loader",
|
||||
|
|
@ -161,10 +174,8 @@ impl App {
|
|||
false
|
||||
}
|
||||
|
||||
fn load_specctra_dsn(&mut self, bufread: FileHandlerData) -> Result<(), String> {
|
||||
fn load_specctra_dsn(&mut self, design: SpecctraDesign) -> Result<(), String> {
|
||||
let tr = &self.translator;
|
||||
let design = SpecctraDesign::load(bufread)
|
||||
.map_err(|err| format!("{}; {}", tr.text("tr-error_failed-to-parse-as-specctra-dsn"), err))?;
|
||||
let board = design.make_board();
|
||||
let overlay = Overlay::new(&board)
|
||||
.map_err(|err| format!("{}; {}", tr.text("tr-error_unable-to-initialize-overlay"), err))?;
|
||||
|
|
|
|||
|
|
@ -46,19 +46,28 @@ impl io::BufRead for FileHandlerData {
|
|||
fhd_forward!(fn consume(&mut self, amt: usize));
|
||||
}
|
||||
|
||||
pub async fn push_file_to_read(
|
||||
#[inline]
|
||||
pub async fn push_file_to_read<R, E, C>(
|
||||
file_handle: &rfd::FileHandle,
|
||||
sender: Sender<std::io::Result<FileHandlerData>>,
|
||||
) {
|
||||
let _ = sender.send(handle_text(&file_handle).await);
|
||||
sender: Sender<Result<R, E>>,
|
||||
callback: C,
|
||||
) where
|
||||
E: From<std::io::Error>,
|
||||
C: FnOnce(FileHandlerData) -> Result<R, E>,
|
||||
{
|
||||
let _ = sender.send(handle_text(&file_handle, callback).await);
|
||||
}
|
||||
|
||||
async fn handle_text(file_handle: &rfd::FileHandle) -> std::io::Result<FileHandlerData> {
|
||||
async fn handle_text<R, E, C>(file_handle: &rfd::FileHandle, callback: C) -> Result<R, E>
|
||||
where
|
||||
E: From<std::io::Error>,
|
||||
C: FnOnce(FileHandlerData) -> Result<R, E>,
|
||||
{
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
let res = FileHandlerData::File(io::BufReader::new(std::fs::File::open(file_handle.path())?));
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
let res = FileHandlerData::Contents(io::Cursor::new(file_handle.read().await));
|
||||
|
||||
Ok(res)
|
||||
callback(res)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,11 +6,15 @@ use std::{
|
|||
use topola::{
|
||||
autorouter::{
|
||||
command::Command,
|
||||
history::History,
|
||||
invoker::{Invoker, InvokerError},
|
||||
AutorouterOptions,
|
||||
},
|
||||
router::RouterOptions,
|
||||
specctra::{design::SpecctraDesign, mesadata::SpecctraMesadata},
|
||||
specctra::{
|
||||
design::{LoadingError as SpecctraLoadingError, SpecctraDesign},
|
||||
mesadata::SpecctraMesadata,
|
||||
},
|
||||
stepper::Abort,
|
||||
};
|
||||
|
||||
|
|
@ -59,8 +63,8 @@ impl MenuBar {
|
|||
&mut self,
|
||||
ctx: &egui::Context,
|
||||
tr: &Translator,
|
||||
content_sender: Sender<std::io::Result<FileHandlerData>>,
|
||||
history_sender: Sender<std::io::Result<FileHandlerData>>,
|
||||
content_sender: Sender<Result<SpecctraDesign, SpecctraLoadingError>>,
|
||||
history_sender: Sender<std::io::Result<Result<History, serde_json::Error>>>,
|
||||
arc_mutex_maybe_invoker: Arc<Mutex<Option<Invoker<SpecctraMesadata>>>>,
|
||||
maybe_activity: &mut Option<ActivityStepperWithStatus>,
|
||||
viewport: &mut Viewport,
|
||||
|
|
@ -239,7 +243,10 @@ impl MenuBar {
|
|||
|
||||
execute(async move {
|
||||
if let Some(file_handle) = task.await {
|
||||
push_file_to_read(&file_handle, content_sender).await;
|
||||
push_file_to_read(&file_handle, content_sender, |data| {
|
||||
SpecctraDesign::load(data)
|
||||
})
|
||||
.await;
|
||||
ctx.request_repaint();
|
||||
}
|
||||
});
|
||||
|
|
@ -278,7 +285,14 @@ impl MenuBar {
|
|||
|
||||
execute(async move {
|
||||
if let Some(file_handle) = task.await {
|
||||
push_file_to_read(&file_handle, history_sender).await;
|
||||
push_file_to_read(&file_handle, history_sender, |data| {
|
||||
match serde_json::from_reader(data) {
|
||||
Ok(history) => Ok(Ok(history)),
|
||||
Err(err) if err.is_io() => Err(err.into()),
|
||||
Err(err) => Ok(Err(err)),
|
||||
}
|
||||
})
|
||||
.await;
|
||||
ctx.request_repaint();
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -26,9 +26,10 @@ use crate::{
|
|||
},
|
||||
};
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub use read::ParseErrorContext;
|
||||
|
||||
/// Errors raised by [`SpecctraDesign::load`]
|
||||
#[derive(Error, Debug)]
|
||||
pub enum LoadingError {
|
||||
/// I/O file reading error from [`std::io::Error`]
|
||||
#[error(transparent)]
|
||||
|
|
|
|||
Loading…
Reference in New Issue