use behavior::Behavior;
use bombay_transition::{Machine, Structure, ValidatedTopology};
pub(crate) struct BehaviorMachine<B> {
behavior: B,
topology: Option<ValidatedTopology>,
}
impl<B> BehaviorMachine<B> {
pub(crate) const fn for_runtime(behavior: B) -> Self {
Self {
behavior,
topology: None,
}
}
#[cfg(test)]
pub(crate) const fn with_topology(behavior: B, topology: ValidatedTopology) -> Self {
Self {
behavior,
topology: Some(topology),
}
}
pub(crate) fn behavior_mut(&mut self) -> &mut B {
&mut self.behavior
}
}
impl<B: Behavior> Machine for BehaviorMachine<B> {
type Input = B::Event;
type Output = behavior::BehaviorActed<B>;
fn step(mut self, input: Self::Input) -> (Self::Output, Self) {
let output = self.behavior.transition(input);
(output, self)
}
fn describe<V: Structure>(&self, visitor: &mut V) -> V::Output {
if let Some(t) = &self.topology {
visitor.base(t.topology())
} else {
static RUNTIME_VERTICES: &[bombay_transition::Vertex] = &[bombay_transition::Vertex {
id: bombay_transition::VertexId(0),
label: "executing",
}];
const RUNTIME_TOPOLOGY: bombay_transition::Topology = bombay_transition::Topology {
name: "behavior-machine (runtime)",
initial: bombay_transition::VertexId(0),
vertices: RUNTIME_VERTICES,
transitions: &[],
};
visitor.base(RUNTIME_TOPOLOGY)
}
}
}