///|
/// A helper representing a Finite State Machine (FSM) manager.
pub struct Fsm[State, Data] {
mut current_state : State
mut current_data : Data
mut timer_sub : TimerSubscription?
}
///|
/// Creates a new FSM with the given initial state and state data.
pub fn[State, Data] Fsm::new(
initial_state : State,
initial_data : Data,
) -> Fsm[State, Data] {
{ current_state: initial_state, current_data: initial_data, timer_sub: None }
}
///|
/// Returns the current state of the FSM.
pub fn[State, Data] Fsm::state(self : Fsm[State, Data]) -> State {
self.current_state
}
///|
/// Returns the current state data of the FSM.
pub fn[State, Data] Fsm::data(self : Fsm[State, Data]) -> Data {
self.current_data
}
///|
/// Cancels any active timeout timer on the FSM.
pub fn[State, Data] Fsm::cancel_timer(self : Fsm[State, Data]) -> Unit {
match self.timer_sub {
Some(sub) => sub.cancel()
None => ()
}
self.timer_sub = None
}
///|
/// Transitions the FSM to a new state and data, cancelling any active timers.
pub fn[State, Data] Fsm::goto(
self : Fsm[State, Data],
next_state : State,
next_data : Data,
) -> Unit {
self.cancel_timer()
self.current_state = next_state
self.current_data = next_data
}
///|
/// Transitions the FSM to a new state and data, scheduling a state timeout message.
pub fn[State, Data, Msg] Fsm::goto_with_timeout(
self : Fsm[State, Data],
next_state : State,
next_data : Data,
timeout : (Int, Msg),
self_ref : ActorRef[Msg],
system : ActorSystem,
) -> Unit {
self.cancel_timer()
self.current_state = next_state
self.current_data = next_data
let (delay, msg) = timeout
let sub = self_ref.send_after(system, delay, msg)
self.timer_sub = Some(sub)
}