Initial Transition's Action

The following diagrams and codes show how to implement an initial transition's action:
fig2.png
In the following code segment, the initial_state typedef just indicates that the state machine starts from State1. The initial_state typedef doesn't introduce an initial pseudo state.
        // Set initial state
        typedef State1 initial_state;

To implement a transition action from the initial pseudo state to State1, you need to define the initial pseudo state in your code. Boost.Msm doesn't support initial pseudo states directly, but you can use a normal state instead of an initial pseudo state. The original diagram changes into the diagram below:
fig3.png
You don't have to write this model. This model's purpose is that you can better understand how to implement the following code:
#include <iostream>
#include <boost/msm/back/state_machine.hpp>
 
#include <boost/msm/front/state_machine_def.hpp>
#include <boost/msm/front/functor_row.hpp>
 
namespace {
    namespace msm = boost::msm;
    namespace msmf = boost::msm::front;
    namespace mpl = boost::mpl;
 
    // ----- Events
    struct Event1 {};
 
    // ----- State machine
    struct Sm1_:msmf::state_machine_def<Sm1_>
    {
        // States
        struct Init:msmf::state<> {};
        struct State1:msmf::state<> 
        {
            // Entry action
            template <class Event,class Fsm>
            void on_entry(Event const&, Fsm&) {
                std::cout << "State1::on_entry()" << std::endl;
            }
            // Exit action
            template <class Event,class Fsm>
            void on_exit(Event const&, Fsm&) {
                std::cout << "State1::on_exit()" << std::endl;
            }
        };
 
        // Set initial state
        typedef Init initial_state;
 
        // Actions
        struct InitAction {
            template <class Event, class Fsm, class SourceState, class TargetState>
            void operator()(Event const&, Fsm&, SourceState&, TargetState&) const
            {
                std::cout << "InitAction()" << std::endl;
            }
        };
 
        // Transition table
        struct transition_table:mpl::vector<
            //          Start   Event       Next    Action      Guard
            msmf::Row < Init,   msmf::none, State1, InitAction, msmf::none >,
            msmf::Row < State1, Event1,     State1, msmf::none, msmf::none >
        > {};
    };
 
    // Pick a back-end
    typedef msm::back::state_machine<Sm1_> Sm1;
 
    void test()
    {        
        Sm1 sm1;
        sm1.start(); 
        std::cout << "> Send Event1" << std::endl;
        sm1.process_event(Event1());
    }
}
 
int main()
{
    test();
    return 0;
}
 
// Output:
//
// InitAction()
// State1::on_entry()
// > Send Event1
// State1::on_exit()
// State1::on_entry()

See the following code sengment:

            msmf::Row < Init,   msmf::none, State1, InitAction, msmf::none >,

This is a transition table's row. The important thing is that its event is msmf::none. This means the transition from Init to State1 is triggered automatically when the current state transitions to Init.
Add a New Comment