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