
Hi Jan,
i am working with the Boost 1.45 Meta State Machine, using both orthogonal regions and submachines. Overall, i am very happy with this library.
Cool :)
But i am looking for a nice way to check if a state machine (e.g. instance mAvail of class AvailFSM) is in a given state, for example i would like to write something like this:
assert(isInState(mAvail, AvailFSM::UpstreamAvailable()));
I didn't find something like "isInState" provided by the MSM library, so i came up with the following implementation:
template
bool isInState(const FSM& p, const StateType& s) { int stateId = boost::msm::back::get_state_id ::value; for (int i=0; i < FSM::nr_regions::value; ++i) { if(p.current_state()[i] == stateId) { return true; } } return false; }
This works well for simple state machines and orthogonal regions, but not for submachines. Does any one knows a way to extend the above code to work with submachines?
Hmmm not a bad idea indeed, I need to think about it, but in the meantime I have another (and I think faster) solution. See below. <snip>
Currently i am using the following workaround:
assert(isInState(mAvail, AvailFSM::UpstreamAvailable())); assert(isInState(mAvail.get_stateAvailFSM::UpstreamAvailable&(), AvailFSM::UpstreamAvailable::Primary()));
I consider this solution ugly not only because of its lengthiness, but also because "get_state" isn't a const function. Unfortunately i'am not deep enough into the template magic to tell if a const implementation of "get_state" is possible. Can anyone help me out ?
Usually, if you want to ask "isInState", you actually mean "is my fsm in such a state that a property is true?". Next, what you will want is: assert(isInState(mAvail, AvailFSM::UpstreamAvailable()) || isInState(...) && !... ); And this can pretty fast get much uglier as you need more and more conditions. To that aim, MSM offers the concept of flags, allowing you to flag a state with a certain property. You can then check if the property is true with, say: if (mAvail.is_flag_active<UpstreamOk>()) ... Please have a look at (for 1.46 but any released version of MSM can do this): http://www.boost.org/doc/libs/1_46_0/libs/msm/doc/HTML/ch03s02.html#d0e1110 Ah and it also works on submachines.
So, to sum up, i have two questions: 1) How to implement something like "isInState" that even works on submachines, if possible ?
Would the offered solution satisfy your need?
2) Is a const version of "get_state" possible ? And how?
Sure. My mistake. Will be fixed in 1.47. Would you mind opening a ticket so I don't forget it?
best regards, jan
Best regards, Christophe