This is my first post to the list. I've been working with MSM and have
been pulling my hair out over what I now think is a bug, either in the
library or the compiler.
If you create an action, and inside that action you do a get_attribute on
the state machine, and that state machine (MSM) is a sub-statemachine of
another (parent) MSM, and that sub-machine state happens to be the initial
state of the parent machine (that's a lot of ifs!), the code will not
compile. It aborts with the mysterious error:
c:\boost_1_51_0\boost\fusion\container\map\detail\deref_data_impl.hpp(28):
error C2039: 'second_type' : is not a member of 'boost::mpl::void_'
followed by the traditional slew of other stuff.
Although this example is easy enough to work around, I've found whether it
works or not is erratic. The one thing that seems to work OK is to move
the action out of the entry for the sub machine and into the entry of the
first state, but I haven't done enough testing to show that this works.
I've attached a zip and included the text of a sample. As is it will not
compile. You can either uncomment the attribute assignment or change the
initial state to make it compile.
Any help with this would be appreciated! Thanks!
-Chiem
Here's sample code. I've also attached a zip:
#include <vector>
#include <iostream>
#include
#include
using namespace std;
using namespace boost::msm::front::euml;
namespace msm = boost::msm;
namespace MSM_A // Concrete FSM implementation
{
BOOST_MSM_EUML_DECLARE_ATTRIBUTE(int, borrowedBuffer_attribute);
BOOST_MSM_EUML_ACTION(someAction)
{
template
void operator()(Event const& event,FSM& fsm, STATE&)
{
fsm.get_attribute(borrowedBuffer_attribute)=1; //
<--------------- UNCOMMENTING THIS WILL ALSO ALLOW COMPILATION
}
};
BOOST_MSM_EUML_EVENT(someevent)
BOOST_MSM_EUML_STATE((no_action), someStateA)
BOOST_MSM_EUML_STATE((no_action), someStateB)
BOOST_MSM_EUML_TRANSITION_TABLE((
someStateA + someevent == someStateB
),transition_table)
BOOST_MSM_EUML_DECLARE_STATE_MACHINE(( transition_table,
init_ << someStateA,
someAction, // <--------------------
ACTION IS AN ENTRY ACTION
no_action,
attributes_ << borrowedBuffer_attribute,
configure_ << no_configure_
),
MSM_A_frontEnd) //fsm name
typedef msm::back::state_machine MSM_A_player;
}
namespace MSM_B // Concrete FSM implementation
{
::MSM_A::MSM_A_player subMachine;
BOOST_MSM_EUML_EVENT(someEvent)
BOOST_MSM_EUML_STATE((no_action), someState)
BOOST_MSM_EUML_TRANSITION_TABLE((
someState + someEvent == subMachine
), transition_table)
BOOST_MSM_EUML_DECLARE_STATE_MACHINE(( transition_table, //STT
//init_ << someState, //
<---------------- WORKS
init_ << subMachine, //
<---------------- DOES NOT COMPILE
no_action, // Entry
no_action, // Exit
attributes_ << no_attributes_,
// Attributes
configure_ << no_configure_
),
MSM_B_frontEnd) //fsm name
typedef msm::back::state_machine MSM_B_player;
}
int main()
{
MSM_B::MSM_B_player player;
player.start();
return 0;
}