Max Li
Max Li

Reputation: 591

How to exchange data from/to boost MSM statemachine

I am new on MSM, and I think it's a great tool especially the eUML front-end approach. However, after days' reading, I am still not quite sure how to exchange data between a MSM eUML defined statemachine and external world. Two possible ways in my mind are:

  1. Add attributes into the statemachine using "attributes_ << Attr1", and then somehow access the Attr1 from outside world

  2. Use global variable, where fsm action functions store data and external code read the data

I have not figured out any other better ways. Regarding method 1, I am not sure how to access Attr1 from outside. I suppose "fsm_(Attr1)" is only used by the fsm internal function or method to access the attributes. So is there a way to do things list "fsm.Attr1" for outsider to read the data?

As to the method 2, obviously global variables are the thing we always try to avoid.

Any suggestions are welcome!

Upvotes: 0

Views: 478

Answers (1)

Takatoshi Kondo
Takatoshi Kondo

Reputation: 3550

You can do it using the following steps:

First defining attribute.

BOOST_MSM_EUML_DECLARE_ATTRIBUTE(type,name)

For example,

BOOST_MSM_EUML_DECLARE_ATTRIBUTE(std::stringstream,my_attr_logger)

Access the attribute.

fsm.get_attribute(name)

For example,

    template <class Event,class FSM>
    void on_entry(Event const& /*evt*/,FSM& fsm) 
    {
        std::cout << "entering: Empty" << std::endl;
        fsm.get_attribute(my_attr_logger) << "entering: Empty\n";

    }

The combination of get_attribute() and name is key point.

**Create state machine with attributes.

See https://www.boost.org/doc/libs/1_66_0/libs/msm/doc/HTML/ch03s04.html#eUML-build-sm

For example,

// create a state machine "on the fly"
BOOST_MSM_EUML_DECLARE_STATE_MACHINE(( transition_table, //STT
                                    init_ << Empty, // Init State
                                    no_action, // Entry
                                    no_action, // Exit
                                    attributes_ << my_attr_logger, // ==== Attributes
                                    configure_ << no_configure_, // configuration
                                    Log_No_Transition // no_transition handler
                                    ),
                                  player_) //fsm name

**Finally, access attribute via state machine backend from outside world.

statemachine_backend.get_attribute(name)

For example,

    std::cout <<p.get_attribute(my_attr_logger).str() << std::endl;

You can use get_attribute() of the front-end and back-end of the state machine.

Demo

Here is running demo: https://wandbox.org/permlink/nKqb2pEX5AZKeboU

my_attr_logger is the name of attribute.

I just added std::stringstream as the attribute. The base code is official example code. See https://www.boost.org/doc/libs/1_66_0/libs/msm/doc/HTML/examples/SimplePhoenix.cpp

Upvotes: 1

Related Questions