#[doc = crate::_tags!(runtime)]
#[doc = crate::_doc_location!("run/cycle")]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum RunControl {
Continue,
Stop,
}
#[doc = crate::_tags!(runtime)]
#[doc = crate::_doc_location!("run/cycle")]
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
pub enum RunPhase {
#[default]
Init = 0,
Running,
Paused,
Stopped,
}
impl RunPhase {
#[must_use]
pub const fn eq(self, other: Self) -> bool {
self as u8 == other as u8
}
}
#[doc = crate::_tags!(runtime)]
#[doc = crate::_doc_location!("run/cycle")]
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
pub struct RunCycle {
phase: RunPhase,
}
impl RunCycle {
pub const fn new() -> Self {
Self { phase: RunPhase::Init }
}
pub const fn phase(self) -> RunPhase {
self.phase
}
pub const fn is_running(self) -> bool {
matches!(self.phase, RunPhase::Running)
}
pub const fn is_paused(self) -> bool {
matches!(self.phase, RunPhase::Paused)
}
pub const fn is_stopped(self) -> bool {
matches!(self.phase, RunPhase::Stopped)
}
pub const fn can_advance(self) -> bool {
matches!(self.phase, RunPhase::Running)
}
#[allow(clippy::unnested_or_patterns)]
pub const fn can_transition(self, next: RunPhase) -> bool {
use RunPhase as P;
matches!(
(self.phase, next),
(P::Init, P::Init | P::Running | P::Stopped)
| (P::Running, P::Running | P::Paused | P::Stopped)
| (P::Paused, P::Paused | P::Running | P::Stopped)
| (P::Stopped, P::Stopped)
)
}
pub const fn transition(&mut self, next: RunPhase) -> bool {
if self.can_transition(next) {
self.phase = next;
true
} else {
false
}
}
}