egui: s/ExecuteWithStatus/ActivityWithStatus, move it to own file

This commit is contained in:
Mikolaj Wielgus 2024-09-30 01:36:22 +02:00
parent a700bd8c20
commit c8a40860af
7 changed files with 149 additions and 112 deletions

View File

@ -1,10 +1,28 @@
use enum_dispatch::enum_dispatch;
use serde::{Deserialize, Serialize};
use crate::{board::mesadata::AccessMesadata, drawing::graph::PrimitiveIndex, geometry::primitive::PrimitiveShape, layout::via::ViaWeight, router::{navmesh::Navmesh, trace::Trace}, step::Step};
use super::{autoroute::{Autoroute, AutorouteStatus}, compare_detours::{CompareDetours, CompareDetoursStatus}, invoker::{GetGhosts, GetMaybeNavmesh, GetMaybeTrace, GetObstacles, Invoker, InvokerError, InvokerStatus}, measure_length::MeasureLength, place_via::PlaceVia, remove_bands::RemoveBands, selection::{BandSelection, PinSelection}, AutorouterOptions};
use crate::{
board::mesadata::AccessMesadata,
drawing::graph::PrimitiveIndex,
geometry::primitive::PrimitiveShape,
layout::via::ViaWeight,
router::{navmesh::Navmesh, trace::Trace},
step::Step,
};
use super::{
autoroute::{Autoroute, AutorouteStatus},
compare_detours::{CompareDetours, CompareDetoursStatus},
invoker::{
GetGhosts, GetMaybeNavmesh, GetMaybeTrace, GetObstacles, Invoker, InvokerError,
InvokerStatus,
},
measure_length::MeasureLength,
place_via::PlaceVia,
remove_bands::RemoveBands,
selection::{BandSelection, PinSelection},
AutorouterOptions,
};
type Type = PinSelection;
@ -91,54 +109,3 @@ impl<M: AccessMesadata> Step<Invoker<M>, InvokerStatus, InvokerError, ()> for Ex
}
}
}
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: AccessMesadata>(
&mut self,
invoker: &mut Invoker<M>,
) -> Result<InvokerStatus, InvokerError> {
let status = self.execute.step(invoker)?;
self.maybe_status = Some(status.clone());
Ok(status)
}
pub fn maybe_status(&self) -> Option<InvokerStatus> {
self.maybe_status.clone()
}
}
impl GetMaybeNavmesh for ExecuteWithStatus {
fn maybe_navmesh(&self) -> Option<&Navmesh> {
self.execute.maybe_navmesh()
}
}
impl GetMaybeTrace for ExecuteWithStatus {
fn maybe_trace(&self) -> Option<&Trace> {
self.execute.maybe_trace()
}
}
impl GetGhosts for ExecuteWithStatus {
fn ghosts(&self) -> &[PrimitiveShape] {
self.execute.ghosts()
}
}
impl GetObstacles for ExecuteWithStatus {
fn obstacles(&self) -> &[PrimitiveIndex] {
self.execute.obstacles()
}
}

View File

@ -0,0 +1,65 @@
use topola::{
autorouter::{
execute::Execute,
invoker::{
GetGhosts, GetMaybeNavmesh, GetMaybeTrace, GetObstacles, Invoker, InvokerError,
InvokerStatus,
},
},
board::mesadata::AccessMesadata,
drawing::graph::PrimitiveIndex,
geometry::primitive::PrimitiveShape,
router::{navmesh::Navmesh, trace::Trace},
step::Step,
};
pub struct ActivityWithStatus {
execute: Execute,
maybe_status: Option<InvokerStatus>,
}
impl ActivityWithStatus {
pub fn new_execute(execute: Execute) -> ActivityWithStatus {
Self {
execute,
maybe_status: None,
}
}
pub fn step<M: AccessMesadata>(
&mut self,
invoker: &mut Invoker<M>,
) -> Result<InvokerStatus, InvokerError> {
let status = self.execute.step(invoker)?;
self.maybe_status = Some(status.clone());
Ok(status)
}
pub fn maybe_status(&self) -> Option<InvokerStatus> {
self.maybe_status.clone()
}
}
impl GetMaybeNavmesh for ActivityWithStatus {
fn maybe_navmesh(&self) -> Option<&Navmesh> {
self.execute.maybe_navmesh()
}
}
impl GetMaybeTrace for ActivityWithStatus {
fn maybe_trace(&self) -> Option<&Trace> {
self.execute.maybe_trace()
}
}
impl GetGhosts for ActivityWithStatus {
fn ghosts(&self) -> &[PrimitiveShape] {
self.execute.ghosts()
}
}
impl GetObstacles for ActivityWithStatus {
fn obstacles(&self) -> &[PrimitiveIndex] {
self.execute.obstacles()
}
}

