mirror of https://codeberg.org/topola/topola.git
egui: remove most of usages of shared-state parallelism
This commit is contained in:
parent
fd5a95103d
commit
6cadcd3b41
|
|
@ -45,16 +45,6 @@ use crate::{
|
|||
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.
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[serde(default)]
|
||||
|
|
@ -63,10 +53,7 @@ pub struct App {
|
|||
overlay: Option<Overlay>,
|
||||
|
||||
#[serde(skip)]
|
||||
invoker: Option<Arc<Mutex<Invoker<SpecctraMesadata>>>>,
|
||||
|
||||
#[serde(skip)]
|
||||
shared_data: Arc<Mutex<SharedData>>,
|
||||
invoker: Arc<Mutex<Option<Invoker<SpecctraMesadata>>>>,
|
||||
|
||||
#[serde(skip)]
|
||||
text_channel: (Sender<String>, Receiver<String>),
|
||||
|
|
@ -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,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -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<Mutex<SharedData>>,
|
||||
sender: Sender<String>,
|
||||
maybe_invoker: &Option<Arc<Mutex<Invoker<SpecctraMesadata>>>>,
|
||||
maybe_invoker: Arc<Mutex<Option<Invoker<SpecctraMesadata>>>>,
|
||||
maybe_overlay: &Option<Overlay>,
|
||||
) {
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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<Mutex<SharedData>>,
|
||||
maybe_invoker: &Option<Arc<Mutex<Invoker<SpecctraMesadata>>>>,
|
||||
maybe_invoker: &mut Option<Invoker<SpecctraMesadata>>,
|
||||
maybe_overlay: &mut Option<Overlay>,
|
||||
maybe_layers: &Option<Layers>,
|
||||
) -> 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),
|
||||
);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue