Reputation: 591
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:
Add attributes into the statemachine using "attributes_ << Attr1", and then somehow access the Attr1 from outside world
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
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