View File

@ -14,7 +14,6 @@ use unic_langid::{langid, LanguageIdentifier};
use topola::{
autorouter::{
execute::ExecuteWithStatus,
invoker::{Invoker, InvokerStatus},
Autorouter,
},
@ -43,8 +42,8 @@ use topola::{
};
use crate::{
bottom::Bottom, file_receiver::FileReceiver, layers::Layers, overlay::Overlay,
painter::Painter, top::Top, translator::Translator, viewport::Viewport,
activity::ActivityWithStatus, bottom::Bottom, file_receiver::FileReceiver, layers::Layers,
overlay::Overlay, painter::Painter, top::Top, translator::Translator, viewport::Viewport,
};
/// Deserialize/Serialize is needed to persist app state between restarts.
@ -60,7 +59,7 @@ pub struct App {
arc_mutex_maybe_invoker: Arc<Mutex<Option<Invoker<SpecctraMesadata>>>>,
#[serde(skip)]
maybe_execute: Option<ExecuteWithStatus>,
maybe_activity: Option<ActivityWithStatus>,
#[serde(skip)]
content_channel: (Sender<String>, Receiver<String>),
@ -93,7 +92,7 @@ impl Default for App {
translator: Translator::new(langid!("en-US")),
maybe_overlay: None,
arc_mutex_maybe_invoker: Arc::new(Mutex::new(None)),
maybe_execute: None,
maybe_activity: None,
content_channel: channel(),
history_channel: channel(),
viewport: Viewport::new(),
@ -158,8 +157,8 @@ impl App {
invoker.replay(serde_json::from_reader(bufread).unwrap())
}
if let Some(ref mut execute) = self.maybe_execute {
match execute.step(invoker) {
if let Some(ref mut activity) = self.maybe_activity {
match activity.step(invoker) {
Ok(InvokerStatus::Running) => return true,
Ok(InvokerStatus::Finished(..)) => return false,
Err(err) => return false,
@ -185,7 +184,7 @@ impl eframe::App for App {
self.content_channel.0.clone(),
self.history_channel.0.clone(),
self.arc_mutex_maybe_invoker.clone(),
&mut self.maybe_execute,
&mut self.maybe_activity,
&mut self.viewport,
&mut self.maybe_overlay,
&self.maybe_design,
@ -194,7 +193,7 @@ impl eframe::App for App {
self.advance_state_by_dt(ctx.input(|i| i.stable_dt));
self.bottom
.update(ctx, &self.translator, &self.viewport, &self.maybe_execute);
.update(ctx, &self.translator, &self.viewport, &self.maybe_activity);
if self.top.show_layer_manager {
if let Some(ref mut layers) = self.maybe_layers {
@ -208,7 +207,7 @@ impl eframe::App for App {
ctx,
&self.top,
&mut self.arc_mutex_maybe_invoker.lock().unwrap(),
&mut self.maybe_execute,
&mut self.maybe_activity,
&mut self.maybe_overlay,
&self.maybe_layers,
);

View File

@ -1,6 +1,6 @@
use topola::autorouter::{execute::ExecuteWithStatus, invoker::InvokerStatus};
use topola::autorouter::invoker::InvokerStatus;
use crate::{translator::Translator, viewport::Viewport};
use crate::{activity::ActivityWithStatus, translator::Translator, viewport::Viewport};
pub struct Bottom {}
@ -14,7 +14,7 @@ impl Bottom {
ctx: &egui::Context,
tr: &Translator,
viewport: &Viewport,
maybe_execute: &Option<ExecuteWithStatus>,
maybe_activity: &Option<ActivityWithStatus>,
) {
egui::TopBottomPanel::bottom("bottom_panel").show(ctx, |ui| {
let latest_pos = viewport.transform.inverse()
@ -22,8 +22,8 @@ impl Bottom {
let mut message = String::from("");
if let Some(execute) = maybe_execute {
if let Some(InvokerStatus::Finished(msg)) = execute.maybe_status() {
if let Some(activity) = maybe_activity {
if let Some(InvokerStatus::Finished(msg)) = activity.maybe_status() {
message = msg;
}
}

View File

@ -1,6 +1,7 @@
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] // hide console window on Windows in release
mod action;
mod activity;
mod app;
mod bottom;
mod file_receiver;

View File

@ -6,7 +6,7 @@ use std::{
use topola::{
autorouter::{
execute::{Command, ExecuteWithStatus},
execute::Command,
invoker::{Invoker, InvokerError, InvokerStatus},
AutorouterOptions,
},
@ -16,6 +16,7 @@ use topola::{
use crate::{
action::{Action, Switch, Trigger},
activity::ActivityWithStatus,
app::execute,
file_sender::FileSender,
overlay::Overlay,
@ -61,7 +62,7 @@ impl Top {
content_sender: Sender<String>,
history_sender: Sender<String>,
arc_mutex_maybe_invoker: Arc<Mutex<Option<Invoker<SpecctraMesadata>>>>,
maybe_execute: &mut Option<ExecuteWithStatus>,
maybe_activity: &mut Option<ActivityWithStatus>,
viewport: &mut Viewport,
maybe_overlay: &mut Option<Overlay>,
maybe_design: &Option<SpecctraDesign>,
@ -233,9 +234,7 @@ impl Top {
});
} else if export_session.consume_key_triggered(ctx, ui) {
if let Some(design) = maybe_design {
if let Some(invoker) =
arc_mutex_maybe_invoker.lock().unwrap().as_ref()
{
if let Some(invoker) = arc_mutex_maybe_invoker.lock().unwrap().as_ref() {
let ctx = ui.ctx().clone();
let board = invoker.autorouter().board();
@ -274,8 +273,7 @@ impl Top {
}
});
} else if export_history.consume_key_triggered(ctx, ui) {
if let Some(invoker) = arc_mutex_maybe_invoker.lock().unwrap().as_ref()
{
if let Some(invoker) = arc_mutex_maybe_invoker.lock().unwrap().as_ref() {
let ctx = ctx.clone();
let task = rfd::AsyncFileDialog::new().save_file();
@ -293,8 +291,8 @@ impl Top {
} else if quit.consume_key_triggered(ctx, ui) {
ctx.send_viewport_cmd(egui::ViewportCommand::Close);
} else if autoroute.consume_key_triggered(ctx, ui) {
if maybe_execute.as_mut().map_or(true, |execute| {
matches!(execute.maybe_status(), Some(InvokerStatus::Finished(..)))
if maybe_activity.as_mut().map_or(true, |activity| {
matches!(activity.maybe_status(), Some(InvokerStatus::Finished(..)))
}) {
if let (Some(invoker), Some(ref mut overlay)) = (
arc_mutex_maybe_invoker.lock().unwrap().as_mut(),
@ -302,18 +300,18 @@ impl Top {
) {
let selection = overlay.selection().clone();
overlay.clear_selection();
maybe_execute.insert(ExecuteWithStatus::new(invoker.execute_stepper(
Command::Autoroute(
maybe_activity.insert(ActivityWithStatus::new_execute(
invoker.execute_stepper(Command::Autoroute(
selection.pin_selection,
self.autorouter_options,
),
)?));
))?,
));
}
}
} else if place_via.consume_key_enabled(ctx, ui, &mut self.is_placing_via) {
} else if remove_bands.consume_key_triggered(ctx, ui) {
if maybe_execute.as_mut().map_or(true, |execute| {
matches!(execute.maybe_status(), Some(InvokerStatus::Finished(..)))
if maybe_activity.as_mut().map_or(true, |activity| {
matches!(activity.maybe_status(), Some(InvokerStatus::Finished(..)))
}) {
if let (Some(invoker), Some(ref mut overlay)) = (
arc_mutex_maybe_invoker.lock().unwrap().as_mut(),
@ -321,14 +319,16 @@ impl Top {
) {
let selection = overlay.selection().clone();
overlay.clear_selection();
maybe_execute.insert(ExecuteWithStatus::new(invoker.execute_stepper(
Command::RemoveBands(selection.band_selection),
)?));
maybe_activity.insert(ActivityWithStatus::new_execute(
invoker.execute_stepper(Command::RemoveBands(
selection.band_selection,
))?,
));
}
}
} else if measure_length.consume_key_triggered(ctx, ui) {
if maybe_execute.as_mut().map_or(true, |execute| {
matches!(execute.maybe_status(), Some(InvokerStatus::Finished(..)))
if maybe_activity.as_mut().map_or(true, |activity| {
matches!(activity.maybe_status(), Some(InvokerStatus::Finished(..)))
}) {
if let (Some(invoker), Some(ref mut overlay)) = (
arc_mutex_maybe_invoker.lock().unwrap().as_mut(),
@ -336,9 +336,11 @@ impl Top {
) {
let selection = overlay.selection().clone();
overlay.clear_selection();
maybe_execute.insert(ExecuteWithStatus::new(invoker.execute_stepper(
Command::MeasureLength(selection.band_selection),
)?));
maybe_activity.insert(ActivityWithStatus::new_execute(
invoker.execute_stepper(Command::MeasureLength(
selection.band_selection,
))?,
));
}
}
} else if undo.consume_key_triggered(ctx, ui) {
@ -350,8 +352,8 @@ impl Top {
invoker.redo();
}
} else if compare_detours.consume_key_triggered(ctx, ui) {
if maybe_execute.as_mut().map_or(true, |execute| {
matches!(execute.maybe_status(), Some(InvokerStatus::Finished(..)))
if maybe_activity.as_mut().map_or(true, |activity| {
matches!(activity.maybe_status(), Some(InvokerStatus::Finished(..)))
}) {
if let (Some(invoker), Some(ref mut overlay)) = (
arc_mutex_maybe_invoker.lock().unwrap().as_mut(),
@ -359,12 +361,12 @@ impl Top {
) {
let selection = overlay.selection().clone();
overlay.clear_selection();
maybe_execute.insert(ExecuteWithStatus::new(invoker.execute_stepper(
Command::CompareDetours(
maybe_activity.insert(ActivityWithStatus::new_execute(
invoker.execute_stepper(Command::CompareDetours(
selection.pin_selection,
self.autorouter_options,
),
)?));
))?,
));
}
}
}

View File

@ -6,7 +6,7 @@ use petgraph::{
use rstar::{Envelope, AABB};
use topola::{
autorouter::{
execute::{Command, ExecuteWithStatus},
execute::Command,
invoker::{GetGhosts, GetMaybeNavmesh, GetMaybeTrace, GetObstacles, Invoker},
},
board::mesadata::AccessMesadata,
@ -20,7 +20,10 @@ use topola::{
specctra::mesadata::SpecctraMesadata,
};
use crate::{app::execute, layers::Layers, overlay::Overlay, painter::Painter, top::Top};
use crate::{
activity::ActivityWithStatus, app::execute, layers::Layers, overlay::Overlay, painter::Painter,
top::Top,
};
pub struct Viewport {
pub transform: egui::emath::TSTransform,
@ -40,7 +43,7 @@ impl Viewport {
ctx: &egui::Context,
top: &Top,
maybe_invoker: &mut Option<Invoker<SpecctraMesadata>>,
maybe_execute: &mut Option<ExecuteWithStatus>,
maybe_activity: &mut Option<ActivityWithStatus>,
maybe_overlay: &mut Option<Overlay>,
maybe_layers: &Option<Layers>,
) -> egui::Rect {
@ -48,7 +51,7 @@ impl Viewport {
ctx,
top,
maybe_invoker,
maybe_execute,
maybe_activity,
maybe_overlay,
maybe_layers,
);
@ -65,7 +68,7 @@ impl Viewport {
ctx: &egui::Context,
top: &Top,
maybe_invoker: &mut Option<Invoker<SpecctraMesadata>>,
maybe_execute: &mut Option<ExecuteWithStatus>,
maybe_activity: &mut Option<ActivityWithStatus>,
maybe_overlay: &mut Option<Overlay>,
maybe_layers: &Option<Layers>,
) -> egui::Rect {
@ -124,8 +127,8 @@ impl Viewport {
{
layers.highlight_colors[i]
} else {
if let Some(execute) = maybe_execute {
if execute.obstacles().contains(&primitive) {
if let Some(activity) = maybe_activity {
if activity.obstacles().contains(&primitive) {
layers.highlight_colors[i]
} else {
layers.colors[i]
@ -178,8 +181,8 @@ impl Viewport {
}
if top.show_navmesh {
if let Some(execute) = maybe_execute {
if let Some(navmesh) = execute.maybe_navmesh() {
if let Some(activity) = maybe_activity {
if let Some(navmesh) = activity.maybe_navmesh() {
for edge in navmesh.edge_references() {
let mut from = PrimitiveIndex::from(navmesh.node_weight(edge.source()).unwrap().node)
.primitive(board.layout().drawing())
@ -208,11 +211,11 @@ impl Viewport {
let stroke = 'blk: {
if let (Some(source_pos), Some(target_pos)) = (
execute.maybe_trace().map(|trace|
activity.maybe_trace().map(|trace|
trace.path
.iter()
.position(|node| *node == edge.source())).flatten(),
execute.maybe_trace().map(|trace|
activity.maybe_trace().map(|trace|
trace.path
.iter()
.position(|node| *node == edge.target())).flatten(),
@ -243,12 +246,12 @@ impl Viewport {
painter.paint_bbox(root_bbox);
}
if let Some(execute) = maybe_execute {
for ghost in execute.ghosts().iter() {
if let Some(activity) = maybe_activity {
for ghost in activity.ghosts().iter() {
painter.paint_primitive(&ghost, egui::Color32::from_rgb(75, 75, 150));
}
if let Some(navmesh) = execute.maybe_navmesh() {
if let Some(navmesh) = activity.maybe_navmesh() {
if top.show_origin_destination {
if let (origin, destination) = (navmesh.origin(), navmesh.destination()) {
painter.paint_dot(