mirror of https://codeberg.org/topola/topola.git
egui,autorouter: restore displaying navmesh
This commit is contained in:
parent
ee6eeac6d8
commit
2259a75d92
|
|
@ -1,7 +1,7 @@
|
||||||
use petgraph::graph::EdgeIndex;
|
use petgraph::graph::EdgeIndex;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
autorouter::{Autorouter, AutorouterError, AutorouterStatus},
|
autorouter::{invoker::GetMaybeNavmesh, Autorouter, AutorouterError, AutorouterStatus},
|
||||||
board::mesadata::MesadataTrait,
|
board::mesadata::MesadataTrait,
|
||||||
router::{navmesh::Navmesh, route::Route, Router, RouterStatus},
|
router::{navmesh::Navmesh, route::Route, Router, RouterStatus},
|
||||||
};
|
};
|
||||||
|
|
@ -40,10 +40,15 @@ impl Autoroute {
|
||||||
autorouter: &mut Autorouter<M>,
|
autorouter: &mut Autorouter<M>,
|
||||||
) -> Result<AutorouterStatus, AutorouterError> {
|
) -> Result<AutorouterStatus, AutorouterError> {
|
||||||
let Some(ref mut route) = self.route else {
|
let Some(ref mut route) = self.route else {
|
||||||
|
// Shouldn't happen.
|
||||||
return Ok(AutorouterStatus::Finished);
|
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 band = {
|
||||||
let mut router = Router::new(autorouter.board.layout_mut());
|
let mut router = Router::new(autorouter.board.layout_mut());
|
||||||
|
|
@ -63,7 +68,6 @@ impl Autoroute {
|
||||||
.try_set_band_between_nodes(source, target, band);
|
.try_set_band_between_nodes(source, target, band);
|
||||||
|
|
||||||
let Some(new_ratline) = self.ratlines_iter.next() else {
|
let Some(new_ratline) = self.ratlines_iter.next() else {
|
||||||
self.route = None;
|
|
||||||
self.cur_ratline = None;
|
self.cur_ratline = None;
|
||||||
return Ok(AutorouterStatus::Finished);
|
return Ok(AutorouterStatus::Finished);
|
||||||
};
|
};
|
||||||
|
|
@ -81,3 +85,9 @@ impl Autoroute {
|
||||||
self.route.as_ref().map(|route| route.navmesh())
|
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())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
use contracts::debug_requires;
|
use contracts::debug_requires;
|
||||||
|
use enum_dispatch::enum_dispatch;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
|
|
@ -12,8 +13,14 @@ use crate::{
|
||||||
},
|
},
|
||||||
board::mesadata::MesadataTrait,
|
board::mesadata::MesadataTrait,
|
||||||
layout::via::ViaWeight,
|
layout::via::ViaWeight,
|
||||||
|
router::navmesh::Navmesh,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[enum_dispatch]
|
||||||
|
pub trait GetMaybeNavmesh {
|
||||||
|
fn maybe_navmesh(&self) -> Option<&Navmesh>;
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Error, Debug, Clone)]
|
#[derive(Error, Debug, Clone)]
|
||||||
pub enum InvokerError {
|
pub enum InvokerError {
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
|
|
@ -22,6 +29,7 @@ pub enum InvokerError {
|
||||||
Autorouter(#[from] AutorouterError),
|
Autorouter(#[from] AutorouterError),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub enum InvokerStatus {
|
pub enum InvokerStatus {
|
||||||
Running,
|
Running,
|
||||||
Finished,
|
Finished,
|
||||||
|
|
@ -33,6 +41,7 @@ pub enum Command {
|
||||||
PlaceVia(ViaWeight),
|
PlaceVia(ViaWeight),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[enum_dispatch(GetMaybeNavmesh)]
|
||||||
pub enum Execute {
|
pub enum Execute {
|
||||||
Autoroute(Autoroute),
|
Autoroute(Autoroute),
|
||||||
PlaceVia(PlaceVia),
|
PlaceVia(PlaceVia),
|
||||||
|
|
@ -46,7 +55,10 @@ impl Execute {
|
||||||
match self.step_catch_err(invoker) {
|
match self.step_catch_err(invoker) {
|
||||||
Ok(InvokerStatus::Running) => Ok(InvokerStatus::Running),
|
Ok(InvokerStatus::Running) => Ok(InvokerStatus::Running),
|
||||||
Ok(InvokerStatus::Finished) => {
|
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)
|
Ok(InvokerStatus::Finished)
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
|
|
@ -73,6 +85,39 @@ impl Execute {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct ExecuteWithStatus {
|
||||||
|
execute: Execute,
|
||||||
|
maybe_status: Option<InvokerStatus>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ExecuteWithStatus {
|
||||||
|
pub fn new(execute: Execute) -> ExecuteWithStatus {
|
||||||
|
Self {
|
||||||
|
execute,
|
||||||
|
maybe_status: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn step<M: MesadataTrait>(
|
||||||
|
&mut self,
|
||||||
|
invoker: &mut Invoker<M>,
|
||||||
|
) -> Result<InvokerStatus, InvokerError> {
|
||||||
|
let status = self.execute.step(invoker)?;
|
||||||
|
self.maybe_status = Some(status);
|
||||||
|
Ok(status)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn maybe_status(&self) -> Option<InvokerStatus> {
|
||||||
|
self.maybe_status
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GetMaybeNavmesh for ExecuteWithStatus {
|
||||||
|
fn maybe_navmesh(&self) -> Option<&Navmesh> {
|
||||||
|
self.execute.maybe_navmesh()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Invoker<M: MesadataTrait> {
|
pub struct Invoker<M: MesadataTrait> {
|
||||||
autorouter: Autorouter<M>,
|
autorouter: Autorouter<M>,
|
||||||
history: History,
|
history: History,
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,11 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
autorouter::{Autorouter, AutorouterError},
|
autorouter::{invoker::GetMaybeNavmesh, Autorouter, AutorouterError},
|
||||||
board::mesadata::MesadataTrait,
|
board::mesadata::MesadataTrait,
|
||||||
layout::via::ViaWeight,
|
layout::via::ViaWeight,
|
||||||
|
router::navmesh::Navmesh,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct PlaceVia {
|
pub struct PlaceVia {
|
||||||
weight: ViaWeight,
|
weight: ViaWeight,
|
||||||
}
|
}
|
||||||
|
|
@ -20,3 +22,9 @@ impl PlaceVia {
|
||||||
autorouter.place_via(self.weight)
|
autorouter.place_via(self.weight)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl GetMaybeNavmesh for PlaceVia {
|
||||||
|
fn maybe_navmesh(&self) -> Option<&Navmesh> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ use std::{
|
||||||
|
|
||||||
use topola::{
|
use topola::{
|
||||||
autorouter::{
|
autorouter::{
|
||||||
invoker::{Command, Execute, Invoker, InvokerStatus},
|
invoker::{Command, Execute, ExecuteWithStatus, Invoker, InvokerStatus},
|
||||||
Autorouter,
|
Autorouter,
|
||||||
},
|
},
|
||||||
drawing::{
|
drawing::{
|
||||||
|
|
@ -56,7 +56,7 @@ pub struct App {
|
||||||
arc_mutex_maybe_invoker: Arc<Mutex<Option<Invoker<SpecctraMesadata>>>>,
|
arc_mutex_maybe_invoker: Arc<Mutex<Option<Invoker<SpecctraMesadata>>>>,
|
||||||
|
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
maybe_execute: Option<Execute>,
|
maybe_execute: Option<ExecuteWithStatus>,
|
||||||
|
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
text_channel: (Sender<String>, Receiver<String>),
|
text_channel: (Sender<String>, Receiver<String>),
|
||||||
|
|
@ -129,11 +129,6 @@ impl App {
|
||||||
Ok(status) => status,
|
Ok(status) => status,
|
||||||
Err(err) => return,
|
Err(err) => return,
|
||||||
};
|
};
|
||||||
|
|
||||||
if let InvokerStatus::Finished = status {
|
|
||||||
self.maybe_execute = None;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -167,6 +162,7 @@ impl eframe::App for App {
|
||||||
ctx,
|
ctx,
|
||||||
&self.top,
|
&self.top,
|
||||||
&mut self.arc_mutex_maybe_invoker.lock().unwrap(),
|
&mut self.arc_mutex_maybe_invoker.lock().unwrap(),
|
||||||
|
&mut self.maybe_execute,
|
||||||
&mut self.maybe_overlay,
|
&mut self.maybe_overlay,
|
||||||
&self.maybe_layers,
|
&self.maybe_layers,
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ use std::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use topola::{
|
use topola::{
|
||||||
autorouter::invoker::{Command, Execute, Invoker, InvokerStatus},
|
autorouter::invoker::{Command, Execute, ExecuteWithStatus, Invoker, InvokerStatus},
|
||||||
specctra::mesadata::SpecctraMesadata,
|
specctra::mesadata::SpecctraMesadata,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -33,7 +33,7 @@ impl Top {
|
||||||
ctx: &egui::Context,
|
ctx: &egui::Context,
|
||||||
sender: Sender<String>,
|
sender: Sender<String>,
|
||||||
arc_mutex_maybe_invoker: Arc<Mutex<Option<Invoker<SpecctraMesadata>>>>,
|
arc_mutex_maybe_invoker: Arc<Mutex<Option<Invoker<SpecctraMesadata>>>>,
|
||||||
maybe_execute: &mut Option<Execute>,
|
maybe_execute: &mut Option<ExecuteWithStatus>,
|
||||||
maybe_overlay: &Option<Overlay>,
|
maybe_overlay: &Option<Overlay>,
|
||||||
) {
|
) {
|
||||||
egui::TopBottomPanel::top("top_panel").show(ctx, |ui| {
|
egui::TopBottomPanel::top("top_panel").show(ctx, |ui| {
|
||||||
|
|
@ -116,14 +116,17 @@ impl Top {
|
||||||
ui.separator();
|
ui.separator();
|
||||||
|
|
||||||
if ui.button("Autoroute").clicked() {
|
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)) = (
|
if let (Some(invoker), Some(ref overlay)) = (
|
||||||
arc_mutex_maybe_invoker.lock().unwrap().as_mut(),
|
arc_mutex_maybe_invoker.lock().unwrap().as_mut(),
|
||||||
maybe_overlay,
|
maybe_overlay,
|
||||||
) {
|
) {
|
||||||
let selection = overlay.selection().clone();
|
let selection = overlay.selection().clone();
|
||||||
maybe_execute
|
maybe_execute.insert(ExecuteWithStatus::new(
|
||||||
.insert(invoker.execute_walk(Command::Autoroute(selection)));
|
invoker.execute_walk(Command::Autoroute(selection)),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
use geo::point;
|
use geo::point;
|
||||||
use petgraph::visit::{EdgeRef, IntoEdgeReferences};
|
use petgraph::visit::{EdgeRef, IntoEdgeReferences};
|
||||||
use topola::{
|
use topola::{
|
||||||
autorouter::invoker::{Command, Invoker},
|
autorouter::invoker::{Command, ExecuteWithStatus, GetMaybeNavmesh, Invoker},
|
||||||
board::mesadata::MesadataTrait,
|
board::mesadata::MesadataTrait,
|
||||||
drawing::{
|
drawing::{
|
||||||
graph::{MakePrimitive, PrimitiveIndex},
|
graph::{MakePrimitive, PrimitiveIndex},
|
||||||
|
|
@ -31,6 +31,7 @@ impl Viewport {
|
||||||
ctx: &egui::Context,
|
ctx: &egui::Context,
|
||||||
top: &Top,
|
top: &Top,
|
||||||
maybe_invoker: &mut Option<Invoker<SpecctraMesadata>>,
|
maybe_invoker: &mut Option<Invoker<SpecctraMesadata>>,
|
||||||
|
maybe_execute: &mut Option<ExecuteWithStatus>,
|
||||||
maybe_overlay: &mut Option<Overlay>,
|
maybe_overlay: &mut Option<Overlay>,
|
||||||
maybe_layers: &Option<Layers>,
|
maybe_layers: &Option<Layers>,
|
||||||
) -> egui::Rect {
|
) -> egui::Rect {
|
||||||
|
|
@ -152,48 +153,50 @@ impl Viewport {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*if top.show_navmesh {
|
if top.show_navmesh {
|
||||||
if let Some(navmesh) = &shared_data.navmesh {
|
if let Some(execute) = maybe_execute {
|
||||||
for edge in navmesh.graph().edge_references() {
|
if let Some(navmesh) = execute.maybe_navmesh() {
|
||||||
let from = PrimitiveIndex::from(navmesh.graph().node_weight(edge.source()).unwrap().node)
|
for edge in navmesh.graph().edge_references() {
|
||||||
.primitive(board.layout().drawing())
|
let from = PrimitiveIndex::from(navmesh.graph().node_weight(edge.source()).unwrap().node)
|
||||||
.shape()
|
.primitive(board.layout().drawing())
|
||||||
.center();
|
.shape()
|
||||||
let to = PrimitiveIndex::from(navmesh.graph().node_weight(edge.target()).unwrap().node)
|
.center();
|
||||||
.primitive(board.layout().drawing())
|
let to = PrimitiveIndex::from(navmesh.graph().node_weight(edge.target()).unwrap().node)
|
||||||
.shape()
|
.primitive(board.layout().drawing())
|
||||||
.center();
|
.shape()
|
||||||
|
.center();
|
||||||
|
|
||||||
let stroke = 'blk: {
|
let stroke = 'blk: {
|
||||||
if let (Some(source_pos), Some(target_pos)) = (
|
/*if let (Some(source_pos), Some(target_pos)) = (
|
||||||
shared_data
|
shared_data
|
||||||
.path
|
.path
|
||||||
.iter()
|
.iter()
|
||||||
.position(|node| *node == navmesh.graph().node_weight(edge.source()).unwrap().node),
|
.position(|node| *node == navmesh.graph().node_weight(edge.source()).unwrap().node),
|
||||||
shared_data
|
shared_data
|
||||||
.path
|
.path
|
||||||
.iter()
|
.iter()
|
||||||
.position(|node| *node == navmesh.graph().node_weight(edge.target()).unwrap().node),
|
.position(|node| *node == navmesh.graph().node_weight(edge.target()).unwrap().node),
|
||||||
) {
|
) {
|
||||||
if target_pos == source_pos + 1
|
if target_pos == source_pos + 1
|
||||||
|| source_pos == target_pos + 1
|
|| source_pos == target_pos + 1
|
||||||
{
|
{
|
||||||
break 'blk egui::Stroke::new(
|
break 'blk egui::Stroke::new(
|
||||||
5.0,
|
5.0,
|
||||||
egui::Color32::from_rgb(250, 250, 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));
|
painter.paint_primitive(&ghost, egui::Color32::from_rgb(75, 75, 150));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,7 @@ impl<K: PartialOrd, T> Ord for MinScored<K, T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct PathTracker<G>
|
pub struct PathTracker<G>
|
||||||
where
|
where
|
||||||
G: GraphBase,
|
G: GraphBase,
|
||||||
|
|
@ -111,6 +112,7 @@ where
|
||||||
fn estimate_cost(&mut self, graph: &G, node: G::NodeId) -> K;
|
fn estimate_cost(&mut self, graph: &G, node: G::NodeId) -> K;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct Astar<G, K>
|
pub struct Astar<G, K>
|
||||||
where
|
where
|
||||||
G: GraphBase,
|
G: GraphBase,
|
||||||
|
|
@ -131,6 +133,7 @@ pub enum AstarError {
|
||||||
NotFound,
|
NotFound,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub enum AstarStatus<G, K, R>
|
pub enum AstarStatus<G, K, R>
|
||||||
where
|
where
|
||||||
G: GraphBase,
|
G: GraphBase,
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ use crate::{
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct Route {
|
pub struct Route {
|
||||||
astar: Astar<Navmesh, f64>,
|
astar: Astar<Navmesh, f64>,
|
||||||
trace: Trace,
|
trace: Trace,
|
||||||
|
|
|
||||||
|
|
@ -30,11 +30,13 @@ pub enum RouterError {
|
||||||
Astar(#[from] AstarError),
|
Astar(#[from] AstarError),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub enum RouterStatus {
|
pub enum RouterStatus {
|
||||||
Running,
|
Running,
|
||||||
Finished(BandFirstSegIndex),
|
Finished(BandFirstSegIndex),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct RouterAstarStrategy<'a, R: RulesTrait> {
|
pub struct RouterAstarStrategy<'a, R: RulesTrait> {
|
||||||
pub tracer: Tracer<'a, R>,
|
pub tracer: Tracer<'a, R>,
|
||||||
pub trace: &'a mut Trace,
|
pub trace: &'a mut Trace,
|
||||||
|
|
@ -142,6 +144,7 @@ impl<'a, R: RulesTrait> AstarStrategy<Navmesh, f64, BandFirstSegIndex>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct Router<'a, R: RulesTrait> {
|
pub struct Router<'a, R: RulesTrait> {
|
||||||
layout: &'a mut Layout<R>,
|
layout: &'a mut Layout<R>,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue