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