diff options
Diffstat (limited to 'boost/msm/back/dispatch_table.hpp')
-rw-r--r-- | boost/msm/back/dispatch_table.hpp | 67 |
1 files changed, 60 insertions, 7 deletions
diff --git a/boost/msm/back/dispatch_table.hpp b/boost/msm/back/dispatch_table.hpp index d233ff61db..caa830efc1 100644 --- a/boost/msm/back/dispatch_table.hpp +++ b/boost/msm/back/dispatch_table.hpp @@ -21,7 +21,9 @@ #include <boost/mpl/advance.hpp> #include <boost/type_traits/is_base_of.hpp> +#include <boost/type_traits/is_same.hpp> +#include <boost/msm/event_traits.hpp> #include <boost/msm/back/metafunctions.hpp> #include <boost/msm/back/common_types.hpp> @@ -146,6 +148,16 @@ struct dispatch_table typedef typename generate_state_set<Stt>::type state_list; BOOST_STATIC_CONSTANT(int, max_state = ( ::boost::mpl::size<state_list>::value)); + template <class Transition> + struct convert_event_and_forward + { + static HandledEnum execute(Fsm& fsm, int region_index, int state, Event const& evt) + { + typename Transition::transition_event forwarded(evt); + return Transition::execute(fsm,region_index,state,forwarded); + } + }; + // A function object for use with mpl::for_each that stuffs // transitions into cells. struct init_cell @@ -159,7 +171,7 @@ struct dispatch_table typename ::boost::disable_if< typename ::boost::is_same<typename Transition::current_state_type,Fsm>::type ,void>::type - init_event_base_case(Transition const&, ::boost::mpl::true_ const &) const + init_event_base_case(Transition const&, ::boost::mpl::true_ const &, ::boost::mpl::false_ const &) const { typedef typename create_stt<Fsm>::type stt; BOOST_STATIC_CONSTANT(int, state_id = @@ -170,18 +182,40 @@ struct dispatch_table typename ::boost::enable_if< typename ::boost::is_same<typename Transition::current_state_type,Fsm>::type ,void>::type - init_event_base_case(Transition const&, ::boost::mpl::true_ const &) const + init_event_base_case(Transition const&, ::boost::mpl::true_ const &, ::boost::mpl::false_ const &) const { self->entries[0] = reinterpret_cast<cell>(&Transition::execute); } + // version for transition event is boost::any + // first for all transitions, then for internal ones of a fsm + template <class Transition> + typename ::boost::disable_if< + typename ::boost::is_same<typename Transition::current_state_type,Fsm>::type + ,void>::type + init_event_base_case(Transition const&, ::boost::mpl::false_ const &, ::boost::mpl::true_ const &) const + { + typedef typename create_stt<Fsm>::type stt; + BOOST_STATIC_CONSTANT(int, state_id = + (get_state_id<stt,typename Transition::current_state_type>::value)); + self->entries[state_id+1] = &convert_event_and_forward<Transition>::execute; + } + template <class Transition> + typename ::boost::enable_if< + typename ::boost::is_same<typename Transition::current_state_type,Fsm>::type + ,void>::type + init_event_base_case(Transition const&, ::boost::mpl::false_ const &, ::boost::mpl::true_ const &) const + { + self->entries[0] = &convert_event_and_forward<Transition>::execute; + } + // version for transition event base of our event // first for all transitions, then for internal ones of a fsm template <class Transition> typename ::boost::disable_if< typename ::boost::is_same<typename Transition::current_state_type,Fsm>::type ,void>::type - init_event_base_case(Transition const&, ::boost::mpl::false_ const &) const + init_event_base_case(Transition const&, ::boost::mpl::false_ const &, ::boost::mpl::false_ const &) const { typedef typename create_stt<Fsm>::type stt; BOOST_STATIC_CONSTANT(int, state_id = @@ -192,7 +226,7 @@ struct dispatch_table typename ::boost::enable_if< typename ::boost::is_same<typename Transition::current_state_type,Fsm>::type ,void>::type - init_event_base_case(Transition const&, ::boost::mpl::false_ const &) const + init_event_base_case(Transition const&, ::boost::mpl::false_ const &, ::boost::mpl::false_ const &) const { self->entries[0] = &Transition::execute; } @@ -210,7 +244,9 @@ struct dispatch_table //only if the transition event is a base of our event is the reinterpret_case safe init_event_base_case(tr, ::boost::mpl::bool_< - ::boost::is_base_of<typename Transition::transition_event,Event>::type::value>() ); + ::boost::is_base_of<typename Transition::transition_event,Event>::type::value>(), + ::boost::mpl::bool_< + ::boost::msm::is_kleene_event<typename Transition::transition_event>::type::value>()); } dispatch_table* self; @@ -277,8 +313,12 @@ struct dispatch_table // this event is a compound one (not a real one, just one for use in event-less transitions) // Note this event cannot be used as deferred! + // case for internal transitions of this fsm template <class State> - void operator()(boost::msm::wrap<State> const&) + typename ::boost::disable_if< + typename ::boost::is_same<State,Fsm>::type + ,void>::type + operator()(boost::msm::wrap<State> const&,boost::msm::back::dummy<0> = 0) { typedef typename create_stt<Fsm>::type stt; BOOST_STATIC_CONSTANT(int, state_id = (get_state_id<stt,State>::value)); @@ -286,6 +326,15 @@ struct dispatch_table tofill_entries[state_id+1] = call_no_transition; } + template <class State> + typename ::boost::enable_if< + typename ::boost::is_same<State,Fsm>::type + ,void>::type + operator()(boost::msm::wrap<State> const&,boost::msm::back::dummy<1> = 0) + { + cell call_no_transition = &Fsm::default_eventless_transition; + tofill_entries[0] = call_no_transition; + } dispatch_table* self; cell* tofill_entries; }; @@ -305,7 +354,11 @@ struct dispatch_table typedef typename ::boost::mpl::reverse_fold< // filter on event ::boost::mpl::filter_view - <Stt, ::boost::is_base_of<transition_event< ::boost::mpl::placeholders::_>, Event> >, + <Stt, boost::mpl::or_< + ::boost::is_base_of<transition_event< ::boost::mpl::placeholders::_>, Event>, + ::boost::msm::is_kleene_event<transition_event< ::boost::mpl::placeholders::_> > + > + >, // build a map ::boost::mpl::map<>, ::boost::mpl::if_< |