#![allow(dead_code)]
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum StateKind {
Entry,
Exit,
Any,
Normal,
SubStateMachine,
}
#[derive(Debug, Clone)]
pub struct SmState {
pub id: u32,
pub kind: StateKind,
pub label: String,
pub position: [f32; 2],
pub is_active: bool,
}
#[derive(Debug, Clone)]
pub struct SmTransition {
pub from_id: u32,
pub to_id: u32,
pub condition: String,
}
#[derive(Debug, Clone)]
pub struct StateMachineView {
pub states: Vec<SmState>,
pub transitions: Vec<SmTransition>,
pub show_conditions: bool,
pub zoom: f32,
pub enabled: bool,
}
impl StateMachineView {
pub fn new() -> Self {
StateMachineView {
states: Vec::new(),
transitions: Vec::new(),
show_conditions: true,
zoom: 1.0,
enabled: true,
}
}
}
impl Default for StateMachineView {
fn default() -> Self {
Self::new()
}
}
pub fn new_state_machine_view() -> StateMachineView {
StateMachineView::new()
}
pub fn smv_add_state(view: &mut StateMachineView, state: SmState) {
view.states.push(state);
}
pub fn smv_add_transition(view: &mut StateMachineView, transition: SmTransition) {
view.transitions.push(transition);
}
pub fn smv_clear(view: &mut StateMachineView) {
view.states.clear();
view.transitions.clear();
}
pub fn smv_set_zoom(view: &mut StateMachineView, zoom: f32) {
view.zoom = zoom.max(0.05);
}
pub fn smv_show_conditions(view: &mut StateMachineView, show: bool) {
view.show_conditions = show;
}
pub fn smv_set_enabled(view: &mut StateMachineView, enabled: bool) {
view.enabled = enabled;
}
pub fn smv_state_count(view: &StateMachineView) -> usize {
view.states.len()
}
pub fn smv_transition_count(view: &StateMachineView) -> usize {
view.transitions.len()
}
pub fn smv_to_json(view: &StateMachineView) -> String {
format!(
r#"{{"state_count":{},"transition_count":{},"show_conditions":{},"zoom":{},"enabled":{}}}"#,
view.states.len(),
view.transitions.len(),
view.show_conditions,
view.zoom,
view.enabled
)
}
#[cfg(test)]
mod tests {
use super::*;
fn make_state(id: u32) -> SmState {
SmState {
id,
kind: StateKind::Normal,
label: format!("state_{id}"),
position: [0.0, 0.0],
is_active: false,
}
}
fn make_transition(from: u32, to: u32) -> SmTransition {
SmTransition {
from_id: from,
to_id: to,
condition: "speed > 0".to_string(),
}
}
#[test]
fn test_initial_empty() {
let v = new_state_machine_view();
assert_eq!(smv_state_count(&v), 0 );
}
#[test]
fn test_add_state() {
let mut v = new_state_machine_view();
smv_add_state(&mut v, make_state(0));
assert_eq!(smv_state_count(&v), 1 );
}
#[test]
fn test_add_transition() {
let mut v = new_state_machine_view();
smv_add_transition(&mut v, make_transition(0, 1));
assert_eq!(
smv_transition_count(&v),
1
);
}
#[test]
fn test_clear() {
let mut v = new_state_machine_view();
smv_add_state(&mut v, make_state(0));
smv_add_transition(&mut v, make_transition(0, 1));
smv_clear(&mut v);
assert_eq!(smv_state_count(&v), 0 );
assert_eq!(smv_transition_count(&v), 0 );
}
#[test]
fn test_zoom_min() {
let mut v = new_state_machine_view();
smv_set_zoom(&mut v, 0.0);
assert!((v.zoom - 0.05).abs() < 1e-6 );
}
#[test]
fn test_show_conditions() {
let mut v = new_state_machine_view();
smv_show_conditions(&mut v, false);
assert!(!v.show_conditions );
}
#[test]
fn test_set_enabled() {
let mut v = new_state_machine_view();
smv_set_enabled(&mut v, false);
assert!(!v.enabled );
}
#[test]
fn test_to_json_has_state_count() {
let v = new_state_machine_view();
let j = smv_to_json(&v);
assert!(j.contains("\"state_count\"") );
}
#[test]
fn test_enabled_default() {
let v = new_state_machine_view();
assert!(v.enabled );
}
}