diff --git a/src/bin/topola-egui/app.rs b/src/bin/topola-egui/app.rs index 1a608d7..acb1518 100644 --- a/src/bin/topola-egui/app.rs +++ b/src/bin/topola-egui/app.rs @@ -45,16 +45,6 @@ use crate::{ viewport::Viewport, }; -#[derive(Debug, Default)] -pub struct SharedData { - pub from: Option, - pub to: Option, - pub navmesh: Option, - pub path: Vec, - pub ghosts: Vec, - pub highlighteds: Vec, -} - /// Deserialize/Serialize is needed to persist app state between restarts. #[derive(Serialize, Deserialize)] #[serde(default)] @@ -63,10 +53,7 @@ pub struct App { overlay: Option, #[serde(skip)] - invoker: Option>>>, - - #[serde(skip)] - shared_data: Arc>, + invoker: Arc>>>, #[serde(skip)] text_channel: (Sender, Receiver), @@ -88,8 +75,7 @@ impl Default for App { fn default() -> Self { Self { overlay: None, - invoker: None, - shared_data: Default::default(), + invoker: Arc::new(Mutex::new(None)), text_channel: channel(), viewport: Viewport::new(), top: Top::new(), @@ -125,7 +111,7 @@ impl eframe::App for App { let board = design.make_board(); self.overlay = Some(Overlay::new(&board).unwrap()); self.layers = Some(Layers::new(&board)); - self.invoker = Some(Arc::new(Mutex::new(Invoker::new( + self.invoker = Arc::new(Mutex::new(Some(Invoker::new( Autorouter::new(board).unwrap(), )))); } @@ -135,7 +121,7 @@ impl eframe::App for App { let board = design.make_board(); self.overlay = Some(Overlay::new(&board).unwrap()); self.layers = Some(Layers::new(&board)); - self.invoker = Some(Arc::new(Mutex::new(Invoker::new( + self.invoker = Arc::new(Mutex::new(Some(Invoker::new( Autorouter::new(board).unwrap(), )))); } @@ -143,23 +129,21 @@ impl eframe::App for App { self.top.update( ctx, - self.shared_data.clone(), self.text_channel.0.clone(), - &self.invoker, + self.invoker.clone(), &mut self.overlay, ); if let Some(ref mut layers) = self.layers { - if let Some(invoker_arc_mutex) = &self.invoker { - layers.update(ctx, invoker_arc_mutex.lock().unwrap().autorouter().board()); + if let Some(invoker) = self.invoker.lock().unwrap().as_ref() { + layers.update(ctx, invoker.autorouter().board()); } } let viewport_rect = self.viewport.update( ctx, &self.top, - self.shared_data.clone(), - &self.invoker, + &mut self.invoker.lock().unwrap(), &mut self.overlay, &self.layers, ); diff --git a/src/bin/topola-egui/top.rs b/src/bin/topola-egui/top.rs index dabf45c..96f8c7e 100644 --- a/src/bin/topola-egui/top.rs +++ b/src/bin/topola-egui/top.rs @@ -9,7 +9,7 @@ use topola::{ }; use crate::{ - app::{channel_text, execute, SharedData}, + app::{channel_text, execute}, overlay::Overlay, }; @@ -31,9 +31,8 @@ impl Top { pub fn update( &mut self, ctx: &egui::Context, - shared_data: Arc>, sender: Sender, - maybe_invoker: &Option>>>, + maybe_invoker: Arc>>>, maybe_overlay: &Option, ) { egui::TopBottomPanel::top("top_panel").show(ctx, |ui| { @@ -56,37 +55,51 @@ impl Top { ui.separator(); if ui.button("Load history").clicked() { - if let Some(invoker_arc_mutex) = &maybe_invoker { - let invoker_arc_mutex = invoker_arc_mutex.clone(); - let ctx = ui.ctx().clone(); - let task = rfd::AsyncFileDialog::new().pick_file(); + let invoker_arc_mutex = maybe_invoker.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 invoker = invoker_arc_mutex.lock().unwrap(); - let mut file = File::open(path).unwrap(); - invoker.replay(serde_json::from_reader(file).unwrap()); - } - }); - } + 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 ui.button("Save history").clicked() { - if let Some(invoker_arc_mutex) = &maybe_invoker { - let invoker_arc_mutex = invoker_arc_mutex.clone(); - let ctx = ui.ctx().clone(); - let task = rfd::AsyncFileDialog::new().save_file(); + let invoker_arc_mutex = maybe_invoker.clone(); + let ctx = ui.ctx().clone(); + let task = rfd::AsyncFileDialog::new().save_file(); - execute(async move { - if let Some(file_handle) = task.await { - let path = file_handle.path(); - let mut invoker = invoker_arc_mutex.lock().unwrap(); - let mut file = File::create(path).unwrap(); - serde_json::to_writer_pretty(file, invoker.history()); - } - }); - } + 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()); + }); } ui.separator(); @@ -102,45 +115,39 @@ impl Top { ui.separator(); if ui.button("Autoroute").clicked() { - if let (Some(invoker_arc_mutex), Some(overlay)) = - (&maybe_invoker, &maybe_overlay) + if let (Some(invoker), Some(ref overlay)) = + (maybe_invoker.lock().unwrap().as_mut(), maybe_overlay) { - let invoker_arc_mutex = invoker_arc_mutex.clone(); - let shared_data_arc_mutex = shared_data.clone(); let selection = overlay.selection().clone(); + let mut execute = invoker.execute_walk(Command::Autoroute(selection)); - execute(async move { - let mut invoker = invoker_arc_mutex.lock().unwrap(); - 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(); - 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(); + }*/ + } - { - 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(); - } + let _ = loop { + let status = match execute.step(invoker) { + Ok(status) => status, + Err(err) => return, + }; + + if let InvokerStatus::Finished = status { + break; } - let _ = loop { - let status = match execute.step(&mut 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(); - } - }; - }); + /*if let Execute::Autoroute(ref mut autoroute) = execute { + shared_data_arc_mutex.lock().unwrap().navmesh = + autoroute.navmesh().cloned(); + }*/ + }; } } @@ -151,22 +158,16 @@ impl Top { if ui.button("Undo").clicked() || ctx.input_mut(|i| i.consume_key(egui::Modifiers::CTRL, egui::Key::Z)) { - if let Some(invoker_arc_mutex) = &maybe_invoker { - let invoker_arc_mutex = invoker_arc_mutex.clone(); - execute(async move { - invoker_arc_mutex.lock().unwrap().undo(); - }); + if let Some(invoker) = maybe_invoker.lock().unwrap().as_mut() { + invoker.undo(); } } if ui.button("Redo").clicked() || ctx.input_mut(|i| i.consume_key(egui::Modifiers::CTRL, egui::Key::Y)) { - if let Some(invoker_arc_mutex) = &maybe_invoker { - let invoker_arc_mutex = invoker_arc_mutex.clone(); - execute(async move { - invoker_arc_mutex.lock().unwrap().redo(); - }); + if let Some(ref mut invoker) = maybe_invoker.lock().unwrap().as_mut() { + invoker.redo(); } } diff --git a/src/bin/topola-egui/viewport.rs b/src/bin/topola-egui/viewport.rs index bb5aece..082ce82 100644 --- a/src/bin/topola-egui/viewport.rs +++ b/src/bin/topola-egui/viewport.rs @@ -1,5 +1,3 @@ -use std::sync::{Arc, Mutex}; - use geo::point; use petgraph::visit::{EdgeRef, IntoEdgeReferences}; use topola::{ @@ -15,13 +13,7 @@ use topola::{ specctra::mesadata::SpecctraMesadata, }; -use crate::{ - app::{execute, SharedData}, - layers::Layers, - overlay::Overlay, - painter::Painter, - top::Top, -}; +use crate::{app::execute, layers::Layers, overlay::Overlay, painter::Painter, top::Top}; pub struct Viewport { pub from_rect: egui::emath::Rect, @@ -38,8 +30,7 @@ impl Viewport { &mut self, ctx: &egui::Context, top: &Top, - shared_data: Arc>, - maybe_invoker: &Option>>>, + maybe_invoker: &mut Option>, maybe_overlay: &mut Option, maybe_layers: &Option, ) -> egui::Rect { @@ -74,27 +65,21 @@ impl Viewport { let transform = egui::emath::RectTransform::from_to(self.from_rect, viewport_rect); let mut painter = Painter::new(ui, transform); - if let Some(invoker_arc_mutex) = maybe_invoker { + if let Some(ref mut invoker) = maybe_invoker { if ctx.input(|i| i.pointer.any_click()) { if top.is_placing_via { - let invoker_arc_mutex = invoker_arc_mutex.clone(); - - execute(async move { - let mut invoker = invoker_arc_mutex.lock().unwrap(); - invoker.execute( - Command::PlaceVia(ViaWeight { - from_layer: 0, - to_layer: 0, - circle: Circle { - pos: point! {x: latest_pos.x as f64, y: -latest_pos.y as f64}, - r: 100.0, - }, - maybe_net: Some(1234), - }), - ); - }); + invoker.execute( + Command::PlaceVia(ViaWeight { + from_layer: 0, + to_layer: 0, + circle: Circle { + pos: point! {x: latest_pos.x as f64, y: -latest_pos.y as f64}, + r: 100.0, + }, + maybe_net: Some(1234), + }), + ); } else if let Some(overlay) = maybe_overlay { - let invoker = invoker_arc_mutex.lock().unwrap(); overlay.click( invoker.autorouter().board(), point! {x: latest_pos.x as f64, y: -latest_pos.y as f64}, @@ -102,9 +87,8 @@ impl Viewport { } } - if let (invoker, shared_data, Some(overlay)) = ( - &invoker_arc_mutex.lock().unwrap(), - shared_data.lock().unwrap(), + if let (Some(invoker), Some(overlay)) = ( + maybe_invoker, maybe_overlay, ) { let board = invoker.autorouter().board(); @@ -115,7 +99,7 @@ impl Viewport { for primitive in board.layout().drawing().layer_primitive_nodes(i) { let shape = primitive.primitive(board.layout().drawing()).shape(); - let color = if shared_data.highlighteds.contains(&primitive) + /*let color = if shared_data.highlighteds.contains(&primitive) || overlay .selection() .contains_node(board, GenericNode::Primitive(primitive)) @@ -123,7 +107,8 @@ impl Viewport { layers.highlight_colors[i] } else { layers.colors[i] - }; + };*/ + let color = layers.colors[i]; painter.paint_primitive(&shape, color); } @@ -167,7 +152,7 @@ impl Viewport { } } - if top.show_navmesh { + /*if top.show_navmesh { if let Some(navmesh) = &shared_data.navmesh { for edge in navmesh.graph().edge_references() { let from = PrimitiveIndex::from(navmesh.graph().node_weight(edge.source()).unwrap().node) @@ -227,7 +212,7 @@ impl Viewport { }, egui::Color32::from_rgb(255, 255, 100), ); - } + }*/ } } diff --git a/src/bin/topola-sdl2-demo/main.rs b/src/bin/topola-sdl2-demo/main.rs index 15c395b..af74e9c 100644 --- a/src/bin/topola-sdl2-demo/main.rs +++ b/src/bin/topola-sdl2-demo/main.rs @@ -47,7 +47,6 @@ use pathfinder_renderer::options::BuildOptions; use pathfinder_resources::embedded::EmbeddedResourceLoader; use std::collections::HashMap; -use std::sync::{Arc, Mutex}; use std::time::Duration; use topola::math::Circle;