Hi,
I'm trying to setup a MSM state machine, according to :
https://groups.google.com/group/boost-list/browse_thread/thread/bd9854b58a33f05a
I can setup a state machine level internal_transition_table to handle
the state-independent events.
but the build failed if the transition_table has Completion
(anonymous) transitions.
I did following test:
1. if I remove the internal_transition_table, the build succeed.
2. if I give an event to the Rows, then the build succeed tool
Row < Initialized , none , Synchronized >,
Row < Synchronized , none , WaitResponse ,
sendPoll >,
could anybody give me some clues about this? thanks.
following is the code:
#include <iostream>
// back-end
#include <boost/msm/back/state_machine.hpp>
//front-end
#include <boost/msm/front/state_machine_def.hpp>
#include <boost/msm/front/functor_row.hpp>
//#include <boost/msm/front/euml/common.hpp>
// for And_ operator
//#include <boost/msm/front/euml/operator.hpp>
using namespace std;
namespace msm = boost::msm;
using namespace msm::front;
namespace mpl = boost::mpl;
// for And_ operator
//using namespace msm::front::euml;
namespace
{
// events
struct evt_empty {};
struct evt_response{};
// front-end: define the FSM structure
struct mystatemachine_ : public
msm::front::state_machine_def<mystatemachine_>
{
// The list of FSM states
struct Initialized : public msm::front::state<>
{
// every (optional) entry/exit methods get the event passed.
template <class Event,class FSM>
void on_entry(Event const&,FSM& ) { std::cout << "entering: Initialized" << std::endl; }
template <class Event,class FSM>
void on_exit(Event const&,FSM& ) {std::cout << "leaving: Initialized" << std::endl;}
};
struct Synchronized : public msm::front::state<>
{
// every (optional) entry/exit methods get the event passed.
template <class Event,class FSM>
void on_entry(Event const&,FSM& ) { std::cout << "entering: Synchronized" << std::endl; }
template <class Event,class FSM>
void on_exit(Event const&,FSM& ) {std::cout << "leaving: Synchronized" << std::endl;}
};
struct WaitResponse : public msm::front::state<>
{
// every (optional) entry/exit methods get the event passed.
template <class Event,class FSM>
void on_entry(Event const&,FSM& ) { std::cout << "entering: WaitBSPResponse" << std::endl; }
template <class Event,class FSM>
void on_exit(Event const&,FSM& ) {std::cout << "leaving: WaitBSPResponse" << std::endl;}
};
// the initial state of the sas SM. Must be defined
typedef Initialized initial_state;
// actions
struct sendPoll
{
template <class EVT,class FSM,class SourceState,class TargetState>
void operator()(EVT const& ,FSM& ,SourceState& ,TargetState& )
{
cout << "send sync poll" << endl;
}
};
// Transition table for sas
struct transition_table : mpl::vector<
// Start Event Next Action Guard
// +----------------------+--------------------+----------------------+---------------+--------------------+
Row < Initialized , none , Synchronized >,
Row < Synchronized , none , WaitResponse , sendPoll >,
Row < WaitResponse , evt_response , WaitResponse , sendPoll , none >
// +----------------------+--------------------+----------------------+---------------+--------------------+
> {};
struct internal_guard
{
template <class EVT,class FSM,class SourceState,class TargetState>
bool operator()(EVT const& evt ,FSM&fsm,SourceState& ,TargetState& )
{
std::cout << "Empty::internal_transition_table guard " <<std::endl;
return true;
}
};
struct internal_action
{
template <class EVT,class FSM,class SourceState,class TargetState>
void operator()(EVT const& ,FSM& fsm,SourceState& ,TargetState& )
{
std::cout << "Empty::internal_transition_table action\n" <<std::endl;
}
};
struct internal_transition_table : mpl::vector<
// Start Event Next Action Guard
Internal < evt_empty , internal_action ,internal_guard >
// +---------+-------------+---------+---------------------+----------------------+
> {};
// Replaces the default no-transition response.
template <class FSM,class Event>
void no_transition(Event const& e, FSM&,int state)
{
std::cout << "no transition from state " << state << " on event " << typeid(e).name() << std::endl;
}
};
// Pick a back-end
typedef msm::back::state_machine<mystatemachine_> MyStateMachine;
//
// Testing utilities.
//
static char const* const state_names[] = { "initialized", "synchronized", "waitBSPResponse" };
void pstate(MyStateMachine const& p)
{
std::cout << " -> " << state_names[p.current_state()[0]] << std::endl;
}
void test()
{
MyStateMachine sm;
sm.start();
sm.process_event(evt_empty()); pstate(sm);
}
}