egui: remove most of usages of shared-state parallelism

This commit is contained in:
Mikolaj Wielgus 2024-06-29 17:11:29 +02:00
parent fd5a95103d
commit 6cadcd3b41
4 changed files with 101 additions and 132 deletions

View File

@ -45,16 +45,6 @@ use crate::{
viewport::Viewport, viewport::Viewport,
}; };
#[derive(Debug, Default)]
pub struct SharedData {
pub from: Option<FixedDotIndex>,
pub to: Option<FixedDotIndex>,
pub navmesh: Option<Navmesh>,
pub path: Vec<BinavvertexNodeIndex>,
pub ghosts: Vec<PrimitiveShape>,
pub highlighteds: Vec<PrimitiveIndex>,
}
/// Deserialize/Serialize is needed to persist app state between restarts. /// Deserialize/Serialize is needed to persist app state between restarts.
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
#[serde(default)] #[serde(default)]
@ -63,10 +53,7 @@ pub struct App {
overlay: Option<Overlay>, overlay: Option<Overlay>,
#[serde(skip)] #[serde(skip)]
invoker: Option<Arc<Mutex<Invoker<SpecctraMesadata>>>>, invoker: Arc<Mutex<Option<Invoker<SpecctraMesadata>>>>,
#[serde(skip)]
shared_data: Arc<Mutex<SharedData>>,
#[serde(skip)] #[serde(skip)]
text_channel: (Sender<String>, Receiver<String>), text_channel: (Sender<String>, Receiver<String>),
@ -88,8 +75,7 @@ impl Default for App {
fn default() -> Self { fn default() -> Self {
Self { Self {
overlay: None, overlay: None,
invoker: None, invoker: Arc::new(Mutex::new(None)),
shared_data: Default::default(),
text_channel: channel(), text_channel: channel(),
viewport: Viewport::new(), viewport: Viewport::new(),
top: Top::new(), top: Top::new(),
@ -125,7 +111,7 @@ impl eframe::App for App {
let board = design.make_board(); let board = design.make_board();
self.overlay = Some(Overlay::new(&board).unwrap()); self.overlay = Some(Overlay::new(&board).unwrap());
self.layers = Some(Layers::new(&board)); 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(), Autorouter::new(board).unwrap(),
)))); ))));
} }
@ -135,7 +121,7 @@ impl eframe::App for App {
let board = design.make_board(); let board = design.make_board();
self.overlay = Some(Overlay::new(&board).unwrap()); self.overlay = Some(Overlay::new(&board).unwrap());
self.layers = Some(Layers::new(&board)); 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(), Autorouter::new(board).unwrap(),
)))); ))));
} }
@ -143,23 +129,21 @@ impl eframe::App for App {
self.top.update( self.top.update(
ctx, ctx,
self.shared_data.clone(),
self.text_channel.0.clone(), self.text_channel.0.clone(),
&self.invoker, self.invoker.clone(),
&mut self.overlay, &mut self.overlay,
); );
if let Some(ref mut layers) = self.layers { if let Some(ref mut layers) = self.layers {
if let Some(invoker_arc_mutex) = &self.invoker { if let Some(invoker) = self.invoker.lock().unwrap().as_ref() {
layers.update(ctx, invoker_arc_mutex.lock().unwrap().autorouter().board()); layers.update(ctx, invoker.autorouter().board());
} }
} }
let viewport_rect = self.viewport.update( let viewport_rect = self.viewport.update(
ctx, ctx,
&self.top, &self.top,
self.shared_data.clone(), &mut self.invoker.lock().unwrap(),
&self.invoker,
&mut self.overlay, &mut self.overlay,
&self.layers, &self.layers,
); );

View File

@ -9,7 +9,7 @@ use topola::{
}; };
use crate::{ use crate::{
app::{channel_text, execute, SharedData}, app::{channel_text, execute},
overlay::Overlay, overlay::Overlay,
}; };
@ -31,9 +31,8 @@ impl Top {
pub fn update( pub fn update(
&mut self, &mut self,
ctx: &egui::Context, ctx: &egui::Context,
shared_data: Arc<Mutex<SharedData>>,
sender: Sender<String>, sender: Sender<String>,
maybe_invoker: &Option<Arc<Mutex<Invoker<SpecctraMesadata>>>>, maybe_invoker: Arc<Mutex<Option<Invoker<SpecctraMesadata>>>>,
maybe_overlay: &Option<Overlay>, maybe_overlay: &Option<Overlay>,
) { ) {
egui::TopBottomPanel::top("top_panel").show(ctx, |ui| { egui::TopBottomPanel::top("top_panel").show(ctx, |ui| {
@ -56,38 +55,52 @@ impl Top {
ui.separator(); ui.separator();
if ui.button("Load history").clicked() { if ui.button("Load history").clicked() {
if let Some(invoker_arc_mutex) = &maybe_invoker { let invoker_arc_mutex = maybe_invoker.clone();
let invoker_arc_mutex = invoker_arc_mutex.clone();
let ctx = ui.ctx().clone(); let ctx = ui.ctx().clone();
let task = rfd::AsyncFileDialog::new().pick_file(); let task = rfd::AsyncFileDialog::new().pick_file();
execute(async move { execute(async move {
if let Some(file_handle) = task.await { let Some(file_handle) = task.await else {
return;
};
let path = file_handle.path(); let path = file_handle.path();
let mut invoker = invoker_arc_mutex.lock().unwrap(); let Ok(mut file) = File::open(path) else {
let mut file = File::open(path).unwrap(); 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()); invoker.replay(serde_json::from_reader(file).unwrap());
}
}); });
} }
}
if ui.button("Save history").clicked() { if ui.button("Save history").clicked() {
if let Some(invoker_arc_mutex) = &maybe_invoker { let invoker_arc_mutex = maybe_invoker.clone();
let invoker_arc_mutex = invoker_arc_mutex.clone();
let ctx = ui.ctx().clone(); let ctx = ui.ctx().clone();
let task = rfd::AsyncFileDialog::new().save_file(); let task = rfd::AsyncFileDialog::new().save_file();
execute(async move { execute(async move {
if let Some(file_handle) = task.await { let Some(file_handle) = task.await else {
return;
};
let path = file_handle.path(); let path = file_handle.path();
let mut invoker = invoker_arc_mutex.lock().unwrap(); let Ok(mut file) = File::create(path) else {
let mut file = File::create(path).unwrap(); 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()); serde_json::to_writer_pretty(file, invoker.history());
}
}); });
} }
}
ui.separator(); ui.separator();
@ -102,31 +115,26 @@ impl Top {
ui.separator(); ui.separator();
if ui.button("Autoroute").clicked() { if ui.button("Autoroute").clicked() {
if let (Some(invoker_arc_mutex), Some(overlay)) = if let (Some(invoker), Some(ref overlay)) =
(&maybe_invoker, &maybe_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 selection = overlay.selection().clone();
execute(async move {
let mut invoker = invoker_arc_mutex.lock().unwrap();
let mut execute = invoker.execute_walk(Command::Autoroute(selection)); let mut execute = invoker.execute_walk(Command::Autoroute(selection));
if let Execute::Autoroute(ref mut autoroute) = execute { if let Execute::Autoroute(ref mut autoroute) = execute {
let from = autoroute.navmesh().as_ref().unwrap().source(); let from = autoroute.navmesh().as_ref().unwrap().source();
let to = autoroute.navmesh().as_ref().unwrap().target(); let to = autoroute.navmesh().as_ref().unwrap().target();
{ /*{
let mut shared_data = shared_data_arc_mutex.lock().unwrap(); let mut shared_data = shared_data_arc_mutex.lock().unwrap();
shared_data.from = Some(from); shared_data.from = Some(from);
shared_data.to = Some(to); shared_data.to = Some(to);
shared_data.navmesh = autoroute.navmesh().cloned(); shared_data.navmesh = autoroute.navmesh().cloned();
} }*/
} }
let _ = loop { let _ = loop {
let status = match execute.step(&mut invoker) { let status = match execute.step(invoker) {
Ok(status) => status, Ok(status) => status,
Err(err) => return, Err(err) => return,
}; };
@ -135,12 +143,11 @@ impl Top {
break; break;
} }
if let Execute::Autoroute(ref mut autoroute) = execute { /*if let Execute::Autoroute(ref mut autoroute) = execute {
shared_data_arc_mutex.lock().unwrap().navmesh = shared_data_arc_mutex.lock().unwrap().navmesh =
autoroute.navmesh().cloned(); autoroute.navmesh().cloned();
} }*/
}; };
});
} }
} }
@ -151,22 +158,16 @@ impl Top {
if ui.button("Undo").clicked() if ui.button("Undo").clicked()
|| ctx.input_mut(|i| i.consume_key(egui::Modifiers::CTRL, egui::Key::Z)) || ctx.input_mut(|i| i.consume_key(egui::Modifiers::CTRL, egui::Key::Z))
{ {
if let Some(invoker_arc_mutex) = &maybe_invoker { if let Some(invoker) = maybe_invoker.lock().unwrap().as_mut() {
let invoker_arc_mutex = invoker_arc_mutex.clone(); invoker.undo();
execute(async move {
invoker_arc_mutex.lock().unwrap().undo();
});
} }
} }
if ui.button("Redo").clicked() if ui.button("Redo").clicked()
|| ctx.input_mut(|i| i.consume_key(egui::Modifiers::CTRL, egui::Key::Y)) || ctx.input_mut(|i| i.consume_key(egui::Modifiers::CTRL, egui::Key::Y))
{ {
if let Some(invoker_arc_mutex) = &maybe_invoker { if let Some(ref mut invoker) = maybe_invoker.lock().unwrap().as_mut() {
let invoker_arc_mutex = invoker_arc_mutex.clone(); invoker.redo();
execute(async move {
invoker_arc_mutex.lock().unwrap().redo();
});
} }
} }

View File

@ -1,5 +1,3 @@
use std::sync::{Arc, Mutex};
use geo::point; use geo::point;
use petgraph::visit::{EdgeRef, IntoEdgeReferences}; use petgraph::visit::{EdgeRef, IntoEdgeReferences};
use topola::{ use topola::{
@ -15,13 +13,7 @@ use topola::{
specctra::mesadata::SpecctraMesadata, specctra::mesadata::SpecctraMesadata,
}; };
use crate::{ use crate::{app::execute, layers::Layers, overlay::Overlay, painter::Painter, top::Top};
app::{execute, SharedData},
layers::Layers,
overlay::Overlay,
painter::Painter,
top::Top,
};
pub struct Viewport { pub struct Viewport {
pub from_rect: egui::emath::Rect, pub from_rect: egui::emath::Rect,
@ -38,8 +30,7 @@ impl Viewport {
&mut self, &mut self,
ctx: &egui::Context, ctx: &egui::Context,
top: &Top, top: &Top,
shared_data: Arc<Mutex<SharedData>>, maybe_invoker: &mut Option<Invoker<SpecctraMesadata>>,
maybe_invoker: &Option<Arc<Mutex<Invoker<SpecctraMesadata>>>>,
maybe_overlay: &mut Option<Overlay>, maybe_overlay: &mut Option<Overlay>,
maybe_layers: &Option<Layers>, maybe_layers: &Option<Layers>,
) -> egui::Rect { ) -> egui::Rect {
@ -74,13 +65,9 @@ impl Viewport {
let transform = egui::emath::RectTransform::from_to(self.from_rect, viewport_rect); let transform = egui::emath::RectTransform::from_to(self.from_rect, viewport_rect);
let mut painter = Painter::new(ui, transform); 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 ctx.input(|i| i.pointer.any_click()) {
if top.is_placing_via { 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( invoker.execute(
Command::PlaceVia(ViaWeight { Command::PlaceVia(ViaWeight {
from_layer: 0, from_layer: 0,
@ -92,9 +79,7 @@ impl Viewport {
maybe_net: Some(1234), maybe_net: Some(1234),
}), }),
); );
});
} else if let Some(overlay) = maybe_overlay { } else if let Some(overlay) = maybe_overlay {
let invoker = invoker_arc_mutex.lock().unwrap();
overlay.click( overlay.click(
invoker.autorouter().board(), invoker.autorouter().board(),
point! {x: latest_pos.x as f64, y: -latest_pos.y as f64}, 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)) = ( if let (Some(invoker), Some(overlay)) = (
&invoker_arc_mutex.lock().unwrap(), maybe_invoker,
shared_data.lock().unwrap(),
maybe_overlay, maybe_overlay,
) { ) {
let board = invoker.autorouter().board(); let board = invoker.autorouter().board();
@ -115,7 +99,7 @@ impl Viewport {
for primitive in board.layout().drawing().layer_primitive_nodes(i) { for primitive in board.layout().drawing().layer_primitive_nodes(i) {
let shape = primitive.primitive(board.layout().drawing()).shape(); 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 || overlay
.selection() .selection()
.contains_node(board, GenericNode::Primitive(primitive)) .contains_node(board, GenericNode::Primitive(primitive))
@ -123,7 +107,8 @@ impl Viewport {
layers.highlight_colors[i] layers.highlight_colors[i]
} else { } else {
layers.colors[i] layers.colors[i]
}; };*/
let color = layers.colors[i];
painter.paint_primitive(&shape, color); 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 { if let Some(navmesh) = &shared_data.navmesh {
for edge in navmesh.graph().edge_references() { for edge in navmesh.graph().edge_references() {
let from = PrimitiveIndex::from(navmesh.graph().node_weight(edge.source()).unwrap().node) 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), egui::Color32::from_rgb(255, 255, 100),
); );
} }*/
} }
} }

View File

@ -47,7 +47,6 @@ use pathfinder_renderer::options::BuildOptions;
use pathfinder_resources::embedded::EmbeddedResourceLoader; use pathfinder_resources::embedded::EmbeddedResourceLoader;
use std::collections::HashMap; use std::collections::HashMap;
use std::sync::{Arc, Mutex};
use std::time::Duration; use std::time::Duration;
use topola::math::Circle; use topola::math::Circle;