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,
|
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,
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -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();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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),
|
||||||
);
|
);
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue