Chris@16: // Copyright 2008 Christophe Henry Chris@16: // henry UNDERSCORE christophe AT hotmail DOT com Chris@16: // This is an extended version of the state machine available in the boost::mpl library Chris@16: // Distributed under the same license as the original. Chris@16: // Copyright for the original version: Chris@16: // Copyright 2005 David Abrahams and Aleksey Gurtovoy. Distributed Chris@16: // under the Boost Software License, Version 1.0. (See accompanying Chris@16: // file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: #ifndef BOOST_MSM_FRONT_FUNCTOR_ROW_H Chris@16: #define BOOST_MSM_FRONT_FUNCTOR_ROW_H Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() Chris@16: Chris@16: BOOST_MPL_HAS_XXX_TRAIT_DEF(deferring_action) Chris@16: BOOST_MPL_HAS_XXX_TRAIT_DEF(some_deferring_actions) Chris@16: Chris@16: namespace boost { namespace msm { namespace front Chris@16: { Chris@16: template Chris@16: struct get_functor_return_value Chris@16: { Chris@16: static const ::boost::msm::back::HandledEnum value = ::boost::msm::back::HANDLED_TRUE; Chris@16: }; Chris@16: template Chris@16: struct get_functor_return_value::type Chris@16: >::type Chris@16: > Chris@16: { Chris@16: static const ::boost::msm::back::HandledEnum value = ::boost::msm::back::HANDLED_DEFERRED; Chris@16: }; Chris@16: // for sequences Chris@16: template Chris@16: struct get_functor_return_value::type Chris@16: >::type Chris@16: > Chris@16: { Chris@16: static const ::boost::msm::back::HandledEnum value = Chris@16: (Func::some_deferring_actions::value ? ::boost::msm::back::HANDLED_DEFERRED : ::boost::msm::back::HANDLED_TRUE ); Chris@16: }; Chris@16: template Chris@16: struct Row Chris@16: { Chris@16: typedef SOURCE Source; Chris@16: typedef EVENT Evt; Chris@16: typedef TARGET Target; Chris@16: typedef ACTION Action; Chris@16: typedef GUARD Guard; Chris@16: // action plus guard Chris@16: typedef row_tag row_type_tag; Chris@16: template Chris@16: static ::boost::msm::back::HandledEnum action_call(FSM& fsm,EVT const& evt,SourceState& src,TargetState& tgt, AllStates&) Chris@16: { Chris@16: // create functor, call it Chris@16: Action()(evt,fsm,src,tgt); Chris@16: return get_functor_return_value::value; Chris@16: } Chris@16: template Chris@16: static bool guard_call(FSM& fsm,EVT const& evt,SourceState& src,TargetState& tgt,AllStates&) Chris@16: { Chris@16: // create functor, call it Chris@16: return Guard()(evt,fsm,src,tgt); Chris@16: } Chris@16: }; Chris@16: Chris@16: template Chris@16: struct Row Chris@16: { Chris@16: typedef SOURCE Source; Chris@16: typedef EVENT Evt; Chris@16: typedef TARGET Target; Chris@16: typedef none Action; Chris@16: typedef none Guard; Chris@16: // no action, no guard Chris@16: typedef _row_tag row_type_tag; Chris@16: }; Chris@16: template Chris@16: struct Row Chris@16: { Chris@16: typedef SOURCE Source; Chris@16: typedef EVENT Evt; Chris@16: typedef TARGET Target; Chris@16: typedef ACTION Action; Chris@16: typedef none Guard; Chris@16: // no guard Chris@16: typedef a_row_tag row_type_tag; Chris@16: template Chris@16: static ::boost::msm::back::HandledEnum action_call(FSM& fsm,EVT const& evt,SourceState& src,TargetState& tgt, AllStates&) Chris@16: { Chris@16: // create functor, call it Chris@16: Action()(evt,fsm,src,tgt); Chris@16: return get_functor_return_value::value; Chris@16: } Chris@16: }; Chris@16: template Chris@16: struct Row Chris@16: { Chris@16: typedef SOURCE Source; Chris@16: typedef EVENT Evt; Chris@16: typedef TARGET Target; Chris@16: typedef none Action; Chris@16: typedef GUARD Guard; Chris@16: // no action Chris@16: typedef g_row_tag row_type_tag; Chris@16: template Chris@16: static bool guard_call(FSM& fsm,EVT const& evt,SourceState& src,TargetState& tgt, AllStates&) Chris@16: { Chris@16: // create functor, call it Chris@16: return Guard()(evt,fsm,src,tgt); Chris@16: } Chris@16: }; Chris@16: // internal transitions Chris@16: template Chris@16: struct Row Chris@16: { Chris@16: typedef SOURCE Source; Chris@16: typedef EVENT Evt; Chris@16: typedef Source Target; Chris@16: typedef ACTION Action; Chris@16: typedef none Guard; Chris@16: // no guard Chris@16: typedef a_irow_tag row_type_tag; Chris@16: template Chris@16: static ::boost::msm::back::HandledEnum action_call(FSM& fsm,EVT const& evt,SourceState& src,TargetState& tgt, AllStates&) Chris@16: { Chris@16: // create functor, call it Chris@16: Action()(evt,fsm,src,tgt); Chris@16: return get_functor_return_value::value; Chris@16: } Chris@16: }; Chris@16: template Chris@16: struct Row Chris@16: { Chris@16: typedef SOURCE Source; Chris@16: typedef EVENT Evt; Chris@16: typedef Source Target; Chris@16: typedef none Action; Chris@16: typedef GUARD Guard; Chris@16: // no action Chris@16: typedef g_irow_tag row_type_tag; Chris@16: template Chris@16: static bool guard_call(FSM& fsm,EVT const& evt,SourceState& src,TargetState& tgt, AllStates&) Chris@16: { Chris@16: // create functor, call it Chris@16: return Guard()(evt,fsm,src,tgt); Chris@16: } Chris@16: }; Chris@16: template Chris@16: struct Row Chris@16: { Chris@16: typedef SOURCE Source; Chris@16: typedef EVENT Evt; Chris@16: typedef Source Target; Chris@16: typedef ACTION Action; Chris@16: typedef GUARD Guard; Chris@16: // action + guard Chris@16: typedef irow_tag row_type_tag; Chris@16: template Chris@16: static ::boost::msm::back::HandledEnum action_call(FSM& fsm,EVT const& evt,SourceState& src,TargetState& tgt, AllStates&) Chris@16: { Chris@16: // create functor, call it Chris@16: Action()(evt,fsm,src,tgt); Chris@16: return get_functor_return_value::value; Chris@16: } Chris@16: template Chris@16: static bool guard_call(FSM& fsm,EVT const& evt,SourceState& src,TargetState& tgt, AllStates&) Chris@16: { Chris@16: // create functor, call it Chris@16: return Guard()(evt,fsm,src,tgt); Chris@16: } Chris@16: }; Chris@16: template Chris@16: struct Row Chris@16: { Chris@16: typedef SOURCE Source; Chris@16: typedef EVENT Evt; Chris@16: typedef Source Target; Chris@16: typedef none Action; Chris@16: typedef none Guard; Chris@16: // no action, no guard Chris@16: typedef _irow_tag row_type_tag; Chris@16: }; Chris@16: template Chris@16: struct get_row_target Chris@16: { Chris@16: typedef typename TGT::Target type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct Internal Chris@16: { Chris@16: typedef EVENT Evt; Chris@16: typedef ACTION Action; Chris@16: typedef GUARD Guard; Chris@16: // action plus guard Chris@16: typedef sm_i_row_tag row_type_tag; Chris@16: template Chris@16: static ::boost::msm::back::HandledEnum action_call(FSM& fsm,EVT const& evt,SourceState& src,TargetState& tgt, AllStates&) Chris@16: { Chris@16: // create functor, call it Chris@16: Action()(evt,fsm,src,tgt); Chris@16: return get_functor_return_value::value; Chris@16: } Chris@16: template Chris@16: static bool guard_call(FSM& fsm,EVT const& evt,SourceState& src,TargetState& tgt, AllStates&) Chris@16: { Chris@16: // create functor, call it Chris@16: return Guard()(evt,fsm,src,tgt); Chris@16: } Chris@16: }; Chris@16: Chris@16: template Chris@16: struct Internal Chris@16: { Chris@16: typedef EVENT Evt; Chris@16: typedef ACTION Action; Chris@16: typedef none Guard; Chris@16: // no guard Chris@16: typedef sm_a_i_row_tag row_type_tag; Chris@16: template Chris@16: static ::boost::msm::back::HandledEnum action_call(FSM& fsm,EVT const& evt,SourceState& src,TargetState& tgt, AllStates&) Chris@16: { Chris@16: // create functor, call it Chris@16: Action()(evt,fsm,src,tgt); Chris@16: return get_functor_return_value::value; Chris@16: } Chris@16: }; Chris@16: template Chris@16: struct Internal Chris@16: { Chris@16: typedef EVENT Evt; Chris@16: typedef none Action; Chris@16: typedef GUARD Guard; Chris@16: // no action Chris@16: typedef sm_g_i_row_tag row_type_tag; Chris@16: template Chris@16: static bool guard_call(FSM& fsm,EVT const& evt,SourceState& src,TargetState& tgt, AllStates&) Chris@16: { Chris@16: // create functor, call it Chris@16: return Guard()(evt,fsm,src,tgt); Chris@16: } Chris@16: }; Chris@16: template Chris@16: struct Internal Chris@16: { Chris@16: typedef EVENT Evt; Chris@16: typedef none Action; Chris@16: typedef none Guard; Chris@16: // no action, no guard Chris@16: typedef sm__i_row_tag row_type_tag; Chris@16: }; Chris@16: struct event_tag{}; Chris@16: struct action_tag{}; Chris@16: struct state_action_tag{}; Chris@16: struct flag_tag{}; Chris@16: struct config_tag{}; Chris@16: struct not_euml_tag{}; Chris@16: Chris@16: template Chris@16: struct ActionSequence_ Chris@16: { Chris@16: typedef Sequence sequence; Chris@16: // if one functor of the sequence defers events, the complete sequence does Chris@16: typedef ::boost::mpl::bool_< Chris@16: ::boost::mpl::count_if Chris@16: >::value != 0> some_deferring_actions; Chris@16: Chris@16: template Chris@16: struct state_action_result Chris@16: { Chris@16: typedef void type; Chris@16: }; Chris@16: template Chris@16: struct Call Chris@16: { Chris@16: Call(EVT const& evt,FSM& fsm,STATE& state): Chris@16: evt_(evt),fsm_(fsm),state_(state){} Chris@16: template Chris@16: void operator()(::boost::msm::wrap const& ) Chris@16: { Chris@16: FCT()(evt_,fsm_,state_); Chris@16: } Chris@16: private: Chris@16: EVT const& evt_; Chris@16: FSM& fsm_; Chris@16: STATE& state_; Chris@16: }; Chris@16: template Chris@16: struct transition_action_result Chris@16: { Chris@16: typedef void type; Chris@16: }; Chris@16: template Chris@16: struct Call2 Chris@16: { Chris@16: Call2(EVT const& evt,FSM& fsm,SourceState& src,TargetState& tgt): Chris@16: evt_(evt),fsm_(fsm),src_(src),tgt_(tgt){} Chris@16: template Chris@16: void operator()(::boost::msm::wrap const& ) Chris@16: { Chris@16: FCT()(evt_,fsm_,src_,tgt_); Chris@16: } Chris@16: private: Chris@16: EVT const & evt_; Chris@16: FSM& fsm_; Chris@16: SourceState& src_; Chris@16: TargetState& tgt_; Chris@16: }; Chris@16: Chris@16: typedef ::boost::mpl::set tag_type; Chris@16: Chris@16: template Chris@16: void operator()(EVT const& evt,FSM& fsm,STATE& state) Chris@16: { Chris@16: mpl::for_each > Chris@16: (Call(evt,fsm,state)); Chris@16: } Chris@16: template Chris@16: void operator()(EVT const& evt,FSM& fsm,SourceState& src,TargetState& tgt) Chris@16: { Chris@16: mpl::for_each > Chris@16: (Call2(evt,fsm,src,tgt)); Chris@16: } Chris@16: }; Chris@16: Chris@16: // functor pre-defined for basic functionality Chris@16: struct Defer Chris@16: { Chris@16: // mark as deferring to avoid stack overflows in certain conditions Chris@16: typedef int deferring_action; Chris@16: template Chris@16: void operator()(EVT const& evt,FSM& fsm,SourceState& ,TargetState& ) const Chris@16: { Chris@16: fsm.defer_event(evt); Chris@16: } Chris@16: }; Chris@16: }}} Chris@16: #endif //BOOST_MSM_FRONT_FUNCTOR_ROW_H