I see now that it's not that that the sub-machine is a state of the main machine, but ANY time you have an entry action performed directly from the machine level the fsm is reported as a state and not as an fsm.
This isn't a problem since I know this is happening, but perhaps it might be possible to change this so fsm entry actions put the fsm in the fsm parameter slot? What is fsm equal to when an entry action is performed?
Here's some code that shows exactly what can be set where and when for anyone else who is trying to figure this out...
#include <vector>
#include <iostream>
#include <boost/msm/back/state_machine.hpp>
#include <boost/msm/front/euml/euml.hpp>
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_DECLARE_ATTRIBUTE(int, someother_Attribute);
BOOST_MSM_EUML_ACTION(someAction)
{
template <class Event,class FSM,class STATE>
void operator()(Event const& event,FSM& , STATE& state)
{
std::cout<<"Doing someAction."<<std::endl;
state.get_attribute(borrowedBuffer_attribute)=1;
}
};
BOOST_MSM_EUML_ACTION(someOtherAction)
{
template <class Event,class FSM ,class STATE>
void operator()(Event const& event,FSM& fsm, STATE& state)
{
std::cout<<"Doing someOtherAction."<<std::endl;
fsm.get_attribute(borrowedBuffer_attribute)=1;
state.get_attribute(someother_Attribute)=1;
}
};
BOOST_MSM_EUML_EVENT(someevent)
BOOST_MSM_EUML_STATE((someOtherAction, no_action, attributes_<<someother_Attribute), 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_frontEnd> MSM_A_player;
}
namespace MSM_B // Concrete FSM implementation
{
::MSM_A::MSM_A_player subMachine;
BOOST_MSM_EUML_DECLARE_ATTRIBUTE(int, rootFSM_attribute);
BOOST_MSM_EUML_DECLARE_ATTRIBUTE(int, rootstate_attribute);
BOOST_MSM_EUML_EVENT(someEvent)
BOOST_MSM_EUML_ACTION(rootFSM_action)
{
template <class Event,class FSM,class STATE>
void operator()(Event const& event,FSM& , STATE& state)
{
std::cout<<"Doing rootFSM_action."<<std::endl;
state.get_attribute(rootFSM_attribute)=1;
}
};
BOOST_MSM_EUML_ACTION(another_rootFSM_action)
{
template <class Event,class FSM,class STATE>
void operator()(Event const& event,FSM& fsm , STATE& state)
{
std::cout<<"Doing another_rootFSM_action."<<std::endl;
fsm.get_attribute(rootFSM_attribute)=1;
state.get_attribute(rootstate_attribute)=1;
}
};
BOOST_MSM_EUML_STATE((another_rootFSM_action, no_action, attributes_<<rootstate_attribute), someState)
BOOST_MSM_EUML_TRANSITION_TABLE((
someState + someEvent == someEvent
), transition_table)
BOOST_MSM_EUML_DECLARE_STATE_MACHINE(( transition_table, //STT
init_ << subMachine << someState,
rootFSM_action, // Entry
no_action, // Exit
attributes_ << rootFSM_attribute, // Attributes
configure_ << no_configure_
),
MSM_B_frontEnd) //fsm name
typedef msm::back::state_machine<MSM_B_frontEnd> MSM_B_player;
}
int main()
{
std::cout<<"Making player."<<std::endl;
MSM_B::MSM_B_player player;
std::cout<<"Starting player."<<std::endl;
player.start();
std::cin.ignore(1);
return 0;
}