scxml2gen
Command line arguments
scxml2gen works in two modes:
C++ code generation
plantuml state diagram generation
To get a list of supported arguments run:
scxml2gen.py -h
usage: scxml2gen.py [-h] (-code | -plantuml) -scxml SCXML [-class_name CLASS_NAME] [-class_suffix CLASS_SUFFIX] [-template_hpp TEMPLATE_HPP] [-template_cpp TEMPLATE_CPP] [-dest_hpp DEST_HPP] [-dest_cpp DEST_CPP]
[-dest_dir DEST_DIR] [-out OUT]
State machine code/diagram generator
optional arguments:
-h, --help show this help message and exit
-code generate C++ code based on hsmcpp library. Supported arguments: -class_name, -class_suffix, -template_hpp, -template_cpp, -dest_hpp, -dest_cpp, -dest_dir
-plantuml generate plantuml state diagram
-scxml SCXML, -s SCXML
path to state machine in SCXML format
-class_name CLASS_NAME, -c CLASS_NAME
class name used in generated code
-class_suffix CLASS_SUFFIX, -cs CLASS_SUFFIX
suffix to append to class name (default: Base)
-template_hpp TEMPLATE_HPP, -thpp TEMPLATE_HPP
path to HPP template file
-template_cpp TEMPLATE_CPP, -tcpp TEMPLATE_CPP
path to CPP template file
-dest_hpp DEST_HPP, -dhpp DEST_HPP
path to file in which to store generated HPP content (default: ClassSuffixBase.hpp)
-dest_cpp DEST_CPP, -dcpp DEST_CPP
path to file in which to store generated CPP content (default: ClassSuffixBase.cpp)
-dest_dir DEST_DIR, -d DEST_DIR
path to folder where to store generated files (ignored if -dest_hpp and -dest_cpp are provided)
-out OUT, -o OUT path for storing generated Plantuml file (only for -plantuml)
Code generation example
Let’s look at the sample command to generate HSM from SCXML:
python3 ./tools/scxml2gen/scxml2gen.py -code -s ./examples/02_generated/02_generated.scxml -c SwitchHsm -thpp ./tools/scxml2gen/template.hpp -tcpp ./tools/scxml2gen/template.cpp -d ./
This will generate two files:
SwitchHsmBase.hpp
// Content of this file was generated
#ifndef __GEN_HSM_SWITCHHSMBASE__
#define __GEN_HSM_SWITCHHSMBASE__
#include <hsmcpp/hsm.hpp>
enum class SwitchHsmStates
{
On,
Off,
};
enum class SwitchHsmEvents
{
SWITCH,
};
class SwitchHsmBase: public HierarchicalStateMachine<SwitchHsmStates, SwitchHsmEvents>
{
public:
SwitchHsmBase();
virtual ~SwitchHsmBase();
protected:
void configureHsm();
// HSM state changed callbacks
protected:
virtual void onOff(const VariantList_t& args) = 0;
virtual void onOn(const VariantList_t& args) = 0;
// HSM state entering callbacks
protected:
// HSM state exiting callbacks
protected:
// HSM transition callbacks
protected:
// HSM transition condition callbacks
protected:
};
#endif // __GEN_HSM_SWITCHHSMBASE__
SwitchHsmBase.cpp
// Content of this file was generated
#include "SwitchHsmBase.hpp"
SwitchHsmBase::SwitchHsmBase()
: HierarchicalStateMachine<SwitchHsmStates, SwitchHsmEvents>(SwitchHsmStates::On)
{
configureHsm();
}
SwitchHsmBase::~SwitchHsmBase()
{}
void SwitchHsmBase::configureHsm()
{
registerState<SwitchHsmBase>(SwitchHsmStates::On, this, &SwitchHsmBase::onOn, nullptr, nullptr);
registerState<SwitchHsmBase>(SwitchHsmStates::Off, this, &SwitchHsmBase::onOff, nullptr, nullptr);
registerTransition<SwitchHsmBase>(SwitchHsmStates::On, SwitchHsmStates::Off, SwitchHsmEvents::SWITCH, this, nullptr);
registerTransition<SwitchHsmBase>(SwitchHsmStates::Off, SwitchHsmStates::On, SwitchHsmEvents::SWITCH, this, nullptr);
}
Using custom templates
scxml2gen comes with a predefined template for hpp and cpp files:
It it doesnt satisfy your project needs you can define your own. Currently scxml2gen supports following variables:
CLASS_NAME: name of generated class (constructed as class name + suffix provided as arguments)
ENUM_STATES: name of the enum containing HSM states (constructed as class name + “States”)
ENUM_EVENTS: name of the enum containing HSM events (constructed as class name + “Events”)
ENUM_TIMERS: name of the enum containing HSM timers (constructed as class name + “Timers”)
ENUM_STATES_ITEM: (BLOCK item) list of state names
ENUM_EVENTS_ITEM: (BLOCK item) list of event names
ENUM_TIMERS_ITEM: (BLOCK item) list of timer names
INITIAL_STATE: name of the initial state
HSM_STATE_ACTIONS: declaration of HSM onStateChanged callbacks (each function is placed on a new line)
HSM_STATE_ENTERING_ACTIONS: declaration of HSM onEntering callbacks (each function is placed on a new line)
HSM_STATE_EXITING_ACTIONS: declaration of HSM onExit callbacks (each function is placed on a new line)
HSM_TRANSITION_ACTIONS: declaration of HSM transition callbacks (each function is placed on a new line)
HSM_TRANSITION_CONDITIONS: declaration of HSM condition callbacks (each function is placed on a new line)
HPP_FILE: hpp file name
REGISTER_STATES: code registering all HSM states
REGISTER_SUBSTATES: code registering all HSM substates
REGISTER_TRANSITIONS: code registering all HSM transitions
REGISTER_TIMERS: code registering all HSM timers
REGISTER_ACTIONS: code registering all HSM actions
Variables can be referenced in two ways:
@VARIABLE@: inserts variable as-is (for example: @CLASS_NAME@ => SwitchHsmBase)
%VARIABLE%: inserts variable in upper case (for example: %CLASS_NAME% => SWITCHHSMBASE)
// Content of this file was generated
#ifndef __GEN_HSM_%CLASS_NAME%__
#define __GEN_HSM_%CLASS_NAME%__
#include <hsmcpp/hsm.hpp>
enum class @ENUM_STATES@
{
@ENUM_STATES_DEF@
};
...
Warning
TODO: describe how to use block item variables