From 2259a75d92f009fb6b0dc61733b15c5fdb47ca0b Mon Sep 17 00:00:00 2001 From: Mikolaj Wielgus Date: Mon, 1 Jul 2024 00:50:24 +0200 Subject: [PATCH] egui,autorouter: restore displaying navmesh --- src/autorouter/autoroute.rs | 16 +++++-- src/autorouter/invoker.rs | 47 ++++++++++++++++++++- src/autorouter/place_via.rs | 10 ++++- src/bin/topola-egui/app.rs | 10 ++--- src/bin/topola-egui/top.rs | 13 +++--- src/bin/topola-egui/viewport.rs | 75 +++++++++++++++++---------------- src/router/astar.rs | 3 ++ src/router/route.rs | 1 + src/router/router.rs | 3 ++ 9 files changed, 125 insertions(+), 53 deletions(-) diff --git a/src/autorouter/autoroute.rs b/src/autorouter/autoroute.rs index c9d0805..077eaef 100644 --- a/src/autorouter/autoroute.rs +++ b/src/autorouter/autoroute.rs @@ -1,7 +1,7 @@ use petgraph::graph::EdgeIndex; use crate::{ - autorouter::{Autorouter, AutorouterError, AutorouterStatus}, + autorouter::{invoker::GetMaybeNavmesh, Autorouter, AutorouterError, AutorouterStatus}, board::mesadata::MesadataTrait, router::{navmesh::Navmesh, route::Route, Router, RouterStatus}, }; @@ -40,10 +40,15 @@ impl Autoroute { autorouter: &mut Autorouter, ) -> Result { let Some(ref mut route) = self.route else { + // Shouldn't happen. return Ok(AutorouterStatus::Finished); }; - let (source, target) = autorouter.ratline_endpoints(self.cur_ratline.unwrap()); + let Some(cur_ratline) = self.cur_ratline else { + return Ok(AutorouterStatus::Finished); + }; + + let (source, target) = autorouter.ratline_endpoints(cur_ratline); let band = { let mut router = Router::new(autorouter.board.layout_mut()); @@ -63,7 +68,6 @@ impl Autoroute { .try_set_band_between_nodes(source, target, band); let Some(new_ratline) = self.ratlines_iter.next() else { - self.route = None; self.cur_ratline = None; return Ok(AutorouterStatus::Finished); }; @@ -81,3 +85,9 @@ impl Autoroute { self.route.as_ref().map(|route| route.navmesh()) } } + +impl GetMaybeNavmesh for Autoroute { + fn maybe_navmesh(&self) -> Option<&Navmesh> { + self.route.as_ref().map(|route| route.navmesh()) + } +} diff --git a/src/autorouter/invoker.rs b/src/autorouter/invoker.rs index bd32926..b6a38fa 100644 --- a/src/autorouter/invoker.rs +++ b/src/autorouter/invoker.rs @@ -1,4 +1,5 @@ use contracts::debug_requires; +use enum_dispatch::enum_dispatch; use serde::{Deserialize, Serialize}; use thiserror::Error; @@ -12,8 +13,14 @@ use crate::{ }, board::mesadata::MesadataTrait, layout::via::ViaWeight, + router::navmesh::Navmesh, }; +#[enum_dispatch] +pub trait GetMaybeNavmesh { + fn maybe_navmesh(&self) -> Option<&Navmesh>; +} + #[derive(Error, Debug, Clone)] pub enum InvokerError { #[error(transparent)] @@ -22,6 +29,7 @@ pub enum InvokerError { Autorouter(#[from] AutorouterError), } +#[derive(Debug, Clone, Copy)] pub enum InvokerStatus { Running, Finished, @@ -33,6 +41,7 @@ pub enum Command { PlaceVia(ViaWeight), } +#[enum_dispatch(GetMaybeNavmesh)] pub enum Execute { Autoroute(Autoroute), PlaceVia(PlaceVia), @@ -46,7 +55,10 @@ impl Execute { match self.step_catch_err(invoker) { Ok(InvokerStatus::Running) => Ok(InvokerStatus::Running), Ok(InvokerStatus::Finished) => { - invoker.history.do_(invoker.ongoing_command.take().unwrap()); + if let Some(command) = invoker.ongoing_command.take() { + invoker.history.do_(command); + } + Ok(InvokerStatus::Finished) } Err(err) => { @@ -73,6 +85,39 @@ impl Execute { } } +pub struct ExecuteWithStatus { + execute: Execute, + maybe_status: Option, +} + +impl ExecuteWithStatus { + pub fn new(execute: Execute) -> ExecuteWithStatus { + Self { + execute, + maybe_status: None, + } + } + + pub fn step( + &mut self, + invoker: &mut Invoker, + ) -> Result { + let status = self.execute.step(invoker)?; + self.maybe_status = Some(status); + Ok(status) + } + + pub fn maybe_status(&self) -> Option { + self.maybe_status + } +} + +impl GetMaybeNavmesh for ExecuteWithStatus { + fn maybe_navmesh(&self) -> Option<&Navmesh> { + self.execute.maybe_navmesh() + } +} + pub struct Invoker { autorouter: Autorouter, history: History, diff --git a/src/autorouter/place_via.rs b/src/autorouter/place_via.rs index c77c0ef..5307502 100644 --- a/src/autorouter/place_via.rs +++ b/src/autorouter/place_via.rs @@ -1,9 +1,11 @@ use crate::{ - autorouter::{Autorouter, AutorouterError}, + autorouter::{invoker::GetMaybeNavmesh, Autorouter, AutorouterError}, board::mesadata::MesadataTrait, layout::via::ViaWeight, + router::navmesh::Navmesh, }; +#[derive(Debug)] pub struct PlaceVia { weight: ViaWeight, } @@ -20,3 +22,9 @@ impl PlaceVia { autorouter.place_via(self.weight) } } + +impl GetMaybeNavmesh for PlaceVia { + fn maybe_navmesh(&self) -> Option<&Navmesh> { + None + } +} diff --git a/src/bin/topola-egui/app.rs b/src/bin/topola-egui/app.rs index cbb9652..6c0baa5 100644 --- a/src/bin/topola-egui/app.rs +++ b/src/bin/topola-egui/app.rs @@ -13,7 +13,7 @@ use std::{ use topola::{ autorouter::{ - invoker::{Command, Execute, Invoker, InvokerStatus}, + invoker::{Command, Execute, ExecuteWithStatus, Invoker, InvokerStatus}, Autorouter, }, drawing::{ @@ -56,7 +56,7 @@ pub struct App { arc_mutex_maybe_invoker: Arc>>>, #[serde(skip)] - maybe_execute: Option, + maybe_execute: Option, #[serde(skip)] text_channel: (Sender, Receiver), @@ -129,11 +129,6 @@ impl App { Ok(status) => status, Err(err) => return, }; - - if let InvokerStatus::Finished = status { - self.maybe_execute = None; - return; - } } } } @@ -167,6 +162,7 @@ impl eframe::App for App { ctx, &self.top, &mut self.arc_mutex_maybe_invoker.lock().unwrap(), + &mut self.maybe_execute, &mut self.maybe_overlay, &self.maybe_layers, ); diff --git a/src/bin/topola-egui/top.rs b/src/bin/topola-egui/top.rs index 86412a8..65d0cc6 100644 --- a/src/bin/topola-egui/top.rs +++ b/src/bin/topola-egui/top.rs @@ -4,7 +4,7 @@ use std::{ }; use topola::{ - autorouter::invoker::{Command, Execute, Invoker, InvokerStatus}, + autorouter::invoker::{Command, Execute, ExecuteWithStatus, Invoker, InvokerStatus}, specctra::mesadata::SpecctraMesadata, }; @@ -33,7 +33,7 @@ impl Top { ctx: &egui::Context, sender: Sender, arc_mutex_maybe_invoker: Arc>>>, - maybe_execute: &mut Option, + maybe_execute: &mut Option, maybe_overlay: &Option, ) { egui::TopBottomPanel::top("top_panel").show(ctx, |ui| { @@ -116,14 +116,17 @@ impl Top { ui.separator(); if ui.button("Autoroute").clicked() { - if maybe_execute.is_none() { + if maybe_execute.as_mut().map_or(true, |execute| { + matches!(execute.maybe_status(), Some(InvokerStatus::Finished)) + }) { if let (Some(invoker), Some(ref overlay)) = ( arc_mutex_maybe_invoker.lock().unwrap().as_mut(), maybe_overlay, ) { let selection = overlay.selection().clone(); - maybe_execute - .insert(invoker.execute_walk(Command::Autoroute(selection))); + maybe_execute.insert(ExecuteWithStatus::new( + invoker.execute_walk(Command::Autoroute(selection)), + )); } } } diff --git a/src/bin/topola-egui/viewport.rs b/src/bin/topola-egui/viewport.rs index 082ce82..ad83433 100644 --- a/src/bin/topola-egui/viewport.rs +++ b/src/bin/topola-egui/viewport.rs @@ -1,7 +1,7 @@ use geo::point; use petgraph::visit::{EdgeRef, IntoEdgeReferences}; use topola::{ - autorouter::invoker::{Command, Invoker}, + autorouter::invoker::{Command, ExecuteWithStatus, GetMaybeNavmesh, Invoker}, board::mesadata::MesadataTrait, drawing::{ graph::{MakePrimitive, PrimitiveIndex}, @@ -31,6 +31,7 @@ impl Viewport { ctx: &egui::Context, top: &Top, maybe_invoker: &mut Option>, + maybe_execute: &mut Option, maybe_overlay: &mut Option, maybe_layers: &Option, ) -> egui::Rect { @@ -152,48 +153,50 @@ impl Viewport { } } - /*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) - .primitive(board.layout().drawing()) - .shape() - .center(); - let to = PrimitiveIndex::from(navmesh.graph().node_weight(edge.target()).unwrap().node) - .primitive(board.layout().drawing()) - .shape() - .center(); + if top.show_navmesh { + if let Some(execute) = maybe_execute { + if let Some(navmesh) = execute.maybe_navmesh() { + for edge in navmesh.graph().edge_references() { + let from = PrimitiveIndex::from(navmesh.graph().node_weight(edge.source()).unwrap().node) + .primitive(board.layout().drawing()) + .shape() + .center(); + let to = PrimitiveIndex::from(navmesh.graph().node_weight(edge.target()).unwrap().node) + .primitive(board.layout().drawing()) + .shape() + .center(); - let stroke = 'blk: { - if let (Some(source_pos), Some(target_pos)) = ( - shared_data - .path - .iter() - .position(|node| *node == navmesh.graph().node_weight(edge.source()).unwrap().node), - shared_data - .path - .iter() - .position(|node| *node == navmesh.graph().node_weight(edge.target()).unwrap().node), - ) { - if target_pos == source_pos + 1 - || source_pos == target_pos + 1 - { - break 'blk egui::Stroke::new( - 5.0, - egui::Color32::from_rgb(250, 250, 0), - ); - } - } + let stroke = 'blk: { + /*if let (Some(source_pos), Some(target_pos)) = ( + shared_data + .path + .iter() + .position(|node| *node == navmesh.graph().node_weight(edge.source()).unwrap().node), + shared_data + .path + .iter() + .position(|node| *node == navmesh.graph().node_weight(edge.target()).unwrap().node), + ) { + if target_pos == source_pos + 1 + || source_pos == target_pos + 1 + { + break 'blk egui::Stroke::new( + 5.0, + egui::Color32::from_rgb(250, 250, 0), + ); + } + }*/ - egui::Stroke::new(1.0, egui::Color32::from_rgb(125, 125, 125)) - }; + egui::Stroke::new(1.0, egui::Color32::from_rgb(125, 125, 125)) + }; - painter.paint_edge(from, to, stroke); + painter.paint_edge(from, to, stroke); + } } } } - for ghost in shared_data.ghosts.iter() { + /*for ghost in shared_data.ghosts.iter() { painter.paint_primitive(&ghost, egui::Color32::from_rgb(75, 75, 150)); } diff --git a/src/router/astar.rs b/src/router/astar.rs index 3064357..e9df77d 100644 --- a/src/router/astar.rs +++ b/src/router/astar.rs @@ -57,6 +57,7 @@ impl Ord for MinScored { } } +#[derive(Debug)] pub struct PathTracker where G: GraphBase, @@ -111,6 +112,7 @@ where fn estimate_cost(&mut self, graph: &G, node: G::NodeId) -> K; } +#[derive(Debug)] pub struct Astar where G: GraphBase, @@ -131,6 +133,7 @@ pub enum AstarError { NotFound, } +#[derive(Debug)] pub enum AstarStatus where G: GraphBase, diff --git a/src/router/route.rs b/src/router/route.rs index 12d32e0..208e225 100644 --- a/src/router/route.rs +++ b/src/router/route.rs @@ -31,6 +31,7 @@ use crate::{ }, }; +#[derive(Debug)] pub struct Route { astar: Astar, trace: Trace, diff --git a/src/router/router.rs b/src/router/router.rs index 18c6a63..42fda8a 100644 --- a/src/router/router.rs +++ b/src/router/router.rs @@ -30,11 +30,13 @@ pub enum RouterError { Astar(#[from] AstarError), } +#[derive(Debug)] pub enum RouterStatus { Running, Finished(BandFirstSegIndex), } +#[derive(Debug)] pub struct RouterAstarStrategy<'a, R: RulesTrait> { pub tracer: Tracer<'a, R>, pub trace: &'a mut Trace, @@ -142,6 +144,7 @@ impl<'a, R: RulesTrait> AstarStrategy } } +#[derive(Debug)] pub struct Router<'a, R: RulesTrait> { layout: &'a mut Layout, }