#include // back-end #include //front-end #include #include #include // for And_ operator #include 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 Throw { Throw(int id, int value):id_(id),value_(value) {} int id_; int value_; }; // front-end: define the FSM structure struct client_ : public msm::front::state_machine_def { template struct is_my_id { template bool operator()(EVT const& evt ,FSM&,SourceState& src,TargetState& ) { return evt.id_ == id; } }; // not needed in this version struct reprocess { template void operator()(EVT const& evt ,FSM& fsm,SourceState&,TargetState& ) { fsm.process_event(evt); } }; // The list of FSM states struct Init : public msm::front::state<> { }; template struct Id : public msm::front::state<> { Id():value_(0){} int value_; // every (optional) entry/exit methods get the event passed. template void on_entry(Event const& evt,FSM& ) { // todo add or init value? value_ += evt.value_; } template void on_exit(Event const&,FSM& ) { // todo store? } struct add_value { template void operator()(EVT const& evt,FSM& fsm,SourceState& self,TargetState& ) { self.value_ += evt.value_; } }; // Transition table for Empty struct internal_transition_table : mpl::vector< // Start Event Next Action Guard Internal < Throw , add_value ,is_my_id > // +---------+-------------+---------+---------------------+----------------------+ > {}; }; // the initial state of the player SM. Must be defined typedef Init initial_state; // Transition table for player struct transition_table : mpl::vector< // Start Event Next Action Guard // +---------+-------------+---------+---------------------------+----------------------+ Row < Init , Throw , Id<0> , none , is_my_id<0> >, Row < Init , Throw , Id<1> , none , is_my_id<1> >, Row < Init , Throw , Id<2> , none , is_my_id<2> >, Row < Id<0> , Throw , Id<1> , none , is_my_id<1> >, Row < Id<0> , Throw , Id<2> , none , is_my_id<2> >, Row < Id<1> , Throw , Id<0> , none , is_my_id<0> >, Row < Id<1> , Throw , Id<1> , none , is_my_id<1> >, Row < Id<2> , Throw , Id<0> , none , is_my_id<0> >, Row < Id<2> , Throw , Id<1> , none , is_my_id<1> > // +---------+-------------+---------+---------------------------+----------------------+ > {}; // Replaces the default no-transition response. template 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 client; void test() { client c; // needed to start the highest-level SM. This will call on_entry and mark the start of the SM c.start(); c.process_event(Throw(0,4)); c.process_event(Throw(0,8)); c.process_event(Throw(1,7)); std::cout << c.get_state&>().value_ << std::endl; //12 std::cout << c.get_state&>().value_ << std::endl; //7 } } int main() { test(); return 0; }