diff --git a/src/bin/topola-egui/app.rs b/src/bin/topola-egui/app.rs index acb1518..cbb9652 100644 --- a/src/bin/topola-egui/app.rs +++ b/src/bin/topola-egui/app.rs @@ -50,10 +50,13 @@ use crate::{ #[serde(default)] pub struct App { #[serde(skip)] - overlay: Option, + maybe_overlay: Option, #[serde(skip)] - invoker: Arc>>>, + arc_mutex_maybe_invoker: Arc>>>, + + #[serde(skip)] + maybe_execute: Option, #[serde(skip)] text_channel: (Sender, Receiver), @@ -68,19 +71,20 @@ pub struct App { bottom: Bottom, #[serde(skip)] - layers: Option, + maybe_layers: Option, } impl Default for App { fn default() -> Self { Self { - overlay: None, - invoker: Arc::new(Mutex::new(None)), + maybe_overlay: None, + arc_mutex_maybe_invoker: Arc::new(Mutex::new(None)), + maybe_execute: None, text_channel: channel(), viewport: Viewport::new(), top: Top::new(), bottom: Bottom::new(), - layers: None, + maybe_layers: None, } } } @@ -95,6 +99,44 @@ impl App { Default::default() } + + fn update_state(&mut self) { + if cfg!(target_arch = "wasm32") { + if let Ok(file_contents) = self.text_channel.1.try_recv() { + let design = SpecctraDesign::load_from_string(file_contents).unwrap(); + let board = design.make_board(); + self.maybe_overlay = Some(Overlay::new(&board).unwrap()); + self.maybe_layers = Some(Layers::new(&board)); + self.arc_mutex_maybe_invoker = Arc::new(Mutex::new(Some(Invoker::new( + Autorouter::new(board).unwrap(), + )))); + } + } else { + if let Ok(path) = self.text_channel.1.try_recv() { + let design = SpecctraDesign::load_from_file(&path).unwrap(); + let board = design.make_board(); + self.maybe_overlay = Some(Overlay::new(&board).unwrap()); + self.maybe_layers = Some(Layers::new(&board)); + self.arc_mutex_maybe_invoker = Arc::new(Mutex::new(Some(Invoker::new( + Autorouter::new(board).unwrap(), + )))); + } + } + + if let Some(invoker) = self.arc_mutex_maybe_invoker.lock().unwrap().as_mut() { + if let Some(ref mut execute) = self.maybe_execute { + let status = match execute.step(invoker) { + Ok(status) => status, + Err(err) => return, + }; + + if let InvokerStatus::Finished = status { + self.maybe_execute = None; + return; + } + } + } + } } impl eframe::App for App { @@ -105,37 +147,18 @@ impl eframe::App for App { /// Called each time the UI has to be repainted. fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { - if cfg!(target_arch = "wasm32") { - if let Ok(file_contents) = self.text_channel.1.try_recv() { - let design = SpecctraDesign::load_from_string(file_contents).unwrap(); - let board = design.make_board(); - self.overlay = Some(Overlay::new(&board).unwrap()); - self.layers = Some(Layers::new(&board)); - self.invoker = Arc::new(Mutex::new(Some(Invoker::new( - Autorouter::new(board).unwrap(), - )))); - } - } else { - if let Ok(path) = self.text_channel.1.try_recv() { - let design = SpecctraDesign::load_from_file(&path).unwrap(); - let board = design.make_board(); - self.overlay = Some(Overlay::new(&board).unwrap()); - self.layers = Some(Layers::new(&board)); - self.invoker = Arc::new(Mutex::new(Some(Invoker::new( - Autorouter::new(board).unwrap(), - )))); - } - } + self.update_state(); self.top.update( ctx, self.text_channel.0.clone(), - self.invoker.clone(), - &mut self.overlay, + self.arc_mutex_maybe_invoker.clone(), + &mut self.maybe_execute, + &mut self.maybe_overlay, ); - if let Some(ref mut layers) = self.layers { - if let Some(invoker) = self.invoker.lock().unwrap().as_ref() { + if let Some(ref mut layers) = self.maybe_layers { + if let Some(invoker) = self.arc_mutex_maybe_invoker.lock().unwrap().as_ref() { layers.update(ctx, invoker.autorouter().board()); } } @@ -143,9 +166,9 @@ impl eframe::App for App { let viewport_rect = self.viewport.update( ctx, &self.top, - &mut self.invoker.lock().unwrap(), - &mut self.overlay, - &self.layers, + &mut self.arc_mutex_maybe_invoker.lock().unwrap(), + &mut self.maybe_overlay, + &self.maybe_layers, ); self.bottom.update(ctx, &self.viewport, viewport_rect); diff --git a/src/bin/topola-egui/top.rs b/src/bin/topola-egui/top.rs index 96f8c7e..86412a8 100644 --- a/src/bin/topola-egui/top.rs +++ b/src/bin/topola-egui/top.rs @@ -32,7 +32,8 @@ impl Top { &mut self, ctx: &egui::Context, sender: Sender, - maybe_invoker: Arc>>>, + arc_mutex_maybe_invoker: Arc>>>, + maybe_execute: &mut Option, maybe_overlay: &Option, ) { egui::TopBottomPanel::top("top_panel").show(ctx, |ui| { @@ -55,7 +56,7 @@ impl Top { ui.separator(); if ui.button("Load history").clicked() { - let invoker_arc_mutex = maybe_invoker.clone(); + let invoker_arc_mutex = arc_mutex_maybe_invoker.clone(); let ctx = ui.ctx().clone(); let task = rfd::AsyncFileDialog::new().pick_file(); @@ -79,7 +80,7 @@ impl Top { } if ui.button("Save history").clicked() { - let invoker_arc_mutex = maybe_invoker.clone(); + let invoker_arc_mutex = arc_mutex_maybe_invoker.clone(); let ctx = ui.ctx().clone(); let task = rfd::AsyncFileDialog::new().save_file(); @@ -115,39 +116,15 @@ impl Top { ui.separator(); if ui.button("Autoroute").clicked() { - if let (Some(invoker), Some(ref overlay)) = - (maybe_invoker.lock().unwrap().as_mut(), maybe_overlay) - { - let selection = overlay.selection().clone(); - let mut execute = invoker.execute_walk(Command::Autoroute(selection)); - - if let Execute::Autoroute(ref mut autoroute) = execute { - let from = autoroute.navmesh().as_ref().unwrap().source(); - let to = autoroute.navmesh().as_ref().unwrap().target(); - - /*{ - let mut shared_data = shared_data_arc_mutex.lock().unwrap(); - shared_data.from = Some(from); - shared_data.to = Some(to); - shared_data.navmesh = autoroute.navmesh().cloned(); - }*/ + if maybe_execute.is_none() { + if let (Some(invoker), Some(ref overlay)) = ( + arc_mutex_maybe_invoker.lock().unwrap().as_mut(), + maybe_overlay, + ) { + let selection = overlay.selection().clone(); + maybe_execute + .insert(invoker.execute_walk(Command::Autoroute(selection))); } - - let _ = loop { - let status = match execute.step(invoker) { - Ok(status) => status, - Err(err) => return, - }; - - if let InvokerStatus::Finished = status { - break; - } - - /*if let Execute::Autoroute(ref mut autoroute) = execute { - shared_data_arc_mutex.lock().unwrap().navmesh = - autoroute.navmesh().cloned(); - }*/ - }; } } @@ -158,7 +135,7 @@ impl Top { if ui.button("Undo").clicked() || ctx.input_mut(|i| i.consume_key(egui::Modifiers::CTRL, egui::Key::Z)) { - if let Some(invoker) = maybe_invoker.lock().unwrap().as_mut() { + if let Some(invoker) = arc_mutex_maybe_invoker.lock().unwrap().as_mut() { invoker.undo(); } } @@ -166,7 +143,8 @@ impl Top { if ui.button("Redo").clicked() || ctx.input_mut(|i| i.consume_key(egui::Modifiers::CTRL, egui::Key::Y)) { - if let Some(ref mut invoker) = maybe_invoker.lock().unwrap().as_mut() { + if let Some(ref mut invoker) = arc_mutex_maybe_invoker.lock().unwrap().as_mut() + { invoker.redo(); } }