/* Command line options: -Trace -l rust -p ssc -o oven oven.xml */
/* This file is generated from oven.xml - do not edit manually */
/* Generated on: Mon Nov 28 17:57:40 CET 2022 / Version 5.5.5.5 */
use std::fmt;
/// States in which the state machine can be
#[derive(Debug,PartialEq,Copy,Clone)]
pub enum OvenStates{
Super,
Completed,
Cooking,
CookingPause,
Idle,
}
impl fmt::Display for OvenStates {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
OvenStates::Super => write!(f, "Super"),
OvenStates::Completed => write!(f, "Completed"),
OvenStates::Cooking => write!(f, "Cooking"),
OvenStates::CookingPause => write!(f, "CookingPause"),
OvenStates::Idle => write!(f, "Idle"),
}
}
}
/// Events that can be sent to the state machine
#[derive(Debug,PartialEq,Copy,Clone)]
pub enum OvenEvents {
EvDec,
EvTimeout,
EvDoorClosed,
EvDoorOpen,
EvPowerLow,
EvPowerHigh,
EvInc,
OvenNoMsg,
}
impl fmt::Display for OvenEvents {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
OvenEvents::EvDec => write!(f, "EvDec"),
OvenEvents::EvTimeout => write!(f, "EvTimeout"),
OvenEvents::EvDoorClosed => write!(f, "EvDoorClosed"),
OvenEvents::EvDoorOpen => write!(f, "EvDoorOpen"),
OvenEvents::EvPowerLow => write!(f, "EvPowerLow"),
OvenEvents::EvPowerHigh => write!(f, "EvPowerHigh"),
OvenEvents::EvInc => write!(f, "EvInc"),
OvenEvents::OvenNoMsg => write!(f, "OvenNoMsg"),
}
}
}
#[macro_export]
macro_rules! def_fsm{
($data_t:ty , $timer_service_t:ty $(,$element:ident: $ty:ty = $ex:expr)*) => {
/* State machine struct
* is_init flag indicates whether the machine event handler was called the first time
* state_var is the top level state variable
* StateXXX are the state variables for hierachical or regions
*/
#[derive(Debug,Copy,Clone)]
pub struct Oven {
pub is_init: bool,
pub state_var: OvenStates,
pub state_varmain_region: OvenStates,
/* Start of user defined attributes */
$($element: $ty),*
/* End of user defined attributes */
}
impl Default for Oven {
fn default() -> Self{
Oven {
is_init : false,
state_var : OvenStates::Super, /* Set init for top level state */
state_varmain_region : OvenStates::Idle, /* set init state of main_region */
/* Start of user defined attributes */
$($element: $ex),*
/* End of user defined attributes */
}
}
}
impl Oven{
pub fn handle_event(&mut self, ev: OvenEvents,
data:$data_t, timer_service:$timer_service_t
) -> usize {
let ev_consumed : usize;
// Create copy of statevar
let mut fsm_clone : Oven = self.clone();
if self.is_init == false {
fsm_clone.is_init = true;
fsm_clone.initialize(data, timer_service);
}
// Action code
/* just a comment */
ev_consumed = fsm_clone.oven_main_machine(ev, data, timer_service);
// Copy state variables back
*self = fsm_clone;
return ev_consumed;
}
/* Region code for state main_region */
fn oven_main_region(&mut self, ev: OvenEvents,
data:$data_t, timer_service:$timer_service_t) -> usize {
let mut ev_consumed : usize = 0;
match self.state_varmain_region {
OvenStates::Completed => {
if ev == OvenEvents::EvDoorOpen {
/* Transition from Completed to Idle */
ev_consumed=1;
/* OnEntry code of state Idle */
data.oven_off();
/* adjust state variables */
self.state_varmain_region = OvenStates::Idle;
data.log("Completed".to_string(), "Idle".to_string(), "EvDoorOpen".to_string());
} else {
/* Intentionally left blank */
} /* End of event selection */
} /* end of match Completed */
OvenStates::Cooking => {
if ev == OvenEvents::EvDoorOpen {
/* Transition from Cooking to CookingPause */
ev_consumed=1;
/* Action code for transition */
data.oven_off();
timer_service.pause(self.timer_id);
/* adjust state variables */
self.state_varmain_region = OvenStates::CookingPause;
data.log("Cooking".to_string(), "CookingPause".to_string(), "EvDoorOpen".to_string());
} else if ev == OvenEvents::EvTimeout {
/* Transition from Cooking to Completed */
ev_consumed=1;
/* Action code for transition */
data.oven_off();
timer_service.stop(self.timer_id);
/* OnEntry code of state Completed */
self.time=0;
/* adjust state variables */
self.state_varmain_region = OvenStates::Completed;
data.log("Cooking".to_string(), "Completed".to_string(), "EvTimeout".to_string());
} else {
/* Intentionally left blank */
} /* End of event selection */
} /* end of match Cooking */
OvenStates::CookingPause => {
if ev == OvenEvents::EvDoorClosed {
/* Transition from CookingPause to Cooking */
ev_consumed=1;
/* Action code for transition */
timer_service.cont(self.timer_id);
/* OnEntry code of state Cooking */
data.oven_on();
/* adjust state variables */
self.state_varmain_region = OvenStates::Cooking;
data.log("CookingPause".to_string(), "Cooking".to_string(), "EvDoorClosed".to_string());
} else {
/* Intentionally left blank */
} /* End of event selection */
} /* end of match CookingPause */
OvenStates::Idle => {
if ev == OvenEvents::EvDoorClosed {
if self.time > 0 {
/* Transition from Idle to Cooking */
ev_consumed=1;
/* Action code for transition */
timer_service.start(self.timer_id, self.time);
/* OnEntry code of state Cooking */
data.oven_on();
/* adjust state variables */
self.state_varmain_region = OvenStates::Cooking;
data.log("Idle".to_string(), "Cooking".to_string(), "EvDoorClosed[self.time > 0]".to_string());
} else {
/* Intentionally left blank */
} /* End of event selection */
} else {
/* Intentionally left blank */
} /* End of event selection */
} /* end of match Idle */
_ => {
/* Intentionally left blank */
}
} /* End match stateVar_root */
return ev_consumed;
}
pub fn initialize(&mut self, data:$data_t, timer_service:$timer_service_t){
self.is_init = true;
self.timer_id = timer_service.create(TimerType::SingleShot,OvenEvents::EvTimeout);
data.oven_off();
}
fn oven_main_machine(&mut self, ev: OvenEvents,
data:$data_t, timer_service:$timer_service_t) -> usize {
let mut ev_consumed : usize = 0;
match self.state_var {
OvenStates::Super => {
/* calling region code */
ev_consumed |= self.oven_main_region(ev, data, timer_service);
/* Check if event was already processed */
if ev_consumed==0{
if ev == OvenEvents::EvDec {
/* Transition from Super to Super */
/* Exit code for regions in state Super */
/* Action code for transition */
if self.time >= 1000{self.time += 1000;}
/* Entry code for regions in state Super */
data.oven_off();
/* Default in entry chain */
self.state_varmain_region = OvenStates::Idle;/* Default in entry chain */
/* adjust state variables */
self.state_var = OvenStates::Super;
data.log("Super".to_string(), "Super".to_string(), "EvDec".to_string());
} else if ev == OvenEvents::EvInc {
/* Transition from Super to Super */
/* Exit code for regions in state Super */
/* Action code for transition */
self.time += 1000;
/* Entry code for regions in state Super */
data.oven_off();
/* Default in entry chain */
self.state_varmain_region = OvenStates::Idle;/* Default in entry chain */
/* adjust state variables */
self.state_var = OvenStates::Super;
data.log("Super".to_string(), "Super".to_string(), "EvInc".to_string());
} else if ev == OvenEvents::EvPowerHigh {
/* Transition from Super to Super */
/* Exit code for regions in state Super */
/* Action code for transition */
data.oven_set_pwr(2000);
/* Entry code for regions in state Super */
data.oven_off();
/* Default in entry chain */
self.state_varmain_region = OvenStates::Idle;/* Default in entry chain */
/* adjust state variables */
self.state_var = OvenStates::Super;
data.log("Super".to_string(), "Super".to_string(), "EvPowerHigh".to_string());
} else if ev == OvenEvents::EvPowerLow {
/* Transition from Super to Super */
/* Exit code for regions in state Super */
/* Action code for transition */
data.oven_set_pwr(400);
/* Entry code for regions in state Super */
data.oven_off();
/* Default in entry chain */
self.state_varmain_region = OvenStates::Idle;/* Default in entry chain */
/* adjust state variables */
self.state_var = OvenStates::Super;
data.log("Super".to_string(), "Super".to_string(), "EvPowerLow".to_string());
} else {
/* Intentionally left blank */
} /* End of event selection */
}
} /* end of match Super */
_ => {
/* Intentionally left blank */
}
} /* End match stateVar_root */
return ev_consumed;
}
}
};
}