use std::collections::{VecDeque};
use std::fmt;
use crate::event::*;
use crate::sender::*;
use crate::handler::*;
const MAX_DEPTH: usize = 16;
pub type State<T, E> = fn(&mut T , &E) -> Response<T, E>;
pub enum Response<A, E: IsEvent> {
Handled,
Parent(State<A, E>),
Transition(State<A, E>)
}
pub trait Stator: Sender + Handler + Sized + Send {
const INIT: State<Self, Self::Event>;
fn get_stator_component_mut(&mut self) -> &mut StatorComponent<Self, Self::Event>;
fn get_stator_component(&self) -> &StatorComponent<Self, Self::Event>;
fn get_parent_state(&mut self, state: State<Self, Self::Event>) -> Option<State<Self, Self::Event>> {
let nop_event = Self::Event::new_nop_event();
return match state(self, &nop_event) {
Response::Parent(state) => Some(state),
_ => None
}
}
fn handle(&mut self, event: &Self::Event) {
let state = self.get_stator_component_mut().state;
self.call_handler(state, event);
}
fn call_handler(&mut self, handler: State<Self, Self::Event>, event: &Self::Event) {
match handler(self, event) {
Response::Transition(target_state) => self.transition(target_state),
Response::Parent(parent_state) => self.call_handler(parent_state, event),
Response::Handled => ()
}
}
fn init(&mut self) {
let mut entry_path: Vec<State<Self, Self::Event>> = Vec::with_capacity(MAX_DEPTH);
let mut entry_temp = self.get_stator_component_mut().state;
for i in 0..(MAX_DEPTH + 1) {
entry_path.push(entry_temp);
match self.get_parent_state(entry_temp) {
Some(parent_state) => entry_temp = parent_state,
None => break
}
if i == MAX_DEPTH {
panic!("Reached max state nesting depth of {}", MAX_DEPTH)
}
}
let entry_event = Self::Event::new_entry_event();
for entry_state in entry_path.into_iter().rev() {
match entry_state(self, &entry_event) {
Response::Handled => {},
Response::Transition(_) => panic!(
"Do not perform transition on entry event."),
_ => {}
}
}
}
fn transition(&mut self, target: State<Self, Self::Event>) {
let mut exit_path: Vec<State<Self, Self::Event>> = Vec::with_capacity(MAX_DEPTH);
let mut entry_path: Vec<State<Self, Self::Event>> = Vec::with_capacity(MAX_DEPTH);
let source = self.get_stator_component_mut().state;
let mut exit_temp = source;
let mut entry_temp = target;
for i in 0..(MAX_DEPTH + 1) {
exit_path.push(exit_temp);
match self.get_parent_state(exit_temp) {
Some(parent_state) => exit_temp = parent_state,
None => break
}
assert_ne!(i, MAX_DEPTH, "Reached max state nesting depth of {}", MAX_DEPTH);
}
for i in 0..(MAX_DEPTH + 1) {
entry_path.push(entry_temp);
match self.get_parent_state(entry_temp) {
Some(parent_state) => entry_temp = parent_state,
None => break
}
assert_ne!(i, MAX_DEPTH, "Reached max state nesting depth of {}", MAX_DEPTH);
}
for i in 0..(MAX_DEPTH + 1) {
entry_temp = *entry_path.last().expect(
"Only perform transitions to leaf states, i.e. states
that do not contain other sub-states");
exit_temp = *exit_path.last().expect(
"Only perform transitions to leaf states, i.e. states
that do not contain other sub-states");
if exit_temp as usize != entry_temp as usize {
break;
} else {
if entry_path.len() == 1 && exit_path.len() == 1 {
break;
} else {
entry_path.pop();
exit_path.pop();
}
}
assert_ne!(i, MAX_DEPTH, "Reached max state nesting depth of {}", MAX_DEPTH);
}
let exit_event = Self::Event::new_exit_event();
for exit_state in exit_path.into_iter() {
match exit_state(self, &exit_event) {
Response::Handled => {},
Response::Transition(_) => panic!(
"Do not perform transition on exit event."),
_ => {}
}
}
let entry_event = Self::Event::new_entry_event();
for entry_state in entry_path.into_iter().rev() {
match entry_state(self, &entry_event) {
Response::Handled => {},
Response::Transition(_) => panic!(
"Do not perform transition on entry event."),
_ => {}
}
}
self.get_stator_component_mut().state = target;
}
fn defer(&mut self, event: &Self::Event) {
let queue = &mut self.get_stator_component_mut().defered_event_queue;
queue.push_back(event.clone());
}
fn recall_all(&mut self) {
let queue = &mut self.get_stator_component_mut().defered_event_queue;
for event in queue.pop_front() {
self.post_to_self(event);
}
}
fn recall_front(&mut self) {
let queue = &mut self.get_stator_component_mut().defered_event_queue;
if let Some(event) = queue.pop_front() {
self.post_to_self(event);
}
}
fn recall_back(&mut self) {
let queue = &mut self.get_stator_component_mut().defered_event_queue;
if let Some(event) = queue.pop_back() {
self.post_to_self(event);
}
}
fn clear_defered(&mut self) {
let queue = &mut self.get_stator_component_mut().defered_event_queue;
queue.clear();
}
}
pub struct StatorComponent<T, E>
where
T: Stator<Event = E>,
E: IsEvent<Event = E> {
state: State<T, E>,
defered_event_queue: VecDeque<E>
}
impl<T, E> Default for StatorComponent<T, E>
where
T: Stator<Event = E>,
E: IsEvent<Event = E> {
fn default() -> Self {
Self {
state: T::INIT,
defered_event_queue: VecDeque::new()
}
}
}
impl<T, E> Clone for StatorComponent<T, E>
where
T: Stator<Event = E>,
E: IsEvent<Event = E> {
fn clone(&self) -> Self {
Self {
state: self.state,
defered_event_queue: self.defered_event_queue.clone()
}
}
}
impl<T, E > fmt::Debug for StatorComponent<T, E >
where
T: Stator<Event = E>,
E: IsEvent<Event = E> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
writeln!(f, "StatorComponent")
}
}