mirror of https://codeberg.org/topola/topola.git
egui: perform routing in separate thread or task
This commit is contained in:
parent
682f179cad
commit
4144ee361f
|
|
@ -3,7 +3,10 @@ use geo::point;
|
||||||
use petgraph::visit::{EdgeRef, IntoEdgeReferences};
|
use petgraph::visit::{EdgeRef, IntoEdgeReferences};
|
||||||
use std::{
|
use std::{
|
||||||
future::Future,
|
future::Future,
|
||||||
sync::mpsc::{channel, Receiver, Sender},
|
sync::{
|
||||||
|
mpsc::{channel, Receiver, Sender},
|
||||||
|
Arc, Mutex,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
use topola::{
|
use topola::{
|
||||||
|
|
@ -40,7 +43,7 @@ pub struct App {
|
||||||
overlay: Option<Overlay>,
|
overlay: Option<Overlay>,
|
||||||
|
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
autorouter: Option<Autorouter<DsnRules>>,
|
autorouter: Option<Arc<Mutex<Autorouter<DsnRules>>>>,
|
||||||
|
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
text_channel: (Sender<String>, Receiver<String>),
|
text_channel: (Sender<String>, Receiver<String>),
|
||||||
|
|
@ -108,14 +111,14 @@ impl eframe::App for App {
|
||||||
let design = DsnDesign::load_from_string(file_contents).unwrap();
|
let design = DsnDesign::load_from_string(file_contents).unwrap();
|
||||||
let layout = design.make_layout();
|
let layout = design.make_layout();
|
||||||
self.overlay = Some(Overlay::new(&layout).unwrap());
|
self.overlay = Some(Overlay::new(&layout).unwrap());
|
||||||
self.autorouter = Some(Autorouter::new(layout).unwrap());
|
self.autorouter = Some(Arc::new(Mutex::new(Autorouter::new(layout).unwrap())));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if let Ok(path) = self.text_channel.1.try_recv() {
|
if let Ok(path) = self.text_channel.1.try_recv() {
|
||||||
let design = DsnDesign::load_from_file(&path).unwrap();
|
let design = DsnDesign::load_from_file(&path).unwrap();
|
||||||
let layout = design.make_layout();
|
let layout = design.make_layout();
|
||||||
self.overlay = Some(Overlay::new(&layout).unwrap());
|
self.overlay = Some(Overlay::new(&layout).unwrap());
|
||||||
self.autorouter = Some(Autorouter::new(layout).unwrap());
|
self.autorouter = Some(Arc::new(Mutex::new(Autorouter::new(layout).unwrap())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -150,8 +153,12 @@ impl eframe::App for App {
|
||||||
ui.separator();
|
ui.separator();
|
||||||
|
|
||||||
if ui.button("Autoroute").clicked() {
|
if ui.button("Autoroute").clicked() {
|
||||||
if let Some(ref mut autorouter) = &mut self.autorouter {
|
if let Some(autorouter_arc_mutex) = &self.autorouter {
|
||||||
autorouter.autoroute(&mut EmptyRouterObserver {});
|
let autorouter_mutex = autorouter_arc_mutex.clone();
|
||||||
|
execute(async move {
|
||||||
|
let mut autorouter = autorouter_mutex.lock().unwrap();
|
||||||
|
autorouter.autoroute(&mut EmptyRouterObserver {});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -192,97 +199,102 @@ impl eframe::App for App {
|
||||||
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(autorouter), Some(overlay)) = (&self.autorouter, &mut self.overlay) {
|
if let (Some(autorouter_arc_mutex), Some(overlay)) =
|
||||||
if ctx.input(|i| i.pointer.any_click()) {
|
(&self.autorouter, &mut self.overlay)
|
||||||
overlay.click(
|
{
|
||||||
autorouter.router().layout(),
|
if let Ok(autorouter) = autorouter_arc_mutex.try_lock() {
|
||||||
point! {x: latest_pos.x as f64, y: -latest_pos.y as f64},
|
if ctx.input(|i| i.pointer.any_click()) {
|
||||||
);
|
overlay.click(
|
||||||
}
|
autorouter.router().layout(),
|
||||||
|
point! {x: latest_pos.x as f64, y: -latest_pos.y as f64},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
for primitive in autorouter
|
for primitive in autorouter
|
||||||
.router()
|
.router()
|
||||||
.layout()
|
.layout()
|
||||||
.drawing()
|
.drawing()
|
||||||
.layer_primitive_nodes(1)
|
.layer_primitive_nodes(1)
|
||||||
{
|
|
||||||
let shape = primitive
|
|
||||||
.primitive(autorouter.router().layout().drawing())
|
|
||||||
.shape();
|
|
||||||
|
|
||||||
let color = if overlay
|
|
||||||
.selection()
|
|
||||||
.contains(&GenericNode::Primitive(primitive))
|
|
||||||
{
|
{
|
||||||
egui::Color32::from_rgb(100, 100, 255)
|
let shape = primitive
|
||||||
} else {
|
.primitive(autorouter.router().layout().drawing())
|
||||||
egui::Color32::from_rgb(52, 52, 200)
|
.shape();
|
||||||
};
|
|
||||||
painter.paint_shape(&shape, color);
|
|
||||||
}
|
|
||||||
|
|
||||||
for zone in autorouter.router().layout().layer_zone_nodes(1) {
|
let color = if overlay
|
||||||
let color = if overlay.selection().contains(&GenericNode::Compound(zone)) {
|
.selection()
|
||||||
egui::Color32::from_rgb(100, 100, 255)
|
.contains(&GenericNode::Primitive(primitive))
|
||||||
} else {
|
{
|
||||||
egui::Color32::from_rgb(52, 52, 200)
|
egui::Color32::from_rgb(100, 100, 255)
|
||||||
};
|
} else {
|
||||||
painter.paint_polygon(
|
egui::Color32::from_rgb(52, 52, 200)
|
||||||
&autorouter.router().layout().zone(zone).shape().polygon,
|
};
|
||||||
color,
|
painter.paint_shape(&shape, color);
|
||||||
)
|
}
|
||||||
}
|
|
||||||
|
|
||||||
for primitive in autorouter
|
for zone in autorouter.router().layout().layer_zone_nodes(1) {
|
||||||
.router()
|
let color =
|
||||||
.layout()
|
if overlay.selection().contains(&GenericNode::Compound(zone)) {
|
||||||
.drawing()
|
egui::Color32::from_rgb(100, 100, 255)
|
||||||
.layer_primitive_nodes(0)
|
} else {
|
||||||
{
|
egui::Color32::from_rgb(52, 52, 200)
|
||||||
let shape = primitive
|
};
|
||||||
.primitive(autorouter.router().layout().drawing())
|
painter.paint_polygon(
|
||||||
.shape();
|
&autorouter.router().layout().zone(zone).shape().polygon,
|
||||||
|
color,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
let color = if overlay
|
for primitive in autorouter
|
||||||
.selection()
|
.router()
|
||||||
.contains(&GenericNode::Primitive(primitive))
|
.layout()
|
||||||
|
.drawing()
|
||||||
|
.layer_primitive_nodes(0)
|
||||||
{
|
{
|
||||||
egui::Color32::from_rgb(255, 100, 100)
|
let shape = primitive
|
||||||
} else {
|
.primitive(autorouter.router().layout().drawing())
|
||||||
egui::Color32::from_rgb(200, 52, 52)
|
.shape();
|
||||||
};
|
|
||||||
painter.paint_shape(&shape, color);
|
|
||||||
}
|
|
||||||
|
|
||||||
for zone in autorouter.router().layout().layer_zone_nodes(0) {
|
let color = if overlay
|
||||||
let color = if overlay.selection().contains(&GenericNode::Compound(zone)) {
|
.selection()
|
||||||
egui::Color32::from_rgb(255, 100, 100)
|
.contains(&GenericNode::Primitive(primitive))
|
||||||
} else {
|
{
|
||||||
egui::Color32::from_rgb(200, 52, 52)
|
egui::Color32::from_rgb(255, 100, 100)
|
||||||
};
|
} else {
|
||||||
painter.paint_polygon(
|
egui::Color32::from_rgb(200, 52, 52)
|
||||||
&autorouter.router().layout().zone(zone).shape().polygon,
|
};
|
||||||
color,
|
painter.paint_shape(&shape, color);
|
||||||
)
|
}
|
||||||
}
|
|
||||||
|
|
||||||
for edge in overlay.ratsnest().graph().edge_references() {
|
for zone in autorouter.router().layout().layer_zone_nodes(0) {
|
||||||
let from = overlay
|
let color =
|
||||||
.ratsnest()
|
if overlay.selection().contains(&GenericNode::Compound(zone)) {
|
||||||
.graph()
|
egui::Color32::from_rgb(255, 100, 100)
|
||||||
.node_weight(edge.source())
|
} else {
|
||||||
.unwrap()
|
egui::Color32::from_rgb(200, 52, 52)
|
||||||
.pos;
|
};
|
||||||
let to = overlay
|
painter.paint_polygon(
|
||||||
.ratsnest()
|
&autorouter.router().layout().zone(zone).shape().polygon,
|
||||||
.graph()
|
color,
|
||||||
.node_weight(edge.target())
|
)
|
||||||
.unwrap()
|
}
|
||||||
.pos;
|
|
||||||
|
|
||||||
painter.paint_edge(from, to, egui::Color32::from_rgb(90, 90, 200));
|
for edge in overlay.ratsnest().graph().edge_references() {
|
||||||
|
let from = overlay
|
||||||
|
.ratsnest()
|
||||||
|
.graph()
|
||||||
|
.node_weight(edge.source())
|
||||||
|
.unwrap()
|
||||||
|
.pos;
|
||||||
|
let to = overlay
|
||||||
|
.ratsnest()
|
||||||
|
.graph()
|
||||||
|
.node_weight(edge.target())
|
||||||
|
.unwrap()
|
||||||
|
.pos;
|
||||||
|
|
||||||
|
painter.paint_edge(from, to, egui::Color32::from_rgb(90, 90, 200));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//unreachable!();
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue