autorouter: move ratsnest to `Autorouter`, move overlay to egui module

This commit is contained in:
Mikolaj Wielgus 2024-04-27 01:12:01 +02:00
parent 81f9f82f40
commit c74e69a5e9
5 changed files with 40 additions and 50 deletions

View File

@ -3,7 +3,7 @@ use petgraph::visit::{EdgeRef, IntoEdgeReferences};
use spade::InsertionError; use spade::InsertionError;
use crate::{ use crate::{
autorouter::{overlay::Overlay, ratsnest::RatsnestVertexIndex}, autorouter::ratsnest::{Ratsnest, RatsnestVertexIndex},
drawing::rules::RulesTrait, drawing::rules::RulesTrait,
layout::Layout, layout::Layout,
router::Router, router::Router,
@ -11,14 +11,14 @@ use crate::{
}; };
pub struct Autorouter<R: RulesTrait> { pub struct Autorouter<R: RulesTrait> {
overlay: Overlay, ratsnest: Ratsnest,
router: Router<R>, router: Router<R>,
} }
impl<R: RulesTrait> Autorouter<R> { impl<R: RulesTrait> Autorouter<R> {
pub fn new(layout: Layout<R>) -> Result<Self, InsertionError> { pub fn new(layout: Layout<R>) -> Result<Self, InsertionError> {
Ok(Self { Ok(Self {
overlay: Overlay::new(&layout)?, ratsnest: Ratsnest::new(&layout)?,
router: Router::new(layout), router: Router::new(layout),
}) })
} }
@ -27,23 +27,15 @@ impl<R: RulesTrait> Autorouter<R> {
//for ratline in self.overlay.ratsnest().graph().edge_references() { //for ratline in self.overlay.ratsnest().graph().edge_references() {
// For now, let's only take the first ratline. // For now, let's only take the first ratline.
let ratline = self let ratline = self.ratsnest.graph().edge_references().next().unwrap();
.overlay
.ratsnest()
.graph()
.edge_references()
.next()
.unwrap();
self.route( self.route(
self.overlay self.ratsnest
.ratsnest()
.graph() .graph()
.node_weight(ratline.source()) .node_weight(ratline.source())
.unwrap() .unwrap()
.vertex_index(), .vertex_index(),
self.overlay self.ratsnest
.ratsnest()
.graph() .graph()
.node_weight(ratline.target()) .node_weight(ratline.target())
.unwrap() .unwrap()
@ -57,15 +49,6 @@ impl<R: RulesTrait> Autorouter<R> {
todo!(); todo!();
} }
// TODO: Move somewhere higher in abstraction.
pub fn click(&mut self, at: Point) {
self.overlay.click(self.router.layout(), at);
}
pub fn overlay(&self) -> &Overlay {
&self.overlay
}
pub fn router(&self) -> &Router<R> { pub fn router(&self) -> &Router<R> {
&self.router &self.router
} }

View File

@ -1,5 +1,4 @@
mod autorouter; mod autorouter;
pub mod overlay;
pub mod ratsnest; pub mod ratsnest;
pub use autorouter::*; pub use autorouter::*;

View File

@ -7,7 +7,7 @@ use std::{
}; };
use topola::{ use topola::{
autorouter::{overlay::Overlay, Autorouter}, autorouter::Autorouter,
drawing::{graph::MakePrimitive, primitive::MakePrimitiveShape, Drawing}, drawing::{graph::MakePrimitive, primitive::MakePrimitiveShape, Drawing},
dsn::{design::DsnDesign, rules::DsnRules}, dsn::{design::DsnDesign, rules::DsnRules},
geometry::{ geometry::{
@ -19,12 +19,15 @@ use topola::{
math::Circle, math::Circle,
}; };
use crate::painter::Painter; use crate::{overlay::Overlay, painter::Painter};
/// Deserialize/Serialize is needed to persist app state between restarts. /// Deserialize/Serialize is needed to persist app state between restarts.
#[derive(serde::Deserialize, serde::Serialize)] #[derive(serde::Deserialize, serde::Serialize)]
#[serde(default)] #[serde(default)]
pub struct App { pub struct App {
#[serde(skip)]
overlay: Option<Overlay>,
#[serde(skip)] #[serde(skip)]
autorouter: Option<Autorouter<DsnRules>>, autorouter: Option<Autorouter<DsnRules>>,
@ -38,6 +41,7 @@ pub struct App {
impl Default for App { impl Default for App {
fn default() -> Self { fn default() -> Self {
Self { Self {
overlay: None,
autorouter: None, autorouter: None,
text_channel: channel(), text_channel: channel(),
from_rect: egui::Rect::from_x_y_ranges(0.0..=1000000.0, 0.0..=500000.0), from_rect: egui::Rect::from_x_y_ranges(0.0..=1000000.0, 0.0..=500000.0),
@ -69,13 +73,15 @@ impl eframe::App for App {
if let Ok(file_contents) = self.text_channel.1.try_recv() { if let Ok(file_contents) = self.text_channel.1.try_recv() {
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.autorouter = Some(Autorouter::new(design.make_layout()).unwrap()); self.overlay = Some(Overlay::new(&layout).unwrap());
self.autorouter = Some(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.autorouter = Some(Autorouter::new(design.make_layout()).unwrap()); self.overlay = Some(Overlay::new(&layout).unwrap());
self.autorouter = Some(Autorouter::new(layout).unwrap());
} }
} }
@ -143,9 +149,12 @@ 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(ref mut autorouter) = &mut self.autorouter { if let (Some(autorouter), Some(overlay)) = (&self.autorouter, &mut self.overlay) {
if ctx.input(|i| i.pointer.any_click()) { if ctx.input(|i| i.pointer.any_click()) {
autorouter.click(point! {x: latest_pos.x as f64, y: -latest_pos.y as f64}); 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
@ -158,8 +167,7 @@ impl eframe::App for App {
.primitive(autorouter.router().layout().drawing()) .primitive(autorouter.router().layout().drawing())
.shape(); .shape();
let color = if autorouter let color = if overlay
.overlay()
.selection() .selection()
.contains(&GenericNode::Primitive(primitive)) .contains(&GenericNode::Primitive(primitive))
{ {
@ -171,11 +179,7 @@ impl eframe::App for App {
} }
for zone in autorouter.router().layout().layer_zones(1) { for zone in autorouter.router().layout().layer_zones(1) {
let color = if autorouter let color = if overlay.selection().contains(&GenericNode::Compound(zone)) {
.overlay()
.selection()
.contains(&GenericNode::Compound(zone))
{
egui::Color32::from_rgb(100, 100, 255) egui::Color32::from_rgb(100, 100, 255)
} else { } else {
egui::Color32::from_rgb(52, 52, 200) egui::Color32::from_rgb(52, 52, 200)
@ -201,8 +205,7 @@ impl eframe::App for App {
.primitive(autorouter.router().layout().drawing()) .primitive(autorouter.router().layout().drawing())
.shape(); .shape();
let color = if autorouter let color = if overlay
.overlay()
.selection() .selection()
.contains(&GenericNode::Primitive(primitive)) .contains(&GenericNode::Primitive(primitive))
{ {
@ -214,11 +217,7 @@ impl eframe::App for App {
} }
for zone in autorouter.router().layout().layer_zones(0) { for zone in autorouter.router().layout().layer_zones(0) {
let color = if autorouter let color = if overlay.selection().contains(&GenericNode::Compound(zone)) {
.overlay()
.selection()
.contains(&GenericNode::Compound(zone))
{
egui::Color32::from_rgb(255, 100, 100) egui::Color32::from_rgb(255, 100, 100)
} else { } else {
egui::Color32::from_rgb(200, 52, 52) egui::Color32::from_rgb(200, 52, 52)
@ -234,11 +233,19 @@ impl eframe::App for App {
) )
} }
let ratsnest = autorouter.overlay().ratsnest().graph(); for edge in overlay.ratsnest().graph().edge_references() {
let from = overlay
for ratline in ratsnest.edge_references() { .ratsnest()
let from = ratsnest.node_weight(ratline.source()).unwrap().pos; .graph()
let to = ratsnest.node_weight(ratline.target()).unwrap().pos; .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)); painter.paint_edge(from, to, egui::Color32::from_rgb(90, 90, 200));
} }

View File

@ -1,6 +1,7 @@
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] // hide console window on Windows in release #![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] // hide console window on Windows in release
mod app; mod app;
mod overlay;
mod painter; mod painter;
use app::App; use app::App;

View File

@ -4,7 +4,7 @@ use geo::Point;
use rstar::AABB; use rstar::AABB;
use spade::InsertionError; use spade::InsertionError;
use crate::{ use topola::{
autorouter::ratsnest::Ratsnest, autorouter::ratsnest::Ratsnest,
drawing::{ drawing::{
graph::{GetLayer, MakePrimitive}, graph::{GetLayer, MakePrimitive},