summaryrefslogtreecommitdiff
path: root/boost/msm/back/dispatch_table.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/msm/back/dispatch_table.hpp')
-rw-r--r--boost/msm/back/dispatch_table.hpp67
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_<