mirror of https://codeberg.org/topola/topola.git
stepper: refactoring
* put `Error` as an associated type into separate trait
* make `Step::finish` generic over O instead of Step
* introduce `PollStep` trait including `finish` method
* use `PollStep` in GUI, fix infinitely repeating errors
* replace {Activity,Invoker,Interaction}Status with Poll<String>
* `PollStep` provides `Step<_, Poll<_>>`
Fixes #78.
This commit is contained in:
parent
f02b7be878
commit
4171443c45
|
|
@ -9,7 +9,7 @@ use crate::{
|
|||
drawing::{band::BandTermsegIndex, graph::PrimitiveIndex},
|
||||
geometry::primitive::PrimitiveShape,
|
||||
router::{navmesh::Navmesh, route::RouteStepper, trace::TraceStepper, Router, RouterStatus},
|
||||
stepper::Step,
|
||||
stepper::{Step, StepError},
|
||||
};
|
||||
|
||||
use super::{
|
||||
|
|
@ -86,9 +86,11 @@ impl AutorouteExecutionStepper {
|
|||
}
|
||||
}
|
||||
|
||||
impl<M: AccessMesadata> Step<Autorouter<M>, AutorouteStatus, AutorouterError, ()>
|
||||
for AutorouteExecutionStepper
|
||||
{
|
||||
impl StepError for AutorouteExecutionStepper {
|
||||
type Error = AutorouterError;
|
||||
}
|
||||
|
||||
impl<M: AccessMesadata> Step<Autorouter<M>, AutorouteStatus> for AutorouteExecutionStepper {
|
||||
fn step(&mut self, autorouter: &mut Autorouter<M>) -> Result<AutorouteStatus, AutorouterError> {
|
||||
let Some(curr_ratline) = self.curr_ratline else {
|
||||
return Ok(AutorouteStatus::Finished);
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ use crate::{
|
|||
geometry::{primitive::PrimitiveShape, shape::MeasureLength},
|
||||
graph::MakeRef,
|
||||
router::{navmesh::Navmesh, trace::TraceStepper},
|
||||
stepper::Step,
|
||||
stepper::{Step, StepError},
|
||||
};
|
||||
|
||||
use super::{
|
||||
|
|
@ -66,9 +66,13 @@ impl CompareDetoursExecutionStepper {
|
|||
}
|
||||
}
|
||||
|
||||
impl StepError for CompareDetoursExecutionStepper {
|
||||
type Error = AutorouterError;
|
||||
}
|
||||
|
||||
// XXX: Do we really need this to be a stepper? We don't use at the moment, as sorting functions
|
||||
// aren't steppable either. It may be useful for debugging later on tho.
|
||||
impl<M: AccessMesadata> Step<Autorouter<M>, CompareDetoursStatus, AutorouterError, (f64, f64)>
|
||||
impl<M: AccessMesadata> Step<Autorouter<M>, CompareDetoursStatus>
|
||||
for CompareDetoursExecutionStepper
|
||||
{
|
||||
fn step(
|
||||
|
|
|
|||
|
|
@ -1,12 +1,17 @@
|
|||
use core::task::Poll;
|
||||
use enum_dispatch::enum_dispatch;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{board::mesadata::AccessMesadata, layout::via::ViaWeight, stepper::Step};
|
||||
use crate::{
|
||||
board::mesadata::AccessMesadata,
|
||||
layout::via::ViaWeight,
|
||||
stepper::{PollStep, Step, StepError},
|
||||
};
|
||||
|
||||
use super::{
|
||||
autoroute::{AutorouteExecutionStepper, AutorouteStatus},
|
||||
compare_detours::{CompareDetoursExecutionStepper, CompareDetoursStatus},
|
||||
invoker::{Invoker, InvokerError, InvokerStatus},
|
||||
invoker::{Invoker, InvokerError},
|
||||
measure_length::MeasureLengthExecutionStepper,
|
||||
place_via::PlaceViaExecutionStepper,
|
||||
remove_bands::RemoveBandsExecutionStepper,
|
||||
|
|
@ -38,30 +43,28 @@ impl ExecutionStepper {
|
|||
fn step_catch_err<M: AccessMesadata>(
|
||||
&mut self,
|
||||
invoker: &mut Invoker<M>,
|
||||
) -> Result<InvokerStatus, InvokerError> {
|
||||
Ok(match self {
|
||||
) -> Poll<Result<String, InvokerError>> {
|
||||
match self {
|
||||
ExecutionStepper::Autoroute(autoroute) => {
|
||||
match autoroute.step(&mut invoker.autorouter)? {
|
||||
AutorouteStatus::Running => InvokerStatus::Running,
|
||||
AutorouteStatus::Routed(..) => InvokerStatus::Running,
|
||||
AutorouteStatus::Finished => {
|
||||
InvokerStatus::Finished("finished autorouting".to_string())
|
||||
}
|
||||
AutorouteStatus::Running => Poll::Pending,
|
||||
AutorouteStatus::Routed(..) => Poll::Pending,
|
||||
AutorouteStatus::Finished => Poll::Ready("finished autorouting".to_string()),
|
||||
}
|
||||
}
|
||||
ExecutionStepper::PlaceVia(place_via) => {
|
||||
place_via.doit(&mut invoker.autorouter)?;
|
||||
InvokerStatus::Finished("finished placing via".to_string())
|
||||
Poll::Ready("finished placing via".to_string())
|
||||
}
|
||||
ExecutionStepper::RemoveBands(remove_bands) => {
|
||||
remove_bands.doit(&mut invoker.autorouter)?;
|
||||
InvokerStatus::Finished("finished removing bands".to_string())
|
||||
Poll::Ready("finished removing bands".to_string())
|
||||
}
|
||||
ExecutionStepper::CompareDetours(compare_detours) => {
|
||||
match compare_detours.step(&mut invoker.autorouter)? {
|
||||
CompareDetoursStatus::Running => InvokerStatus::Running,
|
||||
CompareDetoursStatus::Running => Poll::Pending,
|
||||
CompareDetoursStatus::Finished(total_length1, total_length2) => {
|
||||
InvokerStatus::Finished(format!(
|
||||
Poll::Ready(format!(
|
||||
"total detour lengths are {} and {}",
|
||||
total_length1, total_length2
|
||||
))
|
||||
|
|
@ -70,27 +73,30 @@ impl ExecutionStepper {
|
|||
}
|
||||
ExecutionStepper::MeasureLength(measure_length) => {
|
||||
let length = measure_length.doit(&mut invoker.autorouter)?;
|
||||
InvokerStatus::Finished(format!("Total length of selected bands: {}", length))
|
||||
Poll::Ready(format!("Total length of selected bands: {}", length))
|
||||
}
|
||||
})
|
||||
}
|
||||
.map(Ok)
|
||||
}
|
||||
}
|
||||
|
||||
impl<M: AccessMesadata> Step<Invoker<M>, InvokerStatus, InvokerError, ()> for ExecutionStepper {
|
||||
fn step(&mut self, invoker: &mut Invoker<M>) -> Result<InvokerStatus, InvokerError> {
|
||||
match self.step_catch_err(invoker) {
|
||||
Ok(InvokerStatus::Running) => Ok(InvokerStatus::Running),
|
||||
Ok(InvokerStatus::Finished(msg)) => {
|
||||
impl StepError for ExecutionStepper {
|
||||
type Error = InvokerError;
|
||||
}
|
||||
|
||||
impl<M: AccessMesadata> PollStep<Invoker<M>, String> for ExecutionStepper {
|
||||
fn poll_step(&mut self, invoker: &mut Invoker<M>) -> Poll<Result<String, InvokerError>> {
|
||||
self.step_catch_err(invoker).map(|x| match x {
|
||||
Ok(msg) => {
|
||||
if let Some(command) = invoker.ongoing_command.take() {
|
||||
invoker.history.do_(command);
|
||||
}
|
||||
|
||||
Ok(InvokerStatus::Finished(msg))
|
||||
Ok(msg)
|
||||
}
|
||||
Err(err) => {
|
||||
invoker.ongoing_command = None;
|
||||
Err(err)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
//! Manages the execution of routing commands within the autorouting system.
|
||||
|
||||
use std::cmp::Ordering;
|
||||
|
||||
use contracts_try::debug_requires;
|
||||
use core::cmp::Ordering;
|
||||
use enum_dispatch::enum_dispatch;
|
||||
use thiserror::Error;
|
||||
|
||||
|
|
@ -11,7 +10,7 @@ use crate::{
|
|||
drawing::graph::PrimitiveIndex,
|
||||
geometry::primitive::PrimitiveShape,
|
||||
router::{navmesh::Navmesh, trace::TraceStepper},
|
||||
stepper::Step,
|
||||
stepper::{PollStep, Step},
|
||||
};
|
||||
|
||||
use super::{
|
||||
|
|
@ -59,16 +58,6 @@ pub enum InvokerError {
|
|||
Autorouter(#[from] AutorouterError),
|
||||
}
|
||||
|
||||
impl TryInto<()> for InvokerStatus {
|
||||
type Error = ();
|
||||
fn try_into(self) -> Result<(), ()> {
|
||||
match self {
|
||||
InvokerStatus::Running => Err(()),
|
||||
InvokerStatus::Finished(..) => Ok(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Invoker<M: AccessMesadata> {
|
||||
pub(super) autorouter: Autorouter<M>,
|
||||
pub(super) history: History,
|
||||
|
|
@ -93,20 +82,11 @@ impl<M: AccessMesadata> Invoker<M> {
|
|||
}
|
||||
|
||||
//#[debug_requires(self.ongoing_command.is_none())]
|
||||
pub fn execute(&mut self, command: Command) -> Result<(), InvokerError> {
|
||||
pub fn execute(&mut self, command: Command) -> Result<String, InvokerError> {
|
||||
let mut execute = self.execute_stepper(command)?;
|
||||
|
||||
loop {
|
||||
let status = match execute.step(self) {
|
||||
Ok(status) => status,
|
||||
Err(err) => return Err(err),
|
||||
};
|
||||
|
||||
if let InvokerStatus::Finished(..) = status {
|
||||
let res = PollStep::finish(&mut execute, self)?;
|
||||
self.history.set_undone(std::iter::empty());
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
#[debug_requires(self.ongoing_command.is_none())]
|
||||
|
|
@ -178,17 +158,8 @@ impl<M: AccessMesadata> Invoker<M> {
|
|||
pub fn redo(&mut self) -> Result<(), InvokerError> {
|
||||
let command = self.history.last_undone()?.clone();
|
||||
let mut execute = self.execute_stepper(command)?;
|
||||
|
||||
loop {
|
||||
let status = match execute.step(self) {
|
||||
Ok(status) => status,
|
||||
Err(err) => return Err(err),
|
||||
};
|
||||
|
||||
if let InvokerStatus::Finished(..) = status {
|
||||
return Ok(self.history.redo()?);
|
||||
}
|
||||
}
|
||||
PollStep::finish(&mut execute, self)?;
|
||||
Ok(self.history.redo()?)
|
||||
}
|
||||
|
||||
#[debug_requires(self.ongoing_command.is_none())]
|
||||
|
|
|
|||
|
|
@ -1,63 +1,25 @@
|
|||
use core::task::Poll;
|
||||
use thiserror::Error;
|
||||
use topola::{
|
||||
autorouter::{
|
||||
execution::ExecutionStepper,
|
||||
invoker::{
|
||||
GetGhosts, GetMaybeNavmesh, GetMaybeTrace, GetObstacles, Invoker, InvokerError,
|
||||
InvokerStatus,
|
||||
},
|
||||
invoker::{GetGhosts, GetMaybeNavmesh, GetMaybeTrace, GetObstacles, Invoker, InvokerError},
|
||||
},
|
||||
board::mesadata::AccessMesadata,
|
||||
drawing::graph::PrimitiveIndex,
|
||||
geometry::primitive::PrimitiveShape,
|
||||
router::{navmesh::Navmesh, trace::TraceStepper},
|
||||
specctra::mesadata::SpecctraMesadata,
|
||||
stepper::{Abort, Step},
|
||||
stepper::{Abort, PollStep, StepError},
|
||||
};
|
||||
|
||||
use crate::interaction::{
|
||||
InteractionContext, InteractionError, InteractionStatus, InteractionStepper,
|
||||
};
|
||||
use crate::interaction::{InteractionContext, InteractionError, InteractionStepper};
|
||||
|
||||
pub struct ActivityContext<'a> {
|
||||
pub interaction: InteractionContext,
|
||||
pub invoker: &'a mut Invoker<SpecctraMesadata>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum ActivityStatus {
|
||||
Running,
|
||||
Finished(String),
|
||||
}
|
||||
|
||||
impl From<InteractionStatus> for ActivityStatus {
|
||||
fn from(status: InteractionStatus) -> Self {
|
||||
match status {
|
||||
InteractionStatus::Running => ActivityStatus::Running,
|
||||
InteractionStatus::Finished(msg) => ActivityStatus::Finished(msg),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Error, Debug, Clone)]
|
||||
pub enum ActivityError {
|
||||
#[error(transparent)]
|
||||
|
|
@ -71,13 +33,22 @@ pub enum ActivityStepper {
|
|||
Execution(ExecutionStepper),
|
||||
}
|
||||
|
||||
impl Step<ActivityContext<'_>, ActivityStatus, ActivityError, ()> for ActivityStepper {
|
||||
fn step(&mut self, context: &mut ActivityContext) -> Result<ActivityStatus, ActivityError> {
|
||||
impl StepError for ActivityStepper {
|
||||
type Error = ActivityError;
|
||||
}
|
||||
|
||||
impl PollStep<ActivityContext<'_>, String> for ActivityStepper {
|
||||
fn poll_step(
|
||||
&mut self,
|
||||
context: &mut ActivityContext<'_>,
|
||||
) -> Poll<Result<String, ActivityError>> {
|
||||
match self {
|
||||
ActivityStepper::Interaction(interaction) => {
|
||||
Ok(interaction.step(&mut context.interaction)?.into())
|
||||
}
|
||||
ActivityStepper::Execution(execution) => Ok(execution.step(context.invoker)?.into()),
|
||||
ActivityStepper::Interaction(interaction) => interaction
|
||||
.poll_step(&mut context.interaction)
|
||||
.map(|x| x.map_err(Into::into)),
|
||||
ActivityStepper::Execution(execution) => execution
|
||||
.poll_step(context.invoker)
|
||||
.map(|x| x.map_err(Into::into)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -86,9 +57,11 @@ impl Abort<ActivityContext<'_>> for ActivityStepper {
|
|||
fn abort(&mut self, context: &mut ActivityContext) {
|
||||
match self {
|
||||
ActivityStepper::Interaction(interaction) => {
|
||||
Ok(interaction.abort(&mut context.interaction))
|
||||
interaction.abort(&mut context.interaction);
|
||||
}
|
||||
ActivityStepper::Execution(execution) => {
|
||||
PollStep::finish(execution, context.invoker); // TODO.
|
||||
}
|
||||
ActivityStepper::Execution(execution) => execution.finish(context.invoker), // TODO.
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -135,7 +108,7 @@ impl GetObstacles for ActivityStepper {
|
|||
|
||||
pub struct ActivityStepperWithStatus {
|
||||
activity: ActivityStepper,
|
||||
maybe_status: Option<ActivityStatus>,
|
||||
maybe_status: Option<Poll<String>>,
|
||||
}
|
||||
|
||||
impl ActivityStepperWithStatus {
|
||||
|
|
@ -146,22 +119,33 @@ impl ActivityStepperWithStatus {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn maybe_status(&self) -> Option<ActivityStatus> {
|
||||
pub fn maybe_status(&self) -> Option<Poll<String>> {
|
||||
self.maybe_status.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl Step<ActivityContext<'_>, ActivityStatus, ActivityError, ()> for ActivityStepperWithStatus {
|
||||
fn step(&mut self, context: &mut ActivityContext) -> Result<ActivityStatus, ActivityError> {
|
||||
let status = self.activity.step(context)?;
|
||||
self.maybe_status = Some(status.clone());
|
||||
Ok(status.into())
|
||||
impl StepError for ActivityStepperWithStatus {
|
||||
type Error = ActivityError;
|
||||
}
|
||||
|
||||
impl PollStep<ActivityContext<'_>, String> for ActivityStepperWithStatus {
|
||||
fn poll_step(
|
||||
&mut self,
|
||||
context: &mut ActivityContext<'_>,
|
||||
) -> Poll<Result<String, ActivityError>> {
|
||||
let res = self.activity.poll_step(context);
|
||||
self.maybe_status = match &res {
|
||||
Poll::Pending => Some(Poll::Pending),
|
||||
Poll::Ready(Ok(msg)) => Some(Poll::Ready(msg.clone())),
|
||||
Poll::Ready(Err(_)) => None,
|
||||
};
|
||||
res
|
||||
}
|
||||
}
|
||||
|
||||
impl Abort<ActivityContext<'_>> for ActivityStepperWithStatus {
|
||||
fn abort(&mut self, context: &mut ActivityContext) {
|
||||
self.maybe_status = Some(ActivityStatus::Finished(String::from("aborted")));
|
||||
fn abort(&mut self, context: &mut ActivityContext<'_>) {
|
||||
self.maybe_status = Some(Poll::Ready("aborted".to_string()));
|
||||
self.activity.abort(context);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ use std::{
|
|||
mpsc::{channel, Receiver, Sender},
|
||||
Arc, Mutex,
|
||||
},
|
||||
task::Poll,
|
||||
};
|
||||
use unic_langid::{langid, LanguageIdentifier};
|
||||
|
||||
|
|
@ -15,11 +16,11 @@ use topola::{
|
|||
design::{LoadingError as SpecctraLoadingError, SpecctraDesign},
|
||||
mesadata::SpecctraMesadata,
|
||||
},
|
||||
stepper::Step,
|
||||
stepper::PollStep,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
activity::{ActivityContext, ActivityStatus, ActivityStepperWithStatus},
|
||||
activity::{ActivityContext, ActivityStepperWithStatus},
|
||||
config::Config,
|
||||
error_dialog::ErrorDialog,
|
||||
interaction::InteractionContext,
|
||||
|
|
@ -171,15 +172,17 @@ impl App {
|
|||
}
|
||||
|
||||
if let Some(ref mut activity) = self.maybe_activity {
|
||||
return match activity.step(&mut ActivityContext {
|
||||
return match activity.poll_step(&mut ActivityContext {
|
||||
interaction: InteractionContext {},
|
||||
invoker,
|
||||
}) {
|
||||
Ok(ActivityStatus::Running) => true,
|
||||
Ok(ActivityStatus::Finished(..)) => false,
|
||||
Err(err) => {
|
||||
Poll::Pending => true,
|
||||
Poll::Ready(res) => {
|
||||
if let Err(err) = res {
|
||||
self.error_dialog
|
||||
.push_error("tr-module-invoker", format!("{}", err));
|
||||
}
|
||||
self.maybe_activity = None;
|
||||
false
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
use core::task::Poll;
|
||||
use thiserror::Error;
|
||||
use topola::{
|
||||
autorouter::invoker::{GetGhosts, GetMaybeNavmesh, GetMaybeTrace, GetObstacles},
|
||||
drawing::graph::PrimitiveIndex,
|
||||
geometry::primitive::PrimitiveShape,
|
||||
router::{navmesh::Navmesh, trace::TraceStepper},
|
||||
stepper::{Abort, Step},
|
||||
stepper::{Abort, PollStep, StepError},
|
||||
};
|
||||
|
||||
use crate::activity::ActivityStepperWithStatus;
|
||||
|
|
@ -15,22 +16,6 @@ pub struct InteractionContext {
|
|||
// (we will need an additional struct to hold a reference to a `Board<...>`)
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum InteractionStatus {
|
||||
Running,
|
||||
Finished(String),
|
||||
}
|
||||
|
||||
impl TryInto<()> for InteractionStatus {
|
||||
type Error = ();
|
||||
fn try_into(self) -> Result<(), ()> {
|
||||
match self {
|
||||
InteractionStatus::Running => Err(()),
|
||||
InteractionStatus::Finished(..) => Ok(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Error, Debug, Clone)]
|
||||
pub enum InteractionError {
|
||||
#[error("nothing to interact with")]
|
||||
|
|
@ -44,12 +29,16 @@ pub enum InteractionStepper {
|
|||
// - interactively moving a footprint.
|
||||
}
|
||||
|
||||
impl Step<InteractionContext, InteractionStatus, InteractionError, ()> for InteractionStepper {
|
||||
fn step(
|
||||
impl StepError for InteractionStepper {
|
||||
type Error = InteractionError;
|
||||
}
|
||||
|
||||
impl PollStep<InteractionContext, String> for InteractionStepper {
|
||||
fn poll_step(
|
||||
&mut self,
|
||||
invoker: &mut InteractionContext,
|
||||
) -> Result<InteractionStatus, InteractionError> {
|
||||
Ok(InteractionStatus::Finished(String::from("")))
|
||||
) -> Poll<Result<String, InteractionError>> {
|
||||
Poll::Ready(Ok(String::new()))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use std::{
|
||||
path::Path,
|
||||
sync::{mpsc::Sender, Arc, Mutex},
|
||||
task::Poll,
|
||||
};
|
||||
|
||||
use topola::{
|
||||
|
|
@ -20,7 +21,7 @@ use topola::{
|
|||
|
||||
use crate::{
|
||||
action::{Action, Switch, Trigger},
|
||||
activity::{ActivityContext, ActivityStatus, ActivityStepperWithStatus},
|
||||
activity::{ActivityContext, ActivityStepperWithStatus},
|
||||
app::{execute, handle_file},
|
||||
interaction::InteractionContext,
|
||||
overlay::Overlay,
|
||||
|
|
@ -340,7 +341,7 @@ impl MenuBar {
|
|||
}
|
||||
} else if remove_bands.consume_key_triggered(ctx, ui) {
|
||||
if maybe_activity.as_mut().map_or(true, |activity| {
|
||||
matches!(activity.maybe_status(), Some(ActivityStatus::Finished(..)))
|
||||
matches!(activity.maybe_status(), Some(Poll::Ready(..)))
|
||||
}) {
|
||||
if let (Some(invoker), Some(ref mut overlay)) = (
|
||||
arc_mutex_maybe_invoker.lock().unwrap().as_mut(),
|
||||
|
|
@ -357,7 +358,7 @@ impl MenuBar {
|
|||
} else if place_via.consume_key_enabled(ctx, ui, &mut self.is_placing_via) {
|
||||
} else if autoroute.consume_key_triggered(ctx, ui) {
|
||||
if maybe_activity.as_mut().map_or(true, |activity| {
|
||||
matches!(activity.maybe_status(), Some(ActivityStatus::Finished(..)))
|
||||
matches!(activity.maybe_status(), Some(Poll::Ready(..)))
|
||||
}) {
|
||||
if let (Some(invoker), Some(ref mut overlay)) = (
|
||||
arc_mutex_maybe_invoker.lock().unwrap().as_mut(),
|
||||
|
|
@ -374,7 +375,7 @@ impl MenuBar {
|
|||
}
|
||||
} else if compare_detours.consume_key_triggered(ctx, ui) {
|
||||
if maybe_activity.as_mut().map_or(true, |activity| {
|
||||
matches!(activity.maybe_status(), Some(ActivityStatus::Finished(..)))
|
||||
matches!(activity.maybe_status(), Some(Poll::Ready(..)))
|
||||
}) {
|
||||
if let (Some(invoker), Some(ref mut overlay)) = (
|
||||
arc_mutex_maybe_invoker.lock().unwrap().as_mut(),
|
||||
|
|
@ -391,7 +392,7 @@ impl MenuBar {
|
|||
}
|
||||
} else if measure_length.consume_key_triggered(ctx, ui) {
|
||||
if maybe_activity.as_mut().map_or(true, |activity| {
|
||||
matches!(activity.maybe_status(), Some(ActivityStatus::Finished(..)))
|
||||
matches!(activity.maybe_status(), Some(Poll::Ready(..)))
|
||||
}) {
|
||||
if let (Some(invoker), Some(ref mut overlay)) = (
|
||||
arc_mutex_maybe_invoker.lock().unwrap().as_mut(),
|
||||
|
|
|
|||
|
|
@ -1,8 +1,5 @@
|
|||
use crate::{
|
||||
activity::{ActivityStatus, ActivityStepperWithStatus},
|
||||
translator::Translator,
|
||||
viewport::Viewport,
|
||||
};
|
||||
use crate::{activity::ActivityStepperWithStatus, translator::Translator, viewport::Viewport};
|
||||
use core::task::Poll;
|
||||
|
||||
pub struct StatusBar {}
|
||||
|
||||
|
|
@ -22,10 +19,10 @@ impl StatusBar {
|
|||
let latest_pos = viewport.transform.inverse()
|
||||
* ctx.input(|i| i.pointer.latest_pos().unwrap_or_default());
|
||||
|
||||
let mut message = String::from("");
|
||||
let mut message = String::new();
|
||||
|
||||
if let Some(activity) = maybe_activity {
|
||||
if let Some(ActivityStatus::Finished(msg)) = activity.maybe_status() {
|
||||
if let Some(Poll::Ready(msg)) = activity.maybe_status() {
|
||||
message = msg;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ use thiserror::Error;
|
|||
|
||||
use std::cmp::Ordering;
|
||||
|
||||
use crate::stepper::Step;
|
||||
use crate::stepper::{Step, StepError};
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct MinScored<K, T>(pub K, pub T);
|
||||
|
|
@ -203,8 +203,17 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<G, K, R, S: AstarStrategy<G, K, R>>
|
||||
Step<S, AstarStatus<G, K, R>, AstarError, (K, Vec<G::NodeId>, R)> for Astar<G, K>
|
||||
impl<G, K> StepError for Astar<G, K>
|
||||
where
|
||||
G: GraphBase,
|
||||
G::NodeId: Eq + Hash,
|
||||
for<'a> &'a G: IntoEdges<NodeId = G::NodeId, EdgeId = G::EdgeId> + MakeEdgeRef,
|
||||
K: Measure + Copy,
|
||||
{
|
||||
type Error = AstarError;
|
||||
}
|
||||
|
||||
impl<G, K, R, S: AstarStrategy<G, K, R>> Step<S, AstarStatus<G, K, R>> for Astar<G, K>
|
||||
where
|
||||
G: GraphBase,
|
||||
G::NodeId: Eq + Hash,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
use crate::{
|
||||
drawing::{
|
||||
band::BandTermsegIndex, dot::FixedDotIndex, graph::PrimitiveIndex, rules::AccessRules,
|
||||
},
|
||||
drawing::{dot::FixedDotIndex, graph::PrimitiveIndex, rules::AccessRules},
|
||||
geometry::primitive::PrimitiveShape,
|
||||
router::{
|
||||
astar::{Astar, AstarError, AstarStatus},
|
||||
|
|
@ -10,7 +8,7 @@ use crate::{
|
|||
tracer::Tracer,
|
||||
Router, RouterAstarStrategy, RouterStatus,
|
||||
},
|
||||
stepper::Step,
|
||||
stepper::{Step, StepError},
|
||||
};
|
||||
|
||||
pub struct RouteStepper {
|
||||
|
|
@ -73,9 +71,11 @@ impl RouteStepper {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, R: AccessRules> Step<Router<'a, R>, RouterStatus, AstarError, BandTermsegIndex>
|
||||
for RouteStepper
|
||||
{
|
||||
impl StepError for RouteStepper {
|
||||
type Error = AstarError;
|
||||
}
|
||||
|
||||
impl<'a, R: AccessRules> Step<Router<'a, R>, RouterStatus> for RouteStepper {
|
||||
fn step(&mut self, router: &mut Router<R>) -> Result<RouterStatus, AstarError> {
|
||||
let tracer = Tracer::new(router.layout_mut());
|
||||
let target = self.astar.graph.destination();
|
||||
|
|
|
|||
|
|
@ -1,7 +1,16 @@
|
|||
pub trait Step<C, S: TryInto<O>, E, O> {
|
||||
fn step(&mut self, context: &mut C) -> Result<S, E>;
|
||||
use core::task::Poll;
|
||||
|
||||
fn finish(&mut self, context: &mut C) -> Result<O, E> {
|
||||
pub trait StepError {
|
||||
type Error;
|
||||
}
|
||||
|
||||
pub trait Step<C, S>: StepError {
|
||||
fn step(&mut self, context: &mut C) -> Result<S, Self::Error>;
|
||||
|
||||
fn finish<O>(&mut self, context: &mut C) -> Result<O, Self::Error>
|
||||
where
|
||||
S: TryInto<O>,
|
||||
{
|
||||
loop {
|
||||
if let Ok(outcome) = self.step(context)?.try_into() {
|
||||
return Ok(outcome);
|
||||
|
|
@ -10,8 +19,40 @@ pub trait Step<C, S: TryInto<O>, E, O> {
|
|||
}
|
||||
}
|
||||
|
||||
pub trait StepBack<C, S, E> {
|
||||
fn step_back(&mut self, context: &mut C) -> Result<S, E>;
|
||||
// Note that PollStep's `S` is usually not the same as Step's `S`.
|
||||
pub trait PollStep<C, S>: StepError {
|
||||
fn poll_step(&mut self, context: &mut C) -> Poll<Result<S, Self::Error>>;
|
||||
|
||||
fn finish(&mut self, context: &mut C) -> Result<S, Self::Error> {
|
||||
loop {
|
||||
if let Poll::Ready(outcome) = self.poll_step(context) {
|
||||
return outcome;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
impl<C, S, Stepper: Step<C, Poll<S>>> PollStep<C, S> for Stepper {
|
||||
#[inline]
|
||||
fn poll_step(&mut self, context: &mut C) -> Poll<Result<S, Self::Error>> {
|
||||
self.step(context)?.map(Ok)
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
impl<C, S, Stepper: PollStep<C, S>> Step<C, Poll<S>> for Stepper {
|
||||
#[inline]
|
||||
fn step(&mut self, context: &mut C) -> Result<Poll<S>, Self::Error> {
|
||||
Ok(match self.poll_step(context) {
|
||||
Poll::Pending => Poll::Pending,
|
||||
Poll::Ready(x) => Poll::Ready(x?),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub trait StepBack<C, S>: StepError {
|
||||
fn step_back(&mut self, context: &mut C) -> Result<S, Self::Error>;
|
||||
}
|
||||
|
||||
pub trait Abort<C> {
|
||||
|
|
|
|||
Loading…
Reference in New Issue