mirror of https://codeberg.org/topola/topola.git
egui: further make an `Activity` enum with error and status types
This commit is contained in:
parent
c8a40860af
commit
169e843736
|
|
@ -1,22 +1,12 @@
|
||||||
use enum_dispatch::enum_dispatch;
|
use enum_dispatch::enum_dispatch;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{
|
use crate::{board::mesadata::AccessMesadata, layout::via::ViaWeight, step::Step};
|
||||||
board::mesadata::AccessMesadata,
|
|
||||||
drawing::graph::PrimitiveIndex,
|
|
||||||
geometry::primitive::PrimitiveShape,
|
|
||||||
layout::via::ViaWeight,
|
|
||||||
router::{navmesh::Navmesh, trace::Trace},
|
|
||||||
step::Step,
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
autoroute::{Autoroute, AutorouteStatus},
|
autoroute::{Autoroute, AutorouteStatus},
|
||||||
compare_detours::{CompareDetours, CompareDetoursStatus},
|
compare_detours::{CompareDetours, CompareDetoursStatus},
|
||||||
invoker::{
|
invoker::{Invoker, InvokerError, InvokerStatus},
|
||||||
GetGhosts, GetMaybeNavmesh, GetMaybeTrace, GetObstacles, Invoker, InvokerError,
|
|
||||||
InvokerStatus,
|
|
||||||
},
|
|
||||||
measure_length::MeasureLength,
|
measure_length::MeasureLength,
|
||||||
place_via::PlaceVia,
|
place_via::PlaceVia,
|
||||||
remove_bands::RemoveBands,
|
remove_bands::RemoveBands,
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
use thiserror::Error;
|
||||||
use topola::{
|
use topola::{
|
||||||
autorouter::{
|
autorouter::{
|
||||||
execute::Execute,
|
execute::Execute,
|
||||||
|
|
@ -10,56 +11,140 @@ use topola::{
|
||||||
drawing::graph::PrimitiveIndex,
|
drawing::graph::PrimitiveIndex,
|
||||||
geometry::primitive::PrimitiveShape,
|
geometry::primitive::PrimitiveShape,
|
||||||
router::{navmesh::Navmesh, trace::Trace},
|
router::{navmesh::Navmesh, trace::Trace},
|
||||||
|
specctra::mesadata::SpecctraMesadata,
|
||||||
step::Step,
|
step::Step,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[derive(Error, Debug, Clone)]
|
||||||
|
pub enum ActivityError {
|
||||||
|
#[error(transparent)]
|
||||||
|
Invoker(#[from] InvokerError),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub enum ActivityStatus {
|
||||||
|
Running,
|
||||||
|
Finished(String),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<InvokerStatus> for ActivityStatus {
|
||||||
|
fn from(status: InvokerStatus) -> Self {
|
||||||
|
match status {
|
||||||
|
InvokerStatus::Running => ActivityStatus::Running,
|
||||||
|
InvokerStatus::Finished(msg) => ActivityStatus::Finished(msg),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryInto<()> for ActivityStatus {
|
||||||
|
type Error = ();
|
||||||
|
fn try_into(self) -> Result<(), ()> {
|
||||||
|
match self {
|
||||||
|
ActivityStatus::Running => Err(()),
|
||||||
|
ActivityStatus::Finished(..) => Ok(()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum Activity {
|
||||||
|
// There will be another variant for interactive activities here soon. (TODO)
|
||||||
|
Execute(Execute),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Step<Invoker<SpecctraMesadata>, ActivityStatus, ActivityError, ()> for Activity {
|
||||||
|
fn step(
|
||||||
|
&mut self,
|
||||||
|
invoker: &mut Invoker<SpecctraMesadata>,
|
||||||
|
) -> Result<ActivityStatus, ActivityError> {
|
||||||
|
match self {
|
||||||
|
Activity::Execute(execute) => Ok(execute.step(invoker)?.into()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GetMaybeNavmesh for Activity {
|
||||||
|
/// Implemented manually instead of with `enum_dispatch` because it doesn't work across crates.
|
||||||
|
fn maybe_navmesh(&self) -> Option<&Navmesh> {
|
||||||
|
match self {
|
||||||
|
Activity::Execute(execute) => execute.maybe_navmesh(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GetMaybeTrace for Activity {
|
||||||
|
/// Implemented manually instead of with `enum_dispatch` because it doesn't work across crates.
|
||||||
|
fn maybe_trace(&self) -> Option<&Trace> {
|
||||||
|
match self {
|
||||||
|
Activity::Execute(execute) => execute.maybe_trace(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GetGhosts for Activity {
|
||||||
|
/// Implemented manually instead of with `enum_dispatch` because it doesn't work across crates.
|
||||||
|
fn ghosts(&self) -> &[PrimitiveShape] {
|
||||||
|
match self {
|
||||||
|
Activity::Execute(execute) => execute.ghosts(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GetObstacles for Activity {
|
||||||
|
/// Implemented manually instead of with `enum_dispatch` because it doesn't work across crates.
|
||||||
|
fn obstacles(&self) -> &[PrimitiveIndex] {
|
||||||
|
match self {
|
||||||
|
Activity::Execute(execute) => execute.obstacles(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct ActivityWithStatus {
|
pub struct ActivityWithStatus {
|
||||||
execute: Execute,
|
activity: Activity,
|
||||||
maybe_status: Option<InvokerStatus>,
|
maybe_status: Option<ActivityStatus>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ActivityWithStatus {
|
impl ActivityWithStatus {
|
||||||
pub fn new_execute(execute: Execute) -> ActivityWithStatus {
|
pub fn new_execute(execute: Execute) -> ActivityWithStatus {
|
||||||
Self {
|
Self {
|
||||||
execute,
|
activity: Activity::Execute(execute),
|
||||||
maybe_status: None,
|
maybe_status: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn step<M: AccessMesadata>(
|
pub fn step(
|
||||||
&mut self,
|
&mut self,
|
||||||
invoker: &mut Invoker<M>,
|
invoker: &mut Invoker<SpecctraMesadata>,
|
||||||
) -> Result<InvokerStatus, InvokerError> {
|
) -> Result<ActivityStatus, ActivityError> {
|
||||||
let status = self.execute.step(invoker)?;
|
let status = self.activity.step(invoker)?;
|
||||||
self.maybe_status = Some(status.clone());
|
self.maybe_status = Some(status.clone());
|
||||||
Ok(status)
|
Ok(status.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn maybe_status(&self) -> Option<InvokerStatus> {
|
pub fn maybe_status(&self) -> Option<ActivityStatus> {
|
||||||
self.maybe_status.clone()
|
self.maybe_status.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GetMaybeNavmesh for ActivityWithStatus {
|
impl GetMaybeNavmesh for ActivityWithStatus {
|
||||||
fn maybe_navmesh(&self) -> Option<&Navmesh> {
|
fn maybe_navmesh(&self) -> Option<&Navmesh> {
|
||||||
self.execute.maybe_navmesh()
|
self.activity.maybe_navmesh()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GetMaybeTrace for ActivityWithStatus {
|
impl GetMaybeTrace for ActivityWithStatus {
|
||||||
fn maybe_trace(&self) -> Option<&Trace> {
|
fn maybe_trace(&self) -> Option<&Trace> {
|
||||||
self.execute.maybe_trace()
|
self.activity.maybe_trace()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GetGhosts for ActivityWithStatus {
|
impl GetGhosts for ActivityWithStatus {
|
||||||
fn ghosts(&self) -> &[PrimitiveShape] {
|
fn ghosts(&self) -> &[PrimitiveShape] {
|
||||||
self.execute.ghosts()
|
self.activity.ghosts()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GetObstacles for ActivityWithStatus {
|
impl GetObstacles for ActivityWithStatus {
|
||||||
fn obstacles(&self) -> &[PrimitiveIndex] {
|
fn obstacles(&self) -> &[PrimitiveIndex] {
|
||||||
self.execute.obstacles()
|
self.activity.obstacles()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,10 +13,7 @@ use std::{
|
||||||
use unic_langid::{langid, LanguageIdentifier};
|
use unic_langid::{langid, LanguageIdentifier};
|
||||||
|
|
||||||
use topola::{
|
use topola::{
|
||||||
autorouter::{
|
autorouter::{invoker::Invoker, Autorouter},
|
||||||
invoker::{Invoker, InvokerStatus},
|
|
||||||
Autorouter,
|
|
||||||
},
|
|
||||||
drawing::{
|
drawing::{
|
||||||
dot::FixedDotIndex,
|
dot::FixedDotIndex,
|
||||||
graph::{MakePrimitive, PrimitiveIndex},
|
graph::{MakePrimitive, PrimitiveIndex},
|
||||||
|
|
@ -42,8 +39,15 @@ use topola::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
activity::ActivityWithStatus, bottom::Bottom, file_receiver::FileReceiver, layers::Layers,
|
activity::{ActivityStatus, ActivityWithStatus},
|
||||||
overlay::Overlay, painter::Painter, top::Top, translator::Translator, viewport::Viewport,
|
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.
|
/// Deserialize/Serialize is needed to persist app state between restarts.
|
||||||
|
|
@ -159,8 +163,8 @@ impl App {
|
||||||
|
|
||||||
if let Some(ref mut activity) = self.maybe_activity {
|
if let Some(ref mut activity) = self.maybe_activity {
|
||||||
match activity.step(invoker) {
|
match activity.step(invoker) {
|
||||||
Ok(InvokerStatus::Running) => return true,
|
Ok(ActivityStatus::Running) => return true,
|
||||||
Ok(InvokerStatus::Finished(..)) => return false,
|
Ok(ActivityStatus::Finished(..)) => return false,
|
||||||
Err(err) => return false,
|
Err(err) => return false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,10 @@
|
||||||
use topola::autorouter::invoker::InvokerStatus;
|
use topola::autorouter::invoker::InvokerStatus;
|
||||||
|
|
||||||
use crate::{activity::ActivityWithStatus, translator::Translator, viewport::Viewport};
|
use crate::{
|
||||||
|
activity::{ActivityStatus, ActivityWithStatus},
|
||||||
|
translator::Translator,
|
||||||
|
viewport::Viewport,
|
||||||
|
};
|
||||||
|
|
||||||
pub struct Bottom {}
|
pub struct Bottom {}
|
||||||
|
|
||||||
|
|
@ -23,7 +27,7 @@ impl Bottom {
|
||||||
let mut message = String::from("");
|
let mut message = String::from("");
|
||||||
|
|
||||||
if let Some(activity) = maybe_activity {
|
if let Some(activity) = maybe_activity {
|
||||||
if let Some(InvokerStatus::Finished(msg)) = activity.maybe_status() {
|
if let Some(ActivityStatus::Finished(msg)) = activity.maybe_status() {
|
||||||
message = msg;
|
message = msg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ use topola::{
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
action::{Action, Switch, Trigger},
|
action::{Action, Switch, Trigger},
|
||||||
activity::ActivityWithStatus,
|
activity::{ActivityStatus, ActivityWithStatus},
|
||||||
app::execute,
|
app::execute,
|
||||||
file_sender::FileSender,
|
file_sender::FileSender,
|
||||||
overlay::Overlay,
|
overlay::Overlay,
|
||||||
|
|
@ -292,7 +292,7 @@ impl Top {
|
||||||
ctx.send_viewport_cmd(egui::ViewportCommand::Close);
|
ctx.send_viewport_cmd(egui::ViewportCommand::Close);
|
||||||
} else if autoroute.consume_key_triggered(ctx, ui) {
|
} else if autoroute.consume_key_triggered(ctx, ui) {
|
||||||
if maybe_activity.as_mut().map_or(true, |activity| {
|
if maybe_activity.as_mut().map_or(true, |activity| {
|
||||||
matches!(activity.maybe_status(), Some(InvokerStatus::Finished(..)))
|
matches!(activity.maybe_status(), Some(ActivityStatus::Finished(..)))
|
||||||
}) {
|
}) {
|
||||||
if let (Some(invoker), Some(ref mut overlay)) = (
|
if let (Some(invoker), Some(ref mut overlay)) = (
|
||||||
arc_mutex_maybe_invoker.lock().unwrap().as_mut(),
|
arc_mutex_maybe_invoker.lock().unwrap().as_mut(),
|
||||||
|
|
@ -311,7 +311,7 @@ impl Top {
|
||||||
} else if place_via.consume_key_enabled(ctx, ui, &mut self.is_placing_via) {
|
} else if place_via.consume_key_enabled(ctx, ui, &mut self.is_placing_via) {
|
||||||
} else if remove_bands.consume_key_triggered(ctx, ui) {
|
} else if remove_bands.consume_key_triggered(ctx, ui) {
|
||||||
if maybe_activity.as_mut().map_or(true, |activity| {
|
if maybe_activity.as_mut().map_or(true, |activity| {
|
||||||
matches!(activity.maybe_status(), Some(InvokerStatus::Finished(..)))
|
matches!(activity.maybe_status(), Some(ActivityStatus::Finished(..)))
|
||||||
}) {
|
}) {
|
||||||
if let (Some(invoker), Some(ref mut overlay)) = (
|
if let (Some(invoker), Some(ref mut overlay)) = (
|
||||||
arc_mutex_maybe_invoker.lock().unwrap().as_mut(),
|
arc_mutex_maybe_invoker.lock().unwrap().as_mut(),
|
||||||
|
|
@ -328,7 +328,7 @@ impl Top {
|
||||||
}
|
}
|
||||||
} else if measure_length.consume_key_triggered(ctx, ui) {
|
} else if measure_length.consume_key_triggered(ctx, ui) {
|
||||||
if maybe_activity.as_mut().map_or(true, |activity| {
|
if maybe_activity.as_mut().map_or(true, |activity| {
|
||||||
matches!(activity.maybe_status(), Some(InvokerStatus::Finished(..)))
|
matches!(activity.maybe_status(), Some(ActivityStatus::Finished(..)))
|
||||||
}) {
|
}) {
|
||||||
if let (Some(invoker), Some(ref mut overlay)) = (
|
if let (Some(invoker), Some(ref mut overlay)) = (
|
||||||
arc_mutex_maybe_invoker.lock().unwrap().as_mut(),
|
arc_mutex_maybe_invoker.lock().unwrap().as_mut(),
|
||||||
|
|
@ -353,7 +353,7 @@ impl Top {
|
||||||
}
|
}
|
||||||
} else if compare_detours.consume_key_triggered(ctx, ui) {
|
} else if compare_detours.consume_key_triggered(ctx, ui) {
|
||||||
if maybe_activity.as_mut().map_or(true, |activity| {
|
if maybe_activity.as_mut().map_or(true, |activity| {
|
||||||
matches!(activity.maybe_status(), Some(InvokerStatus::Finished(..)))
|
matches!(activity.maybe_status(), Some(ActivityStatus::Finished(..)))
|
||||||
}) {
|
}) {
|
||||||
if let (Some(invoker), Some(ref mut overlay)) = (
|
if let (Some(invoker), Some(ref mut overlay)) = (
|
||||||
arc_mutex_maybe_invoker.lock().unwrap().as_mut(),
|
arc_mutex_maybe_invoker.lock().unwrap().as_mut(),
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue