Warning, file /include/boost/msm/back11/state_machine.hpp was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_MSM_BACK11_STATEMACHINE_H
0012 #define BOOST_MSM_BACK11_STATEMACHINE_H
0013
0014 #include <exception>
0015 #include <vector>
0016 #include <functional>
0017 #include <numeric>
0018 #include <utility>
0019 #include <algorithm>
0020
0021 #include <boost/core/no_exceptions_support.hpp>
0022 #include <boost/core/ignore_unused.hpp>
0023 #include <boost/type_index.hpp>
0024
0025 #include <boost/mpl/contains.hpp>
0026 #include <boost/mpl/deref.hpp>
0027 #include <boost/mpl/assert.hpp>
0028 #include <boost/mpl/vector.hpp>
0029
0030 #include <boost/fusion/mpl.hpp>
0031 #include <boost/fusion/container/vector/convert.hpp>
0032 #include <boost/fusion/include/as_vector.hpp>
0033 #include <boost/fusion/include/as_set.hpp>
0034 #include <boost/fusion/container/vector.hpp>
0035 #include <boost/fusion/include/set.hpp>
0036 #include <boost/fusion/include/set_fwd.hpp>
0037 #include <boost/fusion/include/mpl.hpp>
0038 #include <boost/fusion/include/at_key.hpp>
0039 #include <boost/fusion/include/for_each.hpp>
0040 #include <boost/fusion/include/fold.hpp>
0041 #include <boost/fusion/include/insert_range.hpp>
0042
0043 #include <boost/assert.hpp>
0044 #include <boost/ref.hpp>
0045 #include <boost/type_traits.hpp>
0046 #include <boost/utility/enable_if.hpp>
0047 #include <boost/type_traits/is_convertible.hpp>
0048
0049 #include <boost/bind/bind.hpp>
0050 #include <boost/function.hpp>
0051 #ifndef BOOST_NO_RTTI
0052 #include <boost/any.hpp>
0053 #endif
0054
0055 #include <boost/serialization/base_object.hpp>
0056
0057 #include <boost/parameter.hpp>
0058
0059 #include <boost/msm/active_state_switching_policies.hpp>
0060 #include <boost/msm/row_tags.hpp>
0061 #include <boost/msm/msm_grammar.hpp>
0062 #include <boost/msm/back/fold_to_list.hpp>
0063 #include <boost/msm/back11/metafunctions.hpp>
0064 #include <boost/msm/back/history_policies.hpp>
0065 #include <boost/msm/back/common_types.hpp>
0066 #include <boost/msm/back/args.hpp>
0067 #include <boost/msm/back/default_compile_policy.hpp>
0068 #include <boost/msm/back/no_fsm_check.hpp>
0069 #include <boost/msm/back/queue_container_deque.hpp>
0070 #include <boost/msm/back11/dispatch_table.hpp>
0071
0072 BOOST_MPL_HAS_XXX_TRAIT_DEF(accept_sig)
0073 BOOST_MPL_HAS_XXX_TRAIT_DEF(no_automatic_create)
0074 BOOST_MPL_HAS_XXX_TRAIT_DEF(non_forwarding_flag)
0075 BOOST_MPL_HAS_XXX_TRAIT_DEF(direct_entry)
0076 BOOST_MPL_HAS_XXX_TRAIT_DEF(initial_event)
0077 BOOST_MPL_HAS_XXX_TRAIT_DEF(final_event)
0078 BOOST_MPL_HAS_XXX_TRAIT_DEF(do_serialize)
0079 BOOST_MPL_HAS_XXX_TRAIT_DEF(history_policy)
0080 BOOST_MPL_HAS_XXX_TRAIT_DEF(fsm_check)
0081 BOOST_MPL_HAS_XXX_TRAIT_DEF(compile_policy)
0082 BOOST_MPL_HAS_XXX_TRAIT_DEF(queue_container_policy)
0083 BOOST_MPL_HAS_XXX_TRAIT_DEF(using_declared_table)
0084 BOOST_MPL_HAS_XXX_TRAIT_DEF(event_queue_before_deferred_queue)
0085
0086 #ifndef BOOST_MSM_CONSTRUCTOR_ARG_SIZE
0087 #define BOOST_MSM_CONSTRUCTOR_ARG_SIZE 5
0088 #endif
0089
0090 namespace boost { namespace msm { namespace back11
0091 {
0092
0093 template <class StateType,class Event>
0094 struct direct_entry_event
0095 {
0096 typedef int direct_entry;
0097 typedef StateType active_state;
0098 typedef Event contained_event;
0099
0100 direct_entry_event(Event const& evt):m_event(evt){}
0101 Event const& m_event;
0102 };
0103
0104
0105 BOOST_PARAMETER_TEMPLATE_KEYWORD(front_end)
0106 BOOST_PARAMETER_TEMPLATE_KEYWORD(history_policy)
0107 BOOST_PARAMETER_TEMPLATE_KEYWORD(compile_policy)
0108 BOOST_PARAMETER_TEMPLATE_KEYWORD(fsm_check_policy)
0109 BOOST_PARAMETER_TEMPLATE_KEYWORD(queue_container_policy)
0110
0111 typedef ::boost::parameter::parameters<
0112 ::boost::parameter::required< ::boost::msm::back11::tag::front_end >
0113 , ::boost::parameter::optional<
0114 ::boost::parameter::deduced< ::boost::msm::back11::tag::history_policy>, has_history_policy< ::boost::mpl::_ >
0115 >
0116 , ::boost::parameter::optional<
0117 ::boost::parameter::deduced< ::boost::msm::back11::tag::compile_policy>, has_compile_policy< ::boost::mpl::_ >
0118 >
0119 , ::boost::parameter::optional<
0120 ::boost::parameter::deduced< ::boost::msm::back11::tag::fsm_check_policy>, has_fsm_check< ::boost::mpl::_ >
0121 >
0122 , ::boost::parameter::optional<
0123 ::boost::parameter::deduced< ::boost::msm::back11::tag::queue_container_policy>,
0124 has_queue_container_policy< ::boost::mpl::_ >
0125 >
0126 > state_machine_signature;
0127
0128
0129 template <class T, class F,class Enable=void>
0130 struct make_euml_terminal;
0131 template <class T,class F>
0132 struct make_euml_terminal<T,F,typename ::boost::disable_if<has_using_declared_table<F> >::type>
0133 {};
0134 template <class T,class F>
0135 struct make_euml_terminal<T,F,typename ::boost::enable_if<has_using_declared_table<F> >::type>
0136 : public proto::extends<typename proto::terminal< boost::msm::state_tag>::type, T, boost::msm::state_domain>
0137 {};
0138
0139
0140
0141
0142 template <
0143 class A0
0144 , class UpperFsm = void
0145 , class A1 = parameter::void_
0146 , class A2 = parameter::void_
0147 , class A3 = parameter::void_
0148 , class A4 = parameter::void_
0149 >
0150 class state_machine :
0151 public ::boost::parameter::binding<
0152 typename state_machine_signature::bind<A0,A1,A2,A3,A4>::type, ::boost::msm::back11::tag::front_end
0153 >::type
0154 , public make_euml_terminal<state_machine<A0,UpperFsm,A1,A2,A3,A4>,
0155 typename ::boost::parameter::binding<
0156 typename state_machine_signature::bind<A0,A1,A2,A3,A4>::type, ::boost::msm::back11::tag::front_end
0157 >::type
0158 >
0159 {
0160 public:
0161
0162 typedef typename
0163 state_machine_signature::bind<A0,A1,A2,A3,A4>::type
0164 state_machine_args;
0165
0166
0167 typedef typename ::boost::parameter::binding<
0168 state_machine_args, ::boost::msm::back11::tag::front_end>::type Derived;
0169
0170 typedef typename ::boost::parameter::binding<
0171 state_machine_args, ::boost::msm::back11::tag::history_policy, ::boost::msm::back::NoHistory >::type HistoryPolicy;
0172
0173 typedef typename ::boost::parameter::binding<
0174 state_machine_args, ::boost::msm::back11::tag::compile_policy, ::boost::msm::back::favor_runtime_speed >::type CompilePolicy;
0175
0176 typedef typename ::boost::parameter::binding<
0177 state_machine_args, ::boost::msm::back11::tag::fsm_check_policy, ::boost::msm::back::no_fsm_check >::type FsmCheckPolicy;
0178
0179 typedef typename ::boost::parameter::binding<
0180 state_machine_args, ::boost::msm::back11::tag::queue_container_policy,
0181 ::boost::msm::back::queue_container_deque >::type QueueContainerPolicy;
0182
0183
0184 private:
0185
0186 typedef boost::msm::back11::state_machine<
0187 A0,UpperFsm,A1,A2,A3,A4> library_sm;
0188
0189 typedef ::boost::function<
0190 ::boost::msm::back::execute_return ()> transition_fct;
0191 typedef ::boost::function<
0192 ::boost::msm::back::execute_return () > deferred_fct;
0193 typedef typename QueueContainerPolicy::
0194 template In<
0195 std::pair<deferred_fct,char> >::type deferred_events_queue_t;
0196 typedef typename QueueContainerPolicy::
0197 template In<transition_fct>::type events_queue_t;
0198
0199 typedef typename boost::mpl::eval_if<
0200 typename is_active_state_switch_policy<Derived>::type,
0201 get_active_state_switch_policy<Derived>,
0202
0203 ::boost::mpl::identity<active_state_switch_after_entry>
0204 >::type active_state_switching;
0205
0206 typedef bool (*flag_handler)(library_sm const&);
0207
0208
0209 template <class ,class , class, class, class, class
0210 > friend class boost::msm::back11::state_machine;
0211
0212
0213
0214 template <class StateType,class Enable=void>
0215 struct visitor_fct_helper
0216 {
0217 public:
0218 visitor_fct_helper(){}
0219 void fill_visitors(int)
0220 {
0221 }
0222 template <class FCT>
0223 void insert(int,FCT)
0224 {
0225 }
0226 template <class VISITOR>
0227 void execute(int,VISITOR)
0228 {
0229 }
0230 };
0231
0232 template <class StateType>
0233 struct visitor_fct_helper<StateType,typename ::boost::enable_if<has_accept_sig<StateType> >::type>
0234 {
0235 public:
0236 visitor_fct_helper():m_state_visitors(){}
0237 void fill_visitors(int number_of_states)
0238 {
0239 m_state_visitors.resize(number_of_states);
0240 }
0241 template <class FCT>
0242 void insert(int index,FCT fct)
0243 {
0244 m_state_visitors[index]=fct;
0245 }
0246 void execute(int index)
0247 {
0248 m_state_visitors[index]();
0249 }
0250
0251 #define MSM_VISITOR_HELPER_EXECUTE_SUB(z, n, unused) ARG ## n vis ## n
0252 #define MSM_VISITOR_HELPER_EXECUTE(z, n, unused) \
0253 template <BOOST_PP_ENUM_PARAMS(n, class ARG)> \
0254 void execute(int index BOOST_PP_COMMA_IF(n) \
0255 BOOST_PP_ENUM(n, MSM_VISITOR_HELPER_EXECUTE_SUB, ~ ) ) \
0256 { \
0257 m_state_visitors[index](BOOST_PP_ENUM_PARAMS(n,vis)); \
0258 }
0259 BOOST_PP_REPEAT_FROM_TO(1,BOOST_PP_ADD(BOOST_MSM_VISITOR_ARG_SIZE,1), MSM_VISITOR_HELPER_EXECUTE, ~)
0260 #undef MSM_VISITOR_HELPER_EXECUTE
0261 #undef MSM_VISITOR_HELPER_EXECUTE_SUB
0262 private:
0263 typedef typename StateType::accept_sig::type visitor_fct;
0264 typedef std::vector<visitor_fct> visitors;
0265
0266 visitors m_state_visitors;
0267 };
0268
0269 template <class StateType,class Enable=int>
0270 struct deferred_msg_queue_helper
0271 {
0272 void clear(){}
0273 };
0274 template <class StateType>
0275 struct deferred_msg_queue_helper<StateType,
0276 typename ::boost::enable_if<
0277 typename ::boost::msm::back11::has_fsm_deferred_events<StateType>::type,int >::type>
0278 {
0279 public:
0280 deferred_msg_queue_helper():m_deferred_events_queue(),m_cur_seq(0){}
0281 void clear()
0282 {
0283 m_deferred_events_queue.clear();
0284 }
0285 deferred_events_queue_t m_deferred_events_queue;
0286 char m_cur_seq;
0287 };
0288
0289 public:
0290
0291 typedef int composite_tag;
0292
0293
0294 typedef HistoryPolicy history_policy;
0295
0296 struct InitEvent { };
0297 struct ExitEvent { };
0298
0299 struct Flag_AND
0300 {
0301 typedef std::logical_and<bool> type;
0302 };
0303 struct Flag_OR
0304 {
0305 typedef std::logical_or<bool> type;
0306 };
0307 typedef typename Derived::BaseAllStates BaseState;
0308 typedef Derived ConcreteSM;
0309
0310
0311 typedef typename ::boost::mpl::eval_if<
0312 typename has_initial_event<Derived>::type,
0313 get_initial_event<Derived>,
0314 ::boost::mpl::identity<InitEvent>
0315 >::type fsm_initial_event;
0316
0317
0318 typedef typename ::boost::mpl::eval_if<
0319 typename has_final_event<Derived>::type,
0320 get_final_event<Derived>,
0321 ::boost::mpl::identity<ExitEvent>
0322 >::type fsm_final_event;
0323
0324 template <class ExitPoint>
0325 struct exit_pt : public ExitPoint
0326 {
0327
0328 typedef ExitPoint wrapped_exit;
0329 typedef int pseudo_exit;
0330 typedef library_sm owner;
0331 typedef int no_automatic_create;
0332 typedef typename
0333 ExitPoint::event Event;
0334 typedef ::boost::function<::boost::msm::back::execute_return (Event const&)>
0335 forwarding_function;
0336
0337
0338 template <class ForwardEvent>
0339 void forward_event(ForwardEvent const& incomingEvent)
0340 {
0341
0342 ForwardHelper< ::boost::is_convertible<ForwardEvent,Event>::value>::helper(incomingEvent,m_forward);
0343 }
0344 void set_forward_fct(::boost::function<::boost::msm::back::execute_return (Event const&)> fct)
0345 {
0346 m_forward = fct;
0347 }
0348 exit_pt():m_forward(){}
0349
0350 template <class RHS>
0351 exit_pt(RHS&):m_forward(){}
0352 exit_pt<ExitPoint>& operator= (const exit_pt<ExitPoint>& )
0353 {
0354 return *this;
0355 }
0356 private:
0357 forwarding_function m_forward;
0358
0359
0360 template <bool OwnEvent, int Dummy=0>
0361 struct ForwardHelper
0362 {
0363 template <class ForwardEvent>
0364 static void helper(ForwardEvent const& ,forwarding_function& )
0365 {
0366
0367 BOOST_ASSERT(false);
0368 }
0369 };
0370 template <int Dummy>
0371 struct ForwardHelper<true,Dummy>
0372 {
0373 template <class ForwardEvent>
0374 static void helper(ForwardEvent const& incomingEvent,forwarding_function& forward_fct)
0375 {
0376
0377 if (forward_fct)
0378 forward_fct(incomingEvent);
0379 }
0380 };
0381
0382 };
0383 template <class EntryPoint>
0384 struct entry_pt : public EntryPoint
0385 {
0386
0387 typedef EntryPoint wrapped_entry;
0388 typedef int pseudo_entry;
0389 typedef library_sm owner;
0390 typedef int no_automatic_create;
0391 };
0392 template <class EntryPoint>
0393 struct direct : public EntryPoint
0394 {
0395
0396 typedef EntryPoint wrapped_entry;
0397 typedef int explicit_entry_state;
0398 typedef library_sm owner;
0399 typedef int no_automatic_create;
0400 };
0401 typedef typename get_number_of_regions<typename Derived::initial_state>::type nr_regions;
0402
0403 template<
0404 typename ROW
0405 >
0406 struct row_
0407 {
0408
0409 typedef typename make_entry<typename ROW::Source,library_sm>::type T1;
0410 typedef typename make_exit<typename ROW::Target,library_sm>::type T2;
0411 typedef typename ROW::Evt transition_event;
0412
0413
0414
0415 typedef typename ::boost::mpl::eval_if<
0416 typename has_pseudo_exit<T1>::type,
0417 get_owner<T1,library_sm>,
0418 ::boost::mpl::identity<typename ROW::Source> >::type current_state_type;
0419
0420
0421
0422
0423 typedef typename ::boost::mpl::eval_if<
0424 typename ::boost::mpl::is_sequence<T2>::type,
0425 get_fork_owner<T2,library_sm>,
0426 ::boost::mpl::eval_if<
0427 typename has_no_automatic_create<T2>::type,
0428 get_owner<T2,library_sm>,
0429 ::boost::mpl::identity<T2> >
0430 >::type next_state_type;
0431
0432
0433 static bool check_guard(library_sm& fsm,transition_event const& evt)
0434 {
0435 if ( ROW::guard_call(fsm,evt,
0436 ::boost::fusion::at_key<current_state_type>(fsm.m_substate_list),
0437 ::boost::fusion::at_key<next_state_type>(fsm.m_substate_list),
0438 fsm.m_substate_list ) )
0439 return true;
0440 return false;
0441 }
0442
0443 static ::boost::msm::back::HandledEnum execute(library_sm& fsm, int region_index, int state, transition_event& evt)
0444 {
0445
0446 BOOST_STATIC_CONSTANT(int, current_state = (get_state_id<stt,current_state_type>::type::value));
0447 BOOST_STATIC_CONSTANT(int, next_state = (get_state_id<stt,next_state_type>::type::value));
0448 boost::ignore_unused(state, current_state);
0449 BOOST_ASSERT(state == (current_state));
0450
0451 if (has_pseudo_exit<T1>::type::value &&
0452 !is_exit_state_active<T1,get_owner<T1,library_sm> >(fsm))
0453 {
0454 return ::boost::msm::back::HANDLED_FALSE;
0455 }
0456 if (!check_guard(fsm,evt))
0457 {
0458
0459 return ::boost::msm::back::HANDLED_GUARD_REJECT;
0460 }
0461 fsm.m_states[region_index] = active_state_switching::after_guard(current_state,next_state);
0462
0463
0464 execute_exit<current_state_type>
0465 (::boost::fusion::at_key<current_state_type>(fsm.m_substate_list),evt,fsm);
0466 fsm.m_states[region_index] = active_state_switching::after_exit(current_state,next_state);
0467
0468
0469 ::boost::msm::back::HandledEnum res = ROW::action_call(fsm,const_cast<transition_event&>(evt),
0470 ::boost::fusion::at_key<current_state_type>(fsm.m_substate_list),
0471 ::boost::fusion::at_key<next_state_type>(fsm.m_substate_list),
0472 fsm.m_substate_list);
0473 fsm.m_states[region_index] = active_state_switching::after_action(current_state,next_state);
0474
0475
0476 convert_event_and_execute_entry<next_state_type,T2>
0477 (::boost::fusion::at_key<next_state_type>(fsm.m_substate_list),evt,fsm);
0478 fsm.m_states[region_index] = active_state_switching::after_entry(current_state,next_state);
0479 return res;
0480 }
0481 };
0482
0483
0484 template<
0485 typename ROW
0486 >
0487 struct g_row_
0488 {
0489
0490 typedef typename make_entry<typename ROW::Source,library_sm>::type T1;
0491 typedef typename make_exit<typename ROW::Target,library_sm>::type T2;
0492 typedef typename ROW::Evt transition_event;
0493
0494
0495
0496 typedef typename ::boost::mpl::eval_if<
0497 typename has_pseudo_exit<T1>::type,
0498 get_owner<T1,library_sm>,
0499 ::boost::mpl::identity<typename ROW::Source> >::type current_state_type;
0500
0501
0502
0503
0504 typedef typename ::boost::mpl::eval_if<
0505 typename ::boost::mpl::is_sequence<T2>::type,
0506 get_fork_owner<T2,library_sm>,
0507 ::boost::mpl::eval_if<
0508 typename has_no_automatic_create<T2>::type,
0509 get_owner<T2,library_sm>,
0510 ::boost::mpl::identity<T2> >
0511 >::type next_state_type;
0512
0513
0514 static bool check_guard(library_sm& fsm,transition_event const& evt)
0515 {
0516 if ( ROW::guard_call(fsm,evt,
0517 ::boost::fusion::at_key<current_state_type>(fsm.m_substate_list),
0518 ::boost::fusion::at_key<next_state_type>(fsm.m_substate_list),
0519 fsm.m_substate_list ))
0520 return true;
0521 return false;
0522 }
0523
0524 static ::boost::msm::back::HandledEnum execute(library_sm& fsm, int region_index, int state, transition_event const& evt)
0525 {
0526 BOOST_STATIC_CONSTANT(int, current_state = (get_state_id<stt,current_state_type>::type::value));
0527 BOOST_STATIC_CONSTANT(int, next_state = (get_state_id<stt,next_state_type>::type::value));
0528 boost::ignore_unused(state, current_state);
0529 BOOST_ASSERT(state == (current_state));
0530
0531
0532 if (has_pseudo_exit<T1>::type::value &&
0533 !is_exit_state_active<T1,get_owner<T1,library_sm> >(fsm))
0534 {
0535 return ::boost::msm::back::HANDLED_FALSE;
0536 }
0537 if (!check_guard(fsm,evt))
0538 {
0539
0540 return ::boost::msm::back::HANDLED_GUARD_REJECT;
0541 }
0542 fsm.m_states[region_index] = active_state_switching::after_guard(current_state,next_state);
0543
0544
0545 execute_exit<current_state_type>
0546 (::boost::fusion::at_key<current_state_type>(fsm.m_substate_list),evt,fsm);
0547 fsm.m_states[region_index] = active_state_switching::after_exit(current_state,next_state);
0548 fsm.m_states[region_index] = active_state_switching::after_action(current_state,next_state);
0549
0550
0551 convert_event_and_execute_entry<next_state_type,T2>
0552 (::boost::fusion::at_key<next_state_type>(fsm.m_substate_list),evt,fsm);
0553 fsm.m_states[region_index] = active_state_switching::after_entry(current_state,next_state);
0554 return ::boost::msm::back::HANDLED_TRUE;
0555 }
0556 };
0557
0558
0559 template<
0560 typename ROW
0561 >
0562 struct a_row_
0563 {
0564
0565 typedef typename make_entry<typename ROW::Source,library_sm>::type T1;
0566 typedef typename make_exit<typename ROW::Target,library_sm>::type T2;
0567 typedef typename ROW::Evt transition_event;
0568
0569
0570
0571 typedef typename ::boost::mpl::eval_if<
0572 typename has_pseudo_exit<T1>::type,
0573 get_owner<T1,library_sm>,
0574 ::boost::mpl::identity<typename ROW::Source> >::type current_state_type;
0575
0576
0577
0578
0579 typedef typename ::boost::mpl::eval_if<
0580 typename ::boost::mpl::is_sequence<T2>::type,
0581 get_fork_owner<T2,library_sm>,
0582 ::boost::mpl::eval_if<
0583 typename has_no_automatic_create<T2>::type,
0584 get_owner<T2,library_sm>,
0585 ::boost::mpl::identity<T2> >
0586 >::type next_state_type;
0587
0588
0589 static ::boost::msm::back::HandledEnum execute(library_sm& fsm, int region_index, int state, transition_event const& evt)
0590 {
0591 BOOST_STATIC_CONSTANT(int, current_state = (get_state_id<stt,current_state_type>::type::value));
0592 BOOST_STATIC_CONSTANT(int, next_state = (get_state_id<stt,next_state_type>::type::value));
0593 boost::ignore_unused(state, current_state);
0594 BOOST_ASSERT(state == (current_state));
0595
0596
0597 if (has_pseudo_exit<T1>::type::value &&
0598 !is_exit_state_active<T1,get_owner<T1,library_sm> >(fsm))
0599 {
0600 return ::boost::msm::back::HANDLED_FALSE;
0601 }
0602 fsm.m_states[region_index] = active_state_switching::after_guard(current_state,next_state);
0603
0604
0605
0606 execute_exit<current_state_type>
0607 (::boost::fusion::at_key<current_state_type>(fsm.m_substate_list),evt,fsm);
0608 fsm.m_states[region_index] = active_state_switching::after_exit(current_state,next_state);
0609
0610
0611 ::boost::msm::back::HandledEnum res = ROW::action_call(fsm,const_cast<transition_event&>(evt),
0612 ::boost::fusion::at_key<current_state_type>(fsm.m_substate_list),
0613 ::boost::fusion::at_key<next_state_type>(fsm.m_substate_list),
0614 fsm.m_substate_list);
0615 fsm.m_states[region_index] = active_state_switching::after_action(current_state,next_state);
0616
0617
0618 convert_event_and_execute_entry<next_state_type,T2>
0619 (::boost::fusion::at_key<next_state_type>(fsm.m_substate_list),evt,fsm);
0620 fsm.m_states[region_index] = active_state_switching::after_entry(current_state,next_state);
0621 return res;
0622 }
0623 };
0624
0625
0626 template<
0627 typename ROW
0628 >
0629 struct _row_
0630 {
0631
0632 typedef typename make_entry<typename ROW::Source,library_sm>::type T1;
0633 typedef typename make_exit<typename ROW::Target,library_sm>::type T2;
0634 typedef typename ROW::Evt transition_event;
0635
0636
0637
0638 typedef typename ::boost::mpl::eval_if<
0639 typename has_pseudo_exit<T1>::type,
0640 get_owner<T1,library_sm>,
0641 ::boost::mpl::identity<typename ROW::Source> >::type current_state_type;
0642
0643
0644
0645
0646 typedef typename ::boost::mpl::eval_if<
0647 typename ::boost::mpl::is_sequence<T2>::type,
0648 get_fork_owner<T2,library_sm>,
0649 ::boost::mpl::eval_if<
0650 typename has_no_automatic_create<T2>::type,
0651 get_owner<T2,library_sm>,
0652 ::boost::mpl::identity<T2> >
0653 >::type next_state_type;
0654
0655
0656 static ::boost::msm::back::HandledEnum execute(library_sm& fsm, int region_index, int state, transition_event const& evt)
0657 {
0658 BOOST_STATIC_CONSTANT(int, current_state = (get_state_id<stt,current_state_type>::type::value));
0659 BOOST_STATIC_CONSTANT(int, next_state = (get_state_id<stt,next_state_type>::type::value));
0660 boost::ignore_unused(state, current_state);
0661 BOOST_ASSERT(state == (current_state));
0662
0663
0664 if (has_pseudo_exit<T1>::type::value &&
0665 !is_exit_state_active<T1,get_owner<T1,library_sm> >(fsm))
0666 {
0667 return ::boost::msm::back::HANDLED_FALSE;
0668 }
0669 fsm.m_states[region_index] = active_state_switching::after_guard(current_state,next_state);
0670
0671
0672 execute_exit<current_state_type>
0673 (::boost::fusion::at_key<current_state_type>(fsm.m_substate_list),evt,fsm);
0674 fsm.m_states[region_index] = active_state_switching::after_exit(current_state,next_state);
0675 fsm.m_states[region_index] = active_state_switching::after_action(current_state,next_state);
0676
0677
0678
0679 convert_event_and_execute_entry<next_state_type,T2>
0680 (::boost::fusion::at_key<next_state_type>(fsm.m_substate_list),evt,fsm);
0681 fsm.m_states[region_index] = active_state_switching::after_entry(current_state,next_state);
0682 return ::boost::msm::back::HANDLED_TRUE;
0683 }
0684 };
0685
0686 template<
0687 typename ROW
0688 >
0689 struct irow_
0690 {
0691 typedef typename make_entry<typename ROW::Source,library_sm>::type T1;
0692 typedef typename make_exit<typename ROW::Target,library_sm>::type T2;
0693 typedef typename ROW::Evt transition_event;
0694 typedef typename ROW::Source current_state_type;
0695 typedef T2 next_state_type;
0696
0697
0698 static bool check_guard(library_sm& fsm,transition_event const& evt)
0699 {
0700 if ( ROW::guard_call(fsm,evt,
0701 ::boost::fusion::at_key<current_state_type>(fsm.m_substate_list),
0702 ::boost::fusion::at_key<next_state_type>(fsm.m_substate_list),
0703 fsm.m_substate_list))
0704 return true;
0705 return false;
0706 }
0707
0708 static ::boost::msm::back::HandledEnum execute(library_sm& fsm, int , int state, transition_event const& evt)
0709 {
0710
0711 BOOST_STATIC_CONSTANT(int, current_state = (get_state_id<stt,current_state_type>::type::value));
0712 boost::ignore_unused(state, current_state);
0713 BOOST_ASSERT(state == (current_state));
0714
0715 if (!check_guard(fsm,evt))
0716 {
0717
0718 return ::boost::msm::back::HANDLED_GUARD_REJECT;
0719 }
0720
0721
0722 ::boost::msm::back::HandledEnum res = ROW::action_call(fsm,const_cast<transition_event&>(evt),
0723 ::boost::fusion::at_key<current_state_type>(fsm.m_substate_list),
0724 ::boost::fusion::at_key<next_state_type>(fsm.m_substate_list),
0725 fsm.m_substate_list);
0726 return res;
0727 }
0728 };
0729
0730
0731 template<
0732 typename ROW
0733 >
0734 struct g_irow_
0735 {
0736 typedef typename make_entry<typename ROW::Source,library_sm>::type T1;
0737 typedef typename make_exit<typename ROW::Target,library_sm>::type T2;
0738 typedef typename ROW::Evt transition_event;
0739 typedef typename ROW::Source current_state_type;
0740 typedef T2 next_state_type;
0741
0742
0743 static bool check_guard(library_sm& fsm,transition_event const& evt)
0744 {
0745 if ( ROW::guard_call(fsm,evt,
0746 ::boost::fusion::at_key<current_state_type>(fsm.m_substate_list),
0747 ::boost::fusion::at_key<next_state_type>(fsm.m_substate_list),
0748 fsm.m_substate_list) )
0749 return true;
0750 return false;
0751 }
0752
0753 static ::boost::msm::back::HandledEnum execute(library_sm& fsm, int , int state, transition_event const& evt)
0754 {
0755 BOOST_STATIC_CONSTANT(int, current_state = (get_state_id<stt,current_state_type>::type::value));
0756 boost::ignore_unused(state, current_state);
0757 BOOST_ASSERT(state == (current_state));
0758
0759 if (!check_guard(fsm,evt))
0760 {
0761
0762 return ::boost::msm::back::HANDLED_GUARD_REJECT;
0763 }
0764 return ::boost::msm::back::HANDLED_TRUE;
0765 }
0766 };
0767
0768
0769 template<
0770 typename ROW
0771 >
0772 struct a_irow_
0773 {
0774 typedef typename make_entry<typename ROW::Source,library_sm>::type T1;
0775 typedef typename make_exit<typename ROW::Target,library_sm>::type T2;
0776
0777 typedef typename ROW::Evt transition_event;
0778 typedef typename ROW::Source current_state_type;
0779 typedef T2 next_state_type;
0780
0781
0782 static ::boost::msm::back::HandledEnum execute(library_sm& fsm, int , int state, transition_event const& evt)
0783 {
0784 BOOST_STATIC_CONSTANT(int, current_state = (get_state_id<stt,current_state_type>::type::value));
0785 boost::ignore_unused(state, current_state);
0786 BOOST_ASSERT(state == (current_state));
0787
0788
0789 ::boost::msm::back::HandledEnum res = ROW::action_call(fsm,const_cast<transition_event&>(evt),
0790 ::boost::fusion::at_key<current_state_type>(fsm.m_substate_list),
0791 ::boost::fusion::at_key<next_state_type>(fsm.m_substate_list),
0792 fsm.m_substate_list);
0793
0794 return res;
0795 }
0796 };
0797
0798 template<
0799 typename ROW
0800 >
0801 struct _irow_
0802 {
0803 typedef typename make_entry<typename ROW::Source,library_sm>::type T1;
0804 typedef typename make_exit<typename ROW::Target,library_sm>::type T2;
0805 typedef typename ROW::Evt transition_event;
0806 typedef typename ROW::Source current_state_type;
0807 typedef T2 next_state_type;
0808
0809
0810 static ::boost::msm::back::HandledEnum execute(library_sm& , int , int state, transition_event const& )
0811 {
0812 BOOST_STATIC_CONSTANT(int, current_state = (get_state_id<stt,current_state_type>::type::value));
0813 boost::ignore_unused(state, current_state);
0814 BOOST_ASSERT(state == (current_state));
0815 return ::boost::msm::back::HANDLED_TRUE;
0816 }
0817 };
0818
0819 template<
0820 typename ROW,
0821 typename StateType
0822 >
0823 struct internal_
0824 {
0825 typedef StateType current_state_type;
0826 typedef StateType next_state_type;
0827 typedef typename ROW::Evt transition_event;
0828
0829
0830 static bool check_guard(library_sm& fsm,transition_event const& evt)
0831 {
0832 if ( ROW::guard_call(fsm,evt,
0833 ::boost::fusion::at_key<StateType>(fsm.m_substate_list),
0834 ::boost::fusion::at_key<StateType>(fsm.m_substate_list),
0835 fsm.m_substate_list) )
0836 return true;
0837 return false;
0838 }
0839
0840 static ::boost::msm::back::HandledEnum execute(library_sm& fsm, int , int , transition_event const& evt)
0841 {
0842 if (!check_guard(fsm,evt))
0843 {
0844
0845 return ::boost::msm::back::HANDLED_GUARD_REJECT;
0846 }
0847
0848
0849 ::boost::msm::back::HandledEnum res = ROW::action_call(fsm,const_cast<transition_event&>(evt),
0850 ::boost::fusion::at_key<StateType>(fsm.m_substate_list),
0851 ::boost::fusion::at_key<StateType>(fsm.m_substate_list),
0852 fsm.m_substate_list);
0853 return res;
0854 }
0855 };
0856 template<
0857 typename ROW
0858 >
0859 struct internal_ <ROW,library_sm>
0860 {
0861 typedef library_sm current_state_type;
0862 typedef library_sm next_state_type;
0863 typedef typename ROW::Evt transition_event;
0864
0865
0866 static bool check_guard(library_sm& fsm,transition_event const& evt)
0867 {
0868 if ( ROW::guard_call(fsm,evt,
0869 fsm,
0870 fsm,
0871 fsm.m_substate_list) )
0872 return true;
0873 return false;
0874 }
0875
0876 static ::boost::msm::back::HandledEnum execute(library_sm& fsm, int , int , transition_event const& evt)
0877 {
0878 if (!check_guard(fsm,evt))
0879 {
0880
0881 return ::boost::msm::back::HANDLED_GUARD_REJECT;
0882 }
0883
0884
0885 ::boost::msm::back::HandledEnum res = ROW::action_call(fsm,const_cast<transition_event&>(evt),
0886 fsm,
0887 fsm,
0888 fsm.m_substate_list);
0889 return res;
0890 }
0891 };
0892
0893 template<
0894 typename ROW,
0895 typename StateType
0896 >
0897 struct a_internal_
0898 {
0899 typedef StateType current_state_type;
0900 typedef StateType next_state_type;
0901 typedef typename ROW::Evt transition_event;
0902
0903
0904 static ::boost::msm::back::HandledEnum execute(library_sm& fsm, int, int, transition_event const& evt)
0905 {
0906
0907 ::boost::msm::back::HandledEnum res = ROW::action_call(fsm,const_cast<transition_event&>(evt),
0908 ::boost::fusion::at_key<StateType>(fsm.m_substate_list),
0909 ::boost::fusion::at_key<StateType>(fsm.m_substate_list),
0910 fsm.m_substate_list);
0911 return res;
0912 }
0913 };
0914 template<
0915 typename ROW
0916 >
0917 struct a_internal_ <ROW,library_sm>
0918 {
0919 typedef library_sm current_state_type;
0920 typedef library_sm next_state_type;
0921 typedef typename ROW::Evt transition_event;
0922
0923
0924 static ::boost::msm::back::HandledEnum execute(library_sm& fsm, int, int, transition_event const& evt)
0925 {
0926
0927 ::boost::msm::back::HandledEnum res = ROW::action_call(fsm,const_cast<transition_event&>(evt),
0928 fsm,
0929 fsm,
0930 fsm.m_substate_list);
0931 return res;
0932 }
0933 };
0934 template<
0935 typename ROW,
0936 typename StateType
0937 >
0938 struct g_internal_
0939 {
0940 typedef StateType current_state_type;
0941 typedef StateType next_state_type;
0942 typedef typename ROW::Evt transition_event;
0943
0944
0945 static bool check_guard(library_sm& fsm,transition_event const& evt)
0946 {
0947 if ( ROW::guard_call(fsm,evt,
0948 ::boost::fusion::at_key<StateType>(fsm.m_substate_list),
0949 ::boost::fusion::at_key<StateType>(fsm.m_substate_list),
0950 fsm.m_substate_list) )
0951 return true;
0952 return false;
0953 }
0954
0955 static ::boost::msm::back::HandledEnum execute(library_sm& fsm, int, int, transition_event const& evt)
0956 {
0957 if (!check_guard(fsm,evt))
0958 {
0959
0960 return ::boost::msm::back::HANDLED_GUARD_REJECT;
0961 }
0962 return ::boost::msm::back::HANDLED_TRUE;
0963 }
0964 };
0965 template<
0966 typename ROW
0967 >
0968 struct g_internal_ <ROW,library_sm>
0969 {
0970 typedef library_sm current_state_type;
0971 typedef library_sm next_state_type;
0972 typedef typename ROW::Evt transition_event;
0973
0974
0975 static bool check_guard(library_sm& fsm,transition_event const& evt)
0976 {
0977 if ( ROW::guard_call(fsm,evt,
0978 fsm,
0979 fsm,
0980 fsm.m_substate_list) )
0981 return true;
0982 return false;
0983 }
0984
0985 static ::boost::msm::back::HandledEnum execute(library_sm& fsm, int, int, transition_event const& evt)
0986 {
0987 if (!check_guard(fsm,evt))
0988 {
0989
0990 return ::boost::msm::back::HANDLED_GUARD_REJECT;
0991 }
0992 return ::boost::msm::back::HANDLED_TRUE;
0993 }
0994 };
0995 template<
0996 typename ROW,
0997 typename StateType
0998 >
0999 struct _internal_
1000 {
1001 typedef StateType current_state_type;
1002 typedef StateType next_state_type;
1003 typedef typename ROW::Evt transition_event;
1004 static ::boost::msm::back::HandledEnum execute(library_sm& , int , int , transition_event const& )
1005 {
1006 return ::boost::msm::back::HANDLED_TRUE;
1007 }
1008 };
1009 template<
1010 typename ROW
1011 >
1012 struct _internal_ <ROW,library_sm>
1013 {
1014 typedef library_sm current_state_type;
1015 typedef library_sm next_state_type;
1016 typedef typename ROW::Evt transition_event;
1017 static ::boost::msm::back::HandledEnum execute(library_sm& , int , int , transition_event const& )
1018 {
1019 return ::boost::msm::back::HANDLED_TRUE;
1020 }
1021 };
1022
1023 template<
1024 typename T1
1025 , class Evt
1026 >
1027 struct frow
1028 {
1029 typedef T1 current_state_type;
1030 typedef T1 next_state_type;
1031 typedef Evt transition_event;
1032
1033 typedef int is_frow;
1034
1035
1036 static ::boost::msm::back::HandledEnum execute(library_sm& fsm, int region_index, int , transition_event& evt)
1037 {
1038
1039 ::boost::msm::back::execute_return res =
1040 (::boost::fusion::at_key<current_state_type>(fsm.m_substate_list)).process_event_internal(evt);
1041 fsm.m_states[region_index]=get_state_id<stt,T1>::type::value;
1042
1043 return res;
1044 }
1045
1046
1047 template <class NewEvent>
1048 struct replace_event
1049 {
1050 typedef frow<T1,NewEvent> type;
1051 };
1052 };
1053
1054 template <class Tag, class Transition,class StateType>
1055 struct create_backend_stt
1056 {
1057 };
1058 template <class Transition,class StateType>
1059 struct create_backend_stt<g_row_tag,Transition,StateType>
1060 {
1061 typedef g_row_<Transition> type;
1062 };
1063 template <class Transition,class StateType>
1064 struct create_backend_stt<a_row_tag,Transition,StateType>
1065 {
1066 typedef a_row_<Transition> type;
1067 };
1068 template <class Transition,class StateType>
1069 struct create_backend_stt<_row_tag,Transition,StateType>
1070 {
1071 typedef _row_<Transition> type;
1072 };
1073 template <class Transition,class StateType>
1074 struct create_backend_stt<row_tag,Transition,StateType>
1075 {
1076 typedef row_<Transition> type;
1077 };
1078
1079 template <class Transition,class StateType>
1080 struct create_backend_stt<g_irow_tag,Transition,StateType>
1081 {
1082 typedef g_irow_<Transition> type;
1083 };
1084 template <class Transition,class StateType>
1085 struct create_backend_stt<a_irow_tag,Transition,StateType>
1086 {
1087 typedef a_irow_<Transition> type;
1088 };
1089 template <class Transition,class StateType>
1090 struct create_backend_stt<irow_tag,Transition,StateType>
1091 {
1092 typedef irow_<Transition> type;
1093 };
1094 template <class Transition,class StateType>
1095 struct create_backend_stt<_irow_tag,Transition,StateType>
1096 {
1097 typedef _irow_<Transition> type;
1098 };
1099 template <class Transition,class StateType>
1100 struct create_backend_stt<sm_a_i_row_tag,Transition,StateType>
1101 {
1102 typedef a_internal_<Transition,StateType> type;
1103 };
1104 template <class Transition,class StateType>
1105 struct create_backend_stt<sm_g_i_row_tag,Transition,StateType>
1106 {
1107 typedef g_internal_<Transition,StateType> type;
1108 };
1109 template <class Transition,class StateType>
1110 struct create_backend_stt<sm_i_row_tag,Transition,StateType>
1111 {
1112 typedef internal_<Transition,StateType> type;
1113 };
1114 template <class Transition,class StateType>
1115 struct create_backend_stt<sm__i_row_tag,Transition,StateType>
1116 {
1117 typedef _internal_<Transition,StateType> type;
1118 };
1119 template <class Transition,class StateType=void>
1120 struct make_row_tag
1121 {
1122 typedef typename create_backend_stt<typename Transition::row_type_tag,Transition,StateType>::type type;
1123 };
1124
1125
1126 template <class BaseType, class stt_simulated = typename BaseType::transition_table>
1127 struct create_real_stt
1128 {
1129
1130 typedef typename ::boost::mpl::fold<
1131 stt_simulated,boost::fusion::vector0<>,
1132 ::boost::mpl::push_back< ::boost::mpl::placeholders::_1,
1133 make_row_tag< ::boost::mpl::placeholders::_2 , BaseType > >
1134 >::type type;
1135 };
1136
1137 template <class Table,class Intermediate,class StateType>
1138 struct add_forwarding_row_helper
1139 {
1140 typedef typename generate_event_set<Table>::type all_events;
1141 typedef typename ::boost::mpl::fold<
1142 all_events, Intermediate,
1143 ::boost::mpl::push_back< ::boost::mpl::placeholders::_1,
1144 frow<StateType, ::boost::mpl::placeholders::_2> > >::type type;
1145 };
1146
1147 template <class StateType,class IsComposite>
1148 struct get_internal_transition_table
1149 {
1150
1151 typedef typename recursive_get_transition_table<StateType>::type original_table;
1152
1153
1154
1155
1156 typedef typename recursive_get_internal_transition_table<StateType, ::boost::mpl::true_>::type recursive_istt;
1157 typedef typename ::boost::mpl::fold<
1158 recursive_istt,::boost::fusion::vector<>,
1159 ::boost::mpl::push_back< ::boost::mpl::placeholders::_1,
1160 make_row_tag< ::boost::mpl::placeholders::_2 , StateType> >
1161 >::type recursive_istt_with_tag;
1162
1163
1164
1165
1166 typedef typename ::boost::fusion::result_of::as_vector<
1167 typename ::boost::fusion::result_of::insert_range<
1168 original_table,
1169 typename ::boost::fusion::result_of::end<original_table>::type,
1170 recursive_istt_with_tag
1171 >::type
1172 >::type table_with_all_events;
1173
1174
1175 typedef typename ::boost::mpl::eval_if<
1176 typename CompilePolicy::add_forwarding_rows,
1177 add_forwarding_row_helper<table_with_all_events,::boost::fusion::vector<>,StateType>,
1178 ::boost::mpl::identity< ::boost::fusion::vector<> >
1179 >::type type;
1180 };
1181 template <class StateType>
1182 struct get_internal_transition_table<StateType, ::boost::mpl::false_ >
1183 {
1184 typedef typename create_real_stt<StateType, typename StateType::internal_transition_table >::type type;
1185 };
1186
1187 typedef typename create_real_stt<Derived>::type real_transition_table;
1188 typedef typename create_stt<library_sm>::type stt;
1189 typedef typename get_initial_states<typename Derived::initial_state>::type initial_states;
1190 typedef typename generate_state_set<stt>::type state_list;
1191 typedef typename HistoryPolicy::template apply<nr_regions::value>::type concrete_history;
1192
1193 typedef typename ::boost::fusion::result_of::as_set<state_list>::type substate_list;
1194
1195 typedef typename ::boost::msm::back11::generate_event_set<
1196 typename create_real_stt<library_sm, typename library_sm::internal_transition_table >::type
1197 >::type processable_events_internal_table;
1198
1199
1200 template <class Composite>
1201 struct extend_table
1202 {
1203
1204
1205 typedef typename Composite::stt Stt;
1206
1207
1208
1209
1210
1211 typedef typename ::boost::mpl::fold<
1212 typename Composite::internal_transition_table,::boost::fusion::vector<>,
1213 ::boost::mpl::push_back< ::boost::mpl::placeholders::_1,
1214 make_row_tag< ::boost::mpl::placeholders::_2 , Composite> >
1215 >::type internal_stt;
1216
1217
1218
1219
1220
1221
1222
1223
1224 typedef typename ::boost::fusion::result_of::as_vector<
1225 typename ::boost::fusion::result_of::insert_range<
1226 Stt,
1227 typename ::boost::fusion::result_of::end<Stt>::type,
1228 internal_stt
1229 >::type >::type stt_plus_internal;
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242 typedef typename ::boost::mpl::fold<
1243 state_list,stt_plus_internal,
1244 ::boost::fusion::result_of::as_vector<
1245 ::boost::fusion::result_of::insert_range<
1246 ::boost::mpl::placeholders::_1,
1247 ::boost::fusion::result_of::end< ::boost::mpl::placeholders::_1 >,
1248 get_internal_transition_table<
1249 ::boost::mpl::placeholders::_2,
1250 is_composite_state< ::boost::mpl::placeholders::_2> >
1251 >
1252 > >::type type;
1253 };
1254
1255 typedef typename extend_table<library_sm>::type complete_table;
1256
1257 typedef typename get_regions_as_sequence<typename Derived::initial_state>::type seq_initial_states;
1258
1259
1260
1261 void start()
1262 {
1263
1264 ::boost::mpl::for_each< seq_initial_states, ::boost::msm::wrap<mpl::placeholders::_1> >
1265 (init_states(m_states));
1266
1267 (static_cast<Derived*>(this))->on_entry(fsm_initial_event(),*this);
1268 ::boost::mpl::for_each<initial_states, boost::msm::wrap<mpl::placeholders::_1> >
1269 (call_init<fsm_initial_event>(fsm_initial_event(),this));
1270
1271 handle_eventless_transitions_helper<library_sm> eventless_helper(this,true);
1272 eventless_helper.process_completion_event();
1273 }
1274
1275
1276 template <class Event>
1277 void start(Event const& incomingEvent)
1278 {
1279
1280 ::boost::mpl::for_each< seq_initial_states, ::boost::msm::wrap<mpl::placeholders::_1> >
1281 (init_states(m_states));
1282
1283 (static_cast<Derived*>(this))->on_entry(incomingEvent,*this);
1284 ::boost::mpl::for_each<initial_states, boost::msm::wrap<mpl::placeholders::_1> >
1285 (call_init<Event>(incomingEvent,this));
1286
1287 handle_eventless_transitions_helper<library_sm> eventless_helper(this,true);
1288 eventless_helper.process_completion_event();
1289 }
1290
1291
1292 void stop()
1293 {
1294 do_exit(fsm_final_event(),*this);
1295 }
1296
1297
1298 template <class Event>
1299 void stop(Event const& finalEvent)
1300 {
1301 do_exit(finalEvent,*this);
1302 }
1303
1304 UpperFsm* get_upper()
1305 {
1306 return m_upper_fsm;
1307 }
1308
1309
1310 template<class Event>
1311 ::boost::msm::back::execute_return process_event(Event&& evt)
1312 {
1313 return process_event_internal(std::forward<Event>(evt), ::boost::msm::back::EVENT_SOURCE_DIRECT);
1314 }
1315
1316 template <class EventType>
1317 void enqueue_event_helper(EventType const& evt, ::boost::mpl::false_ const &)
1318 {
1319 ::boost::msm::back::execute_return (library_sm::*pf) (EventType&, ::boost::msm::back::EventSource) =
1320 &library_sm::process_event_internal;
1321
1322 m_events_queue.m_events_queue.push_back(
1323 ::boost::bind(
1324 pf, this, evt,
1325 static_cast<::boost::msm::back::EventSource>(::boost::msm::back::EVENT_SOURCE_MSG_QUEUE)));
1326 }
1327 template <class EventType>
1328 void enqueue_event_helper(EventType const& , ::boost::mpl::true_ const &)
1329 {
1330
1331 }
1332
1333 void execute_queued_events_helper(::boost::mpl::false_ const &)
1334 {
1335 while(!m_events_queue.m_events_queue.empty())
1336 {
1337 transition_fct to_call = m_events_queue.m_events_queue.front();
1338 m_events_queue.m_events_queue.pop_front();
1339 to_call();
1340 }
1341 }
1342 void execute_queued_events_helper(::boost::mpl::true_ const &)
1343 {
1344
1345 }
1346 void execute_single_queued_event_helper(::boost::mpl::false_ const &)
1347 {
1348 transition_fct to_call = m_events_queue.m_events_queue.front();
1349 m_events_queue.m_events_queue.pop_front();
1350 to_call();
1351 }
1352 void execute_single_queued_event_helper(::boost::mpl::true_ const &)
1353 {
1354
1355 }
1356
1357
1358
1359
1360 template <class EventType>
1361 void enqueue_event(EventType const& evt)
1362 {
1363 enqueue_event_helper<EventType>(evt, typename is_no_message_queue<library_sm>::type());
1364 }
1365
1366
1367 void execute_queued_events()
1368 {
1369 execute_queued_events_helper(typename is_no_message_queue<library_sm>::type());
1370 }
1371 void execute_single_queued_event()
1372 {
1373 execute_single_queued_event_helper(typename is_no_message_queue<library_sm>::type());
1374 }
1375 typename events_queue_t::size_type get_message_queue_size() const
1376 {
1377 return m_events_queue.m_events_queue.size();
1378 }
1379
1380 events_queue_t& get_message_queue()
1381 {
1382 return m_events_queue.m_events_queue;
1383 }
1384
1385 const events_queue_t& get_message_queue() const
1386 {
1387 return m_events_queue.m_events_queue;
1388 }
1389
1390 void clear_deferred_queue()
1391 {
1392 m_deferred_events_queue.clear();
1393 }
1394
1395 deferred_events_queue_t& get_deferred_queue()
1396 {
1397 return m_deferred_events_queue.m_deferred_events_queue;
1398 }
1399
1400 const deferred_events_queue_t& get_deferred_queue() const
1401 {
1402 return m_deferred_events_queue.m_deferred_events_queue;
1403 }
1404
1405
1406 const int* current_state() const
1407 {
1408 return this->m_states;
1409 }
1410
1411 template <class Archive>
1412 struct serialize_state
1413 {
1414 serialize_state(Archive& ar):ar_(ar){}
1415
1416 template<typename T>
1417 typename ::boost::enable_if<
1418 typename ::boost::mpl::or_<
1419 typename has_do_serialize<T>::type,
1420 typename is_composite_state<T>::type
1421 >::type
1422 ,void
1423 >::type
1424 operator()(T& t) const
1425 {
1426 ar_ & t;
1427 }
1428 template<typename T>
1429 typename ::boost::disable_if<
1430 typename ::boost::mpl::or_<
1431 typename has_do_serialize<T>::type,
1432 typename is_composite_state<T>::type
1433 >::type
1434 ,void
1435 >::type
1436 operator()(T&) const
1437 {
1438
1439 }
1440 Archive& ar_;
1441 };
1442
1443 template<class Archive>
1444 void serialize(Archive & ar, const unsigned int)
1445 {
1446
1447 (serialize_state<Archive>(ar))(boost::serialization::base_object<Derived>(*this));
1448
1449 ar & m_states;
1450
1451 ar & m_history;
1452 ar & m_event_processing;
1453 ar & m_is_included;
1454
1455 ::boost::fusion::for_each(m_substate_list, serialize_state<Archive>(ar));
1456 }
1457
1458
1459 struct get_state_id_helper
1460 {
1461 get_state_id_helper(int id,const BaseState** res,const library_sm* self_):
1462 result_state(res),searched_id(id),self(self_) {}
1463
1464 template <class StateType>
1465 void operator()(boost::msm::wrap<StateType> const&)
1466 {
1467
1468 BOOST_STATIC_CONSTANT(int, id = (get_state_id<stt,StateType>::value));
1469 if (!*result_state && (id == searched_id))
1470 {
1471 *result_state = &::boost::fusion::at_key<StateType>(self->m_substate_list);
1472 }
1473 }
1474 const BaseState** result_state;
1475 int searched_id;
1476 const library_sm* self;
1477 };
1478
1479
1480
1481 BaseState* get_state_by_id(int id)
1482 {
1483 const BaseState* result_state=0;
1484 ::boost::mpl::for_each<state_list,
1485 ::boost::msm::wrap< ::boost::mpl::placeholders::_1> > (get_state_id_helper(id,&result_state,this));
1486 return const_cast<BaseState*>(result_state);
1487 }
1488 const BaseState* get_state_by_id(int id) const
1489 {
1490 const BaseState* result_state=0;
1491 ::boost::mpl::for_each<state_list,
1492 ::boost::msm::wrap< ::boost::mpl::placeholders::_1> > (get_state_id_helper(id,&result_state,this));
1493 return result_state;
1494 }
1495
1496 bool is_contained() const
1497 {
1498 return m_is_included;
1499 }
1500
1501 concrete_history& get_history()
1502 {
1503 return m_history;
1504 }
1505 concrete_history const& get_history() const
1506 {
1507 return m_history;
1508 }
1509
1510
1511 template <class State>
1512 typename ::boost::enable_if<typename ::boost::is_pointer<State>::type,State >::type
1513 get_state(::boost::msm::back::dummy<0> = 0) const
1514 {
1515 return const_cast<State >
1516 (&
1517 (::boost::fusion::at_key<
1518 typename ::boost::remove_const<typename ::boost::remove_pointer<State>::type>::type>(m_substate_list)));
1519 }
1520
1521 template <class State>
1522 typename ::boost::enable_if<typename ::boost::is_reference<State>::type,State >::type
1523 get_state(::boost::msm::back::dummy<1> = 0) const
1524 {
1525 return const_cast<State >
1526 ( ::boost::fusion::at_key<
1527 typename ::boost::remove_const<typename ::boost::remove_reference<State>::type>::type>(m_substate_list) );
1528 }
1529
1530
1531 template <class State>
1532 typename ::boost::enable_if<typename ::boost::is_pointer<State>::type,State >::type
1533 get_state(::boost::msm::back::dummy<0> = 0)
1534 {
1535 return &(static_cast<typename boost::add_reference<typename ::boost::remove_pointer<State>::type>::type >
1536 (::boost::fusion::at_key<typename ::boost::remove_pointer<State>::type>(m_substate_list)));
1537 }
1538
1539 template <class State>
1540 typename ::boost::enable_if<typename ::boost::is_reference<State>::type,State >::type
1541 get_state(::boost::msm::back::dummy<1> = 0)
1542 {
1543 return ::boost::fusion::at_key<typename ::boost::remove_reference<State>::type>(m_substate_list);
1544 }
1545
1546 template <class Flag,class BinaryOp>
1547 bool is_flag_active() const
1548 {
1549 flag_handler* flags_entries = get_entries_for_flag<Flag>();
1550 bool res = (*flags_entries[ m_states[0] ])(*this);
1551 for (int i = 1; i < nr_regions::value ; ++i)
1552 {
1553 res = typename BinaryOp::type() (res,(*flags_entries[ m_states[i] ])(*this));
1554 }
1555 return res;
1556 }
1557
1558 template <class Flag>
1559 bool is_flag_active() const
1560 {
1561 return FlagHelper<Flag,(nr_regions::value>1)>::helper(*this,get_entries_for_flag<Flag>());
1562 }
1563
1564
1565 void visit_current_states()
1566 {
1567 for (int i=0; i<nr_regions::value;++i)
1568 {
1569 m_visitors.execute(m_states[i]);
1570 }
1571 }
1572 #define MSM_VISIT_STATE_SUB(z, n, unused) ARG ## n vis ## n
1573 #define MSM_VISIT_STATE_EXECUTE(z, n, unused) \
1574 template <BOOST_PP_ENUM_PARAMS(n, class ARG)> \
1575 void visit_current_states(BOOST_PP_ENUM(n, MSM_VISIT_STATE_SUB, ~ ) ) \
1576 { \
1577 for (int i=0; i<nr_regions::value;++i) \
1578 { \
1579 m_visitors.execute(m_states[i],BOOST_PP_ENUM_PARAMS(n,vis)); \
1580 } \
1581 }
1582 BOOST_PP_REPEAT_FROM_TO(1,BOOST_PP_ADD(BOOST_MSM_VISITOR_ARG_SIZE,1), MSM_VISIT_STATE_EXECUTE, ~)
1583 #undef MSM_VISIT_STATE_EXECUTE
1584 #undef MSM_VISIT_STATE_SUB
1585
1586
1587 template <class Event>
1588 typename::boost::disable_if< typename ::boost::msm::is_kleene_event<Event>::type,void>::type
1589 defer_event(Event const& e)
1590 {
1591
1592
1593 BOOST_MPL_ASSERT(( has_fsm_deferred_events<library_sm> ));
1594 ::boost::msm::back::execute_return (library_sm::*pf) (Event&, ::boost::msm::back::EventSource) =
1595 &library_sm::process_event_internal;
1596
1597
1598
1599
1600 m_deferred_events_queue.m_deferred_events_queue.push_back(
1601 std::make_pair(
1602 ::boost::bind(
1603 pf, this, e, static_cast<::boost::msm::back::EventSource>(::boost::msm::back::EVENT_SOURCE_DIRECT|::boost::msm::back::EVENT_SOURCE_DEFERRED)),
1604 static_cast<char>(m_deferred_events_queue.m_cur_seq+1)));
1605 }
1606
1607 protected:
1608 template <class KleeneEvent, class Fsm>
1609 struct defer_event_kleene_helper
1610 {
1611 defer_event_kleene_helper(KleeneEvent const& e, Fsm* fsm, bool& found)
1612 : m_event(e), m_fsm(fsm), m_found(found) {}
1613
1614
1615 template <class Event>
1616 void operator()(Event const& ev)
1617 {
1618 if (m_event.type() == boost::typeindex::type_id<decltype(ev)>().type_info())
1619 {
1620 m_found = true;
1621
1622
1623 BOOST_MPL_ASSERT((has_fsm_deferred_events<library_sm>));
1624 ::boost::msm::back::execute_return(library_sm:: * pf) (Event const&, ::boost::msm::back::EventSource) =
1625 &library_sm::process_event_internal;
1626
1627
1628
1629
1630 m_fsm->m_deferred_events_queue.m_deferred_events_queue.push_back(
1631 std::make_pair(
1632 ::boost::bind(
1633 pf, m_fsm, boost::any_cast<Event>(m_event), static_cast<::boost::msm::back::EventSource>(::boost::msm::back::EVENT_SOURCE_DIRECT | ::boost::msm::back::EVENT_SOURCE_DEFERRED)),
1634 static_cast<char>(m_fsm->m_deferred_events_queue.m_cur_seq + 1)));
1635 }
1636 }
1637 KleeneEvent const& m_event;
1638 Fsm* m_fsm;
1639 bool& m_found;
1640 };
1641
1642 public:
1643 template <class Event>
1644 typename::boost::enable_if< typename ::boost::msm::is_kleene_event<Event>::type, void>::type
1645 defer_event(Event const& e)
1646 {
1647 typedef typename generate_event_set<stt>::type event_list;
1648 bool found = false;
1649 boost::fusion::for_each(
1650 event_list(),
1651 defer_event_kleene_helper<Event,library_sm>(e,this,found));
1652 if (!found)
1653 {
1654 for (int i = 0; i < nr_regions::value; ++i)
1655 {
1656 this->no_transition(e, *this, this->m_states[i]);
1657 }
1658 }
1659 }
1660
1661
1662 protected:
1663
1664
1665 struct init_states
1666 {
1667 init_states(int* const init):m_initial_states(init),m_index(-1){}
1668
1669
1670 template <class State>
1671 void operator()(::boost::msm::wrap<State> const&)
1672 {
1673 m_initial_states[++m_index]=get_state_id<stt,State>::type::value;
1674 }
1675 int* const m_initial_states;
1676 int m_index;
1677 };
1678 public:
1679 struct update_state
1680 {
1681 update_state(substate_list& to_overwrite_):to_overwrite(&to_overwrite_){}
1682 template<typename StateType>
1683 void operator()(StateType const& astate) const
1684 {
1685 ::boost::fusion::at_key<StateType>(*to_overwrite)=astate;
1686 }
1687 substate_list* to_overwrite;
1688 };
1689 template <class Expr>
1690 void set_states(Expr const& expr)
1691 {
1692 ::boost::fusion::for_each(
1693 ::boost::fusion::as_vector(boost::msm::back::FoldToList()(expr, boost::fusion::nil_())),update_state(this->m_substate_list));
1694 }
1695
1696
1697 state_machine()
1698 :Derived()
1699 ,m_events_queue()
1700 ,m_deferred_events_queue()
1701 ,m_history()
1702 ,m_event_processing(false)
1703 ,m_is_included(false)
1704 ,m_visitors()
1705 ,m_substate_list()
1706 {
1707
1708 ::boost::mpl::for_each< seq_initial_states, ::boost::msm::wrap<mpl::placeholders::_1> >
1709 (init_states(m_states));
1710 m_history.set_initial_states(m_states);
1711
1712 fill_states(this);
1713 }
1714
1715
1716 #if defined (BOOST_NO_CXX11_RVALUE_REFERENCES) \
1717 || defined (BOOST_NO_CXX11_VARIADIC_TEMPLATES) \
1718 || defined (BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS)
1719 template <class Expr>
1720 state_machine
1721 (Expr const& expr, typename ::boost::enable_if<typename ::boost::proto::is_expr<Expr>::type >::type* = 0)
1722 :Derived()
1723 , m_events_queue()
1724 , m_deferred_events_queue()
1725 , m_history()
1726 , m_event_processing(false)
1727 , m_is_included(false)
1728 , m_visitors()
1729 , m_substate_list()
1730 {
1731 BOOST_MPL_ASSERT_MSG(
1732 (::boost::proto::matches<Expr, boost::msm::back::FoldToList>::value),
1733 THE_STATES_EXPRESSION_PASSED_DOES_NOT_MATCH_GRAMMAR,
1734 (boost::msm::back::FoldToList));
1735
1736
1737 ::boost::mpl::for_each< seq_initial_states, ::boost::msm::wrap<mpl::placeholders::_1> >
1738 (init_states(m_states));
1739 m_history.set_initial_states(m_states);
1740
1741 set_states(expr);
1742 fill_states(this);
1743 }
1744 #define MSM_CONSTRUCTOR_HELPER_EXECUTE_SUB(z, n, unused) ARG ## n t ## n
1745 #define MSM_CONSTRUCTOR_HELPER_EXECUTE(z, n, unused) \
1746 template <BOOST_PP_ENUM_PARAMS(n, class ARG)> \
1747 state_machine<A0,A1,A2,A3,A4 \
1748 >(BOOST_PP_ENUM(n, MSM_CONSTRUCTOR_HELPER_EXECUTE_SUB, ~ ), \
1749 typename ::boost::disable_if<typename ::boost::proto::is_expr<ARG0>::type >::type* =0 ) \
1750 :Derived(BOOST_PP_ENUM_PARAMS(n,t)) \
1751 ,m_events_queue() \
1752 ,m_deferred_events_queue() \
1753 ,m_history() \
1754 ,m_event_processing(false) \
1755 ,m_is_included(false) \
1756 ,m_visitors() \
1757 ,m_substate_list() \
1758 { \
1759 ::boost::mpl::for_each< seq_initial_states, ::boost::msm::wrap<mpl::placeholders::_1> > \
1760 (init_states(m_states)); \
1761 m_history.set_initial_states(m_states); \
1762 fill_states(this); \
1763 } \
1764 template <class Expr,BOOST_PP_ENUM_PARAMS(n, class ARG)> \
1765 state_machine<A0,A1,A2,A3,A4 \
1766 >(Expr const& expr,BOOST_PP_ENUM(n, MSM_CONSTRUCTOR_HELPER_EXECUTE_SUB, ~ ), \
1767 typename ::boost::enable_if<typename ::boost::proto::is_expr<Expr>::type >::type* =0 ) \
1768 :Derived(BOOST_PP_ENUM_PARAMS(n,t)) \
1769 ,m_events_queue() \
1770 ,m_deferred_events_queue() \
1771 ,m_history() \
1772 ,m_event_processing(false) \
1773 ,m_is_included(false) \
1774 ,m_visitors() \
1775 ,m_substate_list() \
1776 { \
1777 BOOST_MPL_ASSERT_MSG( \
1778 ( ::boost::proto::matches<Expr, boost::msm::back::FoldToList>::value), \
1779 THE_STATES_EXPRESSION_PASSED_DOES_NOT_MATCH_GRAMMAR, \
1780 (boost::msm::back::FoldToList)); \
1781 ::boost::mpl::for_each< seq_initial_states, ::boost::msm::wrap<mpl::placeholders::_1> > \
1782 (init_states(m_states)); \
1783 m_history.set_initial_states(m_states); \
1784 set_states(expr); \
1785 fill_states(this); \
1786 }
1787
1788 BOOST_PP_REPEAT_FROM_TO(1,BOOST_PP_ADD(BOOST_MSM_CONSTRUCTOR_ARG_SIZE,1), MSM_CONSTRUCTOR_HELPER_EXECUTE, ~)
1789 #undef MSM_CONSTRUCTOR_HELPER_EXECUTE
1790 #undef MSM_CONSTRUCTOR_HELPER_EXECUTE_SUB
1791
1792 #else
1793 template <class ARG0,class... ARG,class=typename ::boost::disable_if<typename ::boost::proto::is_expr<ARG0>::type >::type>
1794 state_machine(ARG0&& t0,ARG&&... t)
1795 :Derived(std::forward<ARG0>(t0), std::forward<ARG>(t)...)
1796 ,m_events_queue()
1797 ,m_deferred_events_queue()
1798 ,m_history()
1799 ,m_event_processing(false)
1800 ,m_is_included(false)
1801 ,m_visitors()
1802 ,m_substate_list()
1803 {
1804 ::boost::mpl::for_each< seq_initial_states, ::boost::msm::wrap<mpl::placeholders::_1> >
1805 (init_states(m_states));
1806 m_history.set_initial_states(m_states);
1807 fill_states(this);
1808 }
1809 template <class Expr,class... ARG,class=typename ::boost::enable_if<typename ::boost::proto::is_expr<Expr>::type >::type>
1810 state_machine(Expr const& expr,ARG&&... t)
1811 :Derived(std::forward<ARG>(t)...)
1812 ,m_events_queue()
1813 ,m_deferred_events_queue()
1814 ,m_history()
1815 ,m_event_processing(false)
1816 ,m_is_included(false)
1817 ,m_visitors()
1818 ,m_substate_list()
1819 {
1820 BOOST_MPL_ASSERT_MSG(
1821 ( ::boost::proto::matches<Expr, boost::msm::back::FoldToList>::value),
1822 THE_STATES_EXPRESSION_PASSED_DOES_NOT_MATCH_GRAMMAR,
1823 (boost::msm::back::FoldToList));
1824 ::boost::mpl::for_each< seq_initial_states, ::boost::msm::wrap<mpl::placeholders::_1> >
1825 (init_states(m_states));
1826 m_history.set_initial_states(m_states);
1827 set_states(expr);
1828 fill_states(this);
1829 }
1830 #endif
1831
1832
1833
1834 library_sm& operator= (library_sm const& rhs)
1835 {
1836 if (this != &rhs)
1837 {
1838 Derived::operator=(rhs);
1839 do_copy(rhs);
1840 }
1841 return *this;
1842 }
1843 state_machine(library_sm const& rhs)
1844 : Derived(rhs)
1845 {
1846 if (this != &rhs)
1847 {
1848
1849 fill_states(this);
1850 do_copy(rhs);
1851 }
1852 }
1853
1854
1855
1856 template <class Event>
1857 bool is_event_handling_blocked_helper( ::boost::mpl::true_ const &)
1858 {
1859
1860 if (is_flag_active< ::boost::msm::TerminateFlag>())
1861 return true;
1862
1863
1864 if ( is_flag_active< ::boost::msm::InterruptedFlag>() &&
1865 !is_flag_active< ::boost::msm::EndInterruptFlag<Event> >())
1866 return true;
1867 return false;
1868 }
1869
1870 template <class Event>
1871 bool is_event_handling_blocked_helper( ::boost::mpl::false_ const &)
1872 {
1873
1874 return false;
1875 }
1876 void do_handle_prio_msg_queue_deferred_queue(::boost::msm::back::EventSource source, ::boost::msm::back::HandledEnum handled, ::boost::mpl::true_ const &)
1877 {
1878
1879 if (!(::boost::msm::back::EVENT_SOURCE_MSG_QUEUE & source))
1880 {
1881 do_post_msg_queue_helper(
1882 ::boost::mpl::bool_<
1883 is_no_message_queue<library_sm>::type::value>());
1884 if (!(::boost::msm::back::EVENT_SOURCE_DEFERRED & source))
1885 {
1886 handle_defer_helper<library_sm> defer_helper(m_deferred_events_queue);
1887 defer_helper.do_handle_deferred(::boost::msm::back::HANDLED_TRUE & handled);
1888 }
1889 }
1890 }
1891 void do_handle_prio_msg_queue_deferred_queue(::boost::msm::back::EventSource source, ::boost::msm::back::HandledEnum handled, ::boost::mpl::false_ const &)
1892 {
1893
1894 if (!(::boost::msm::back::EVENT_SOURCE_DEFERRED & source))
1895 {
1896 handle_defer_helper<library_sm> defer_helper(m_deferred_events_queue);
1897 defer_helper.do_handle_deferred(::boost::msm::back::HANDLED_TRUE & handled);
1898
1899
1900
1901 if (!(::boost::msm::back::EVENT_SOURCE_MSG_QUEUE & source))
1902 {
1903 do_post_msg_queue_helper(
1904 ::boost::mpl::bool_<
1905 is_no_message_queue<library_sm>::type::value>());
1906 }
1907 }
1908 }
1909
1910 template <class StateType,class EventType>
1911 bool do_pre_msg_queue_helper(EventType const&, ::boost::mpl::true_ const &)
1912 {
1913
1914 return true;
1915 }
1916 template <class StateType,class EventType>
1917 bool do_pre_msg_queue_helper(EventType const& evt, ::boost::mpl::false_ const &)
1918 {
1919 ::boost::msm::back::execute_return (library_sm::*pf) (EventType&, ::boost::msm::back::EventSource) =
1920 &library_sm::process_event_internal;
1921
1922
1923 if (m_event_processing)
1924 {
1925
1926 m_events_queue.m_events_queue.push_back(
1927 ::boost::bind(
1928 pf, this, evt,
1929 static_cast<::boost::msm::back::EventSource>(::boost::msm::back::EVENT_SOURCE_DIRECT | ::boost::msm::back::EVENT_SOURCE_MSG_QUEUE)));
1930
1931 return false;
1932 }
1933
1934
1935 m_event_processing = true;
1936 return true;
1937 }
1938 void do_post_msg_queue_helper( ::boost::mpl::true_ const &)
1939 {
1940
1941 }
1942 void do_post_msg_queue_helper( ::boost::mpl::false_ const &)
1943 {
1944 process_message_queue(this);
1945 }
1946 void do_allow_event_processing_after_transition( ::boost::mpl::true_ const &)
1947 {
1948
1949 }
1950 void do_allow_event_processing_after_transition( ::boost::mpl::false_ const &)
1951 {
1952 m_event_processing = false;
1953 }
1954
1955 template <class StateType,class EventType>
1956 ::boost::msm::back::HandledEnum do_process_helper(EventType&& evt, ::boost::mpl::true_ const &, bool is_direct_call)
1957 {
1958 return this->do_process_event(std::forward<EventType>(evt),is_direct_call);
1959 }
1960 template <class StateType,class EventType>
1961 ::boost::msm::back::HandledEnum do_process_helper(EventType&& evt, ::boost::mpl::false_ const &, bool is_direct_call)
1962 {
1963
1964
1965
1966 std::exception e;
1967 BOOST_TRY
1968 {
1969 return this->do_process_event(std::forward<EventType>(evt),is_direct_call);
1970 }
1971 BOOST_CATCH (std::exception& e)
1972 {
1973
1974
1975 this->exception_caught(evt,*this,e);
1976 return ::boost::msm::back::HANDLED_FALSE;
1977 }
1978 BOOST_CATCH_END
1979 return ::boost::msm::back::HANDLED_TRUE;
1980 }
1981
1982
1983 template <class StateType, class Enable = int>
1984 struct handle_defer_helper
1985 {
1986 handle_defer_helper(deferred_msg_queue_helper<library_sm>& ){}
1987 void do_handle_deferred(bool)
1988 {
1989 }
1990 };
1991
1992 template <class StateType>
1993 struct handle_defer_helper
1994 <StateType, typename enable_if< typename ::boost::msm::back11::has_fsm_deferred_events<StateType>::type,int >::type>
1995 {
1996 handle_defer_helper(deferred_msg_queue_helper<library_sm>& a_queue):
1997 m_events_queue(a_queue) {}
1998 void do_handle_deferred(bool new_seq=false)
1999 {
2000
2001
2002
2003
2004 if (new_seq)
2005 {
2006 ++m_events_queue.m_cur_seq;
2007 }
2008
2009 char& cur_seq = m_events_queue.m_cur_seq;
2010
2011
2012
2013
2014 bool not_only_deferred = false;
2015 while (!m_events_queue.m_deferred_events_queue.empty())
2016 {
2017 typename deferred_events_queue_t::value_type& pair =
2018 m_events_queue.m_deferred_events_queue.front();
2019
2020 if (cur_seq != pair.second)
2021 {
2022 break;
2023 }
2024
2025 deferred_fct next = pair.first;
2026 m_events_queue.m_deferred_events_queue.pop_front();
2027 boost::msm::back::execute_return res = next();
2028 if (res != ::boost::msm::back::HANDLED_FALSE && res != ::boost::msm::back::HANDLED_DEFERRED)
2029 {
2030 not_only_deferred = true;
2031 }
2032 if (not_only_deferred)
2033 {
2034
2035 break;
2036 }
2037 }
2038 if (not_only_deferred)
2039 {
2040
2041
2042
2043 std::stable_sort(
2044 m_events_queue.m_deferred_events_queue.begin(),
2045 m_events_queue.m_deferred_events_queue.end(),
2046 [](typename deferred_events_queue_t::value_type const& d1, typename deferred_events_queue_t::value_type const& d2)
2047 {
2048 return d1.second > d2.second;
2049 }
2050 );
2051
2052 std::for_each(
2053 m_events_queue.m_deferred_events_queue.begin(),
2054 m_events_queue.m_deferred_events_queue.end(),
2055 [seq = m_events_queue.m_cur_seq](typename deferred_events_queue_t::value_type& d)
2056 {
2057 d.second = seq+1;
2058 }
2059 );
2060
2061 do_handle_deferred(true);
2062 }
2063 }
2064
2065 private:
2066 deferred_msg_queue_helper<library_sm>& m_events_queue;
2067 };
2068
2069
2070
2071 template <class StateType, class Enable = void>
2072 struct handle_eventless_transitions_helper
2073 {
2074 handle_eventless_transitions_helper(library_sm* , bool ){}
2075 void process_completion_event(::boost::msm::back::EventSource = ::boost::msm::back::EVENT_SOURCE_DEFAULT){}
2076 };
2077
2078 template <class StateType>
2079 struct handle_eventless_transitions_helper
2080 <StateType, typename enable_if< typename ::boost::msm::back11::has_fsm_eventless_transition<StateType>::type >::type>
2081 {
2082 handle_eventless_transitions_helper(library_sm* self_, bool handled_):self(self_),handled(handled_){}
2083 void process_completion_event(::boost::msm::back::EventSource source = ::boost::msm::back::EVENT_SOURCE_DEFAULT)
2084 {
2085 typedef typename ::boost::mpl::deref<
2086 typename ::boost::mpl::begin<
2087 typename find_completion_events<StateType>::type
2088 >::type
2089 >::type first_completion_event;
2090 if (handled)
2091 {
2092 self->process_event_internal(
2093 first_completion_event(),
2094 source | ::boost::msm::back::EVENT_SOURCE_DIRECT);
2095 }
2096 }
2097
2098 private:
2099 library_sm* self;
2100 bool handled;
2101 };
2102
2103
2104 template<class Event>
2105 struct process_fsm_internal_table
2106 {
2107 typedef typename ::boost::mpl::has_key<processable_events_internal_table,Event>::type is_event_processable;
2108
2109
2110 static void process(Event const& evt,library_sm* self_,::boost::msm::back::HandledEnum& result)
2111 {
2112 do_process(evt,self_,result,is_event_processable());
2113 }
2114 private:
2115
2116 static void do_process(Event const& evt,library_sm* self_,::boost::msm::back::HandledEnum& result, ::boost::mpl::true_)
2117 {
2118 if (result != ::boost::msm::back::HANDLED_TRUE)
2119 {
2120 typedef dispatch_table<library_sm,complete_table,Event,CompilePolicy> table;
2121 ::boost::msm::back::HandledEnum res_internal = table::instance().entries[0](*self_, 0, self_->m_states[0], evt);
2122 result = (::boost::msm::back::HandledEnum)((int)result | (int)res_internal);
2123 }
2124 }
2125
2126 static void do_process(Event const& ,library_sm* ,::boost::msm::back::HandledEnum& , ::boost::mpl::false_)
2127 {
2128
2129 }
2130 };
2131
2132 template <class StateType,class Enable=void>
2133 struct region_processing_helper
2134 {
2135 public:
2136 region_processing_helper(library_sm* self_,::boost::msm::back::HandledEnum& result_)
2137 :self(self_),result(result_){}
2138 template<class Event>
2139 void process(Event& evt)
2140 {
2141
2142 typedef dispatch_table<library_sm,complete_table,Event,CompilePolicy> table;
2143
2144 ::boost::msm::back::HandledEnum res =
2145 table::instance().entries[self->m_states[0]+1](
2146 *self, 0, self->m_states[0], evt);
2147 result = (::boost::msm::back::HandledEnum)((int)result | (int)res);
2148
2149 process_fsm_internal_table<Event>::process(evt,self,result);
2150 }
2151 library_sm* self;
2152 ::boost::msm::back::HandledEnum& result;
2153 };
2154
2155 template <class StateType>
2156 struct region_processing_helper<StateType,typename ::boost::enable_if<
2157 ::boost::mpl::is_sequence<typename StateType::initial_state> >::type>
2158 {
2159 private:
2160
2161 template <class region_id,int Dummy=0>
2162 struct In
2163 {
2164 template<class Event>
2165 static void process(Event& evt,library_sm* self_,::boost::msm::back::HandledEnum& result_)
2166 {
2167
2168 typedef dispatch_table<library_sm,complete_table,Event,CompilePolicy> table;
2169
2170 ::boost::msm::back::HandledEnum res =
2171 table::instance().entries[self_->m_states[region_id::value]+1](
2172 *self_, region_id::value , self_->m_states[region_id::value], evt);
2173 result_ = (::boost::msm::back::HandledEnum)((int)result_ | (int)res);
2174 In< ::boost::mpl::int_<region_id::value+1> >::process(evt,self_,result_);
2175 }
2176 };
2177 template <int Dummy>
2178 struct In< ::boost::mpl::int_<nr_regions::value>,Dummy>
2179 {
2180
2181 template<class Event>
2182 static void process(Event& evt,library_sm* self_,::boost::msm::back::HandledEnum& result_)
2183 {
2184
2185 process_fsm_internal_table<Event>::process(evt,self_,result_);
2186 }
2187 };
2188 public:
2189 region_processing_helper(library_sm* self_,::boost::msm::back::HandledEnum& result_)
2190 :self(self_),result(result_){}
2191 template<class Event>
2192 void process(Event& evt)
2193 {
2194 In< ::boost::mpl::int_<0> >::process(evt,self,result);
2195 }
2196
2197 library_sm* self;
2198 ::boost::msm::back::HandledEnum& result;
2199 };
2200
2201
2202
2203 template<class Event>
2204 ::boost::msm::back::execute_return process_event_internal(Event&& evt,
2205 ::boost::msm::back::EventSource source = ::boost::msm::back::EVENT_SOURCE_DEFAULT)
2206 {
2207
2208 if (is_event_handling_blocked_helper<Event>
2209 ( ::boost::mpl::bool_<has_fsm_blocking_states<library_sm>::type::value>() ) )
2210 {
2211 return ::boost::msm::back::HANDLED_TRUE;
2212 }
2213
2214
2215 if (!do_pre_msg_queue_helper<Event>
2216 (evt,::boost::mpl::bool_<is_no_message_queue<library_sm>::type::value>()))
2217 {
2218
2219 return ::boost::msm::back::HANDLED_TRUE;
2220 }
2221 else
2222 {
2223
2224 ::boost::msm::back::HandledEnum handled = this->do_process_helper<Event>(
2225 std::forward<Event>(evt),
2226 ::boost::mpl::bool_<is_no_exception_thrown<library_sm>::type::value>(),
2227 (::boost::msm::back::EVENT_SOURCE_DIRECT & source));
2228
2229
2230
2231 do_allow_event_processing_after_transition(
2232 ::boost::mpl::bool_<is_no_message_queue<library_sm>::type::value>());
2233
2234
2235
2236 handle_eventless_transitions_helper<library_sm>
2237 eventless_helper(this,(::boost::msm::back::HANDLED_TRUE & handled));
2238 eventless_helper.process_completion_event(source);
2239
2240
2241
2242 do_handle_prio_msg_queue_deferred_queue(
2243 source,handled,
2244 ::boost::mpl::bool_<has_event_queue_before_deferred_queue<library_sm>::type::value>());
2245 return handled;
2246 }
2247 }
2248
2249
2250 template<class Event>
2251 ::boost::msm::back::HandledEnum do_process_event(Event&& evt, bool is_direct_call)
2252 {
2253 ::boost::msm::back::HandledEnum handled = ::boost::msm::back::HANDLED_FALSE;
2254
2255
2256 region_processing_helper<Derived> helper(this,handled);
2257 helper.process(evt);
2258
2259
2260
2261
2262
2263
2264
2265 if ( (!is_contained() || is_direct_call) && !handled && !is_completion_event<Event>::type::value)
2266 {
2267 for (int i=0; i<nr_regions::value;++i)
2268 {
2269 this->no_transition(evt,*this,this->m_states[i]);
2270 }
2271 }
2272 return handled;
2273 }
2274
2275
2276 template <class Event>
2277 bool no_guard(Event const&){return true;}
2278 template <class Event>
2279 void no_action(Event const&){}
2280
2281 #ifndef BOOST_NO_RTTI
2282 ::boost::msm::back::HandledEnum process_any_event( ::boost::any const& evt);
2283 #endif
2284
2285 private:
2286
2287 void composite_accept()
2288 {
2289 this->accept();
2290 this->visit_current_states();
2291 }
2292
2293 #define MSM_COMPOSITE_ACCEPT_SUB(z, n, unused) ARG ## n vis ## n
2294 #define MSM_COMPOSITE_ACCEPT_SUB2(z, n, unused) boost::ref( vis ## n )
2295 #define MSM_COMPOSITE_ACCEPT_EXECUTE(z, n, unused) \
2296 template <BOOST_PP_ENUM_PARAMS(n, class ARG)> \
2297 void composite_accept(BOOST_PP_ENUM(n, MSM_COMPOSITE_ACCEPT_SUB, ~ ) ) \
2298 { \
2299 this->accept(BOOST_PP_ENUM_PARAMS(n,vis)); \
2300 this->visit_current_states(BOOST_PP_ENUM(n,MSM_COMPOSITE_ACCEPT_SUB2, ~)); \
2301 }
2302 BOOST_PP_REPEAT_FROM_TO(1,BOOST_PP_ADD(BOOST_MSM_VISITOR_ARG_SIZE,1), MSM_COMPOSITE_ACCEPT_EXECUTE, ~)
2303 #undef MSM_COMPOSITE_ACCEPT_EXECUTE
2304 #undef MSM_COMPOSITE_ACCEPT_SUB
2305 #undef MSM_COMPOSITE_ACCEPT_SUB2
2306
2307
2308 template <class Event>
2309 struct call_init
2310 {
2311 call_init(Event const& an_event,library_sm* self_):
2312 evt(an_event),self(self_){}
2313 template <class State>
2314 void operator()(boost::msm::wrap<State> const&)
2315 {
2316 execute_entry(::boost::fusion::at_key<State>(self->m_substate_list),evt,*self);
2317 }
2318 private:
2319 Event const& evt;
2320 library_sm* self;
2321 };
2322
2323 template <class Flag,bool orthogonalStates>
2324 struct FlagHelper
2325 {
2326 static bool helper(library_sm const& sm,flag_handler* )
2327 {
2328
2329 return sm.is_flag_active<Flag,Flag_OR>();
2330 }
2331 };
2332 template <class Flag>
2333 struct FlagHelper<Flag,false>
2334 {
2335 static bool helper(library_sm const& sm,flag_handler* flags_entries)
2336 {
2337
2338 return flags_entries[sm.current_state()[0]](sm);
2339 }
2340 };
2341
2342
2343 template <class StateType,class Flag>
2344 struct FlagHandler
2345 {
2346 static bool flag_true(library_sm const& )
2347 {
2348 return true;
2349 }
2350 static bool flag_false(library_sm const& )
2351 {
2352 return false;
2353 }
2354 static bool forward(library_sm const& fsm)
2355 {
2356 return ::boost::fusion::at_key<StateType>(fsm.m_substate_list).template is_flag_active<Flag>();
2357 }
2358 };
2359 template <class Flag>
2360 struct init_flags
2361 {
2362 private:
2363
2364 template <class T>
2365 void helper (flag_handler* an_entry,int offset, ::boost::mpl::true_ const & )
2366 {
2367
2368 an_entry[offset] = &FlagHandler<T,Flag>::forward;
2369 }
2370 template <class T>
2371 void helper (flag_handler* an_entry,int offset, ::boost::mpl::false_ const & )
2372 {
2373
2374 an_entry[offset] = &FlagHandler<T,Flag>::flag_false;
2375 }
2376
2377 flag_handler* entries;
2378
2379 public:
2380 init_flags(flag_handler* entries_)
2381 : entries(entries_)
2382 {}
2383
2384
2385 template <class StateType>
2386 void operator()( ::boost::msm::wrap<StateType> const& )
2387 {
2388 typedef typename get_flag_list<StateType>::type flags;
2389 typedef typename ::boost::mpl::contains<flags,Flag >::type found;
2390
2391 BOOST_STATIC_CONSTANT(int, state_id = (get_state_id<stt,StateType>::type::value));
2392 if (found::type::value)
2393 {
2394
2395 entries[state_id] = &FlagHandler<StateType,Flag>::flag_true;
2396 }
2397 else
2398 {
2399
2400 typedef typename ::boost::mpl::and_<
2401 typename is_composite_state<StateType>::type,
2402 typename ::boost::mpl::not_<
2403 typename has_non_forwarding_flag<Flag>::type>::type >::type composite_no_forward;
2404
2405 helper<StateType>(entries,state_id,::boost::mpl::bool_<composite_no_forward::type::value>());
2406 }
2407 }
2408 };
2409
2410 template <class Flag>
2411 flag_handler* get_entries_for_flag() const
2412 {
2413 BOOST_STATIC_CONSTANT(int, max_state = (mpl::size<state_list>::value));
2414
2415 static flag_handler flags_entries[max_state];
2416
2417 static flag_handler* flags_entries_ptr =
2418 (::boost::mpl::for_each<state_list, boost::msm::wrap< ::boost::mpl::placeholders::_1> >
2419 (init_flags<Flag>(flags_entries)),
2420 flags_entries);
2421 return flags_entries_ptr;
2422 }
2423
2424
2425 template <class State, class Enable=void>
2426 struct create_state_helper
2427 {
2428 static void set_sm(library_sm* )
2429 {
2430
2431 }
2432 };
2433
2434 template <class State>
2435 struct create_state_helper<State,typename boost::enable_if<typename State::needs_sm >::type>
2436 {
2437 static void set_sm(library_sm* sm)
2438 {
2439
2440 ::boost::fusion::at_key<State>(sm->m_substate_list).set_sm_ptr(sm);
2441 }
2442 };
2443
2444 template <class StateType,int ARGS>
2445 struct visitor_args;
2446
2447 #define MSM_VISITOR_ARGS_SUB(z, n, unused) BOOST_PP_CAT(::boost::placeholders::_,BOOST_PP_ADD(n,1))
2448 #define MSM_VISITOR_ARGS_TYPEDEF_SUB(z, n, unused) typename StateType::accept_sig::argument ## n
2449
2450 #define MSM_VISITOR_ARGS_EXECUTE(z, n, unused) \
2451 template <class StateType> \
2452 struct visitor_args<StateType,n> \
2453 { \
2454 template <class State> \
2455 static typename enable_if_c<!is_composite_state<State>::value,void >::type \
2456 helper (library_sm* sm, \
2457 int id,StateType& astate) \
2458 { \
2459 sm->m_visitors.insert(id, boost::bind(&StateType::accept, \
2460 ::boost::ref(astate) BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM(n, MSM_VISITOR_ARGS_SUB, ~) )); \
2461 } \
2462 template <class State> \
2463 static typename enable_if_c<is_composite_state<State>::value,void >::type \
2464 helper (library_sm* sm, \
2465 int id,StateType& astate) \
2466 { \
2467 void (StateType::*caccept)(BOOST_PP_ENUM(n, MSM_VISITOR_ARGS_TYPEDEF_SUB, ~ ) ) \
2468 = &StateType::composite_accept; \
2469 sm->m_visitors.insert(id, boost::bind(caccept, \
2470 ::boost::ref(astate) BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM(n, MSM_VISITOR_ARGS_SUB, ~) )); \
2471 } \
2472 };
2473 BOOST_PP_REPEAT(BOOST_PP_ADD(BOOST_MSM_VISITOR_ARG_SIZE,1), MSM_VISITOR_ARGS_EXECUTE, ~)
2474 #undef MSM_VISITOR_ARGS_EXECUTE
2475 #undef MSM_VISITOR_ARGS_SUB
2476
2477
2478
2479
2480 #if defined (__IBMCPP__) || (__GNUC__ == 4 && __GNUC_MINOR__ < 1) || (defined(_MSC_VER) && (_MSC_VER < 1400))
2481 public:
2482 #endif
2483 template<class ContainingSM>
2484 void set_containing_sm(ContainingSM* sm)
2485 {
2486 m_is_included=true;
2487 ::boost::fusion::for_each(m_substate_list,add_state<ContainingSM>(this,sm));
2488 }
2489 #if defined (__IBMCPP__) || (__GNUC__ == 4 && __GNUC_MINOR__ < 1) || (defined(_MSC_VER) && (_MSC_VER < 1400))
2490 private:
2491 #endif
2492
2493
2494 template<class ContainingSM>
2495 struct add_state
2496 {
2497 add_state(library_sm* self_,ContainingSM* sm)
2498 : self(self_),containing_sm(sm){}
2499
2500
2501 template <class StateType>
2502 typename ::boost::enable_if<
2503 typename is_composite_state<StateType>::type,void >::type
2504 new_state_helper(boost::msm::back::dummy<0> = 0)
2505 {
2506 ::boost::fusion::at_key<StateType>(self->m_substate_list).set_containing_sm(containing_sm);
2507 ::boost::fusion::at_key<StateType>(self->m_substate_list).m_upper_fsm = containing_sm;
2508 }
2509
2510
2511 template <class StateType>
2512 typename ::boost::enable_if<
2513 typename boost::mpl::and_<typename boost::mpl::not_
2514 <typename is_composite_state<StateType>::type>::type,
2515 typename boost::mpl::not_
2516 <typename is_pseudo_exit<StateType>::type>::type
2517 >::type,void>::type
2518 new_state_helper( ::boost::msm::back::dummy<1> = 0) const
2519 {
2520
2521 }
2522
2523 template <class StateType>
2524 typename ::boost::enable_if<typename is_pseudo_exit<StateType>::type,void >::type
2525 new_state_helper( ::boost::msm::back::dummy<2> = 0) const
2526 {
2527 ::boost::msm::back::execute_return (ContainingSM::*pf) (typename StateType::event const& evt)=
2528 &ContainingSM::process_event;
2529 ::boost::function<::boost::msm::back::execute_return (typename StateType::event const&)> fct =
2530 ::boost::bind(pf,containing_sm,::boost::placeholders::_1);
2531 ::boost::fusion::at_key<StateType>(self->m_substate_list).set_forward_fct(fct);
2532 }
2533
2534 template <class State>
2535 void operator()( State const&)
2536 {
2537
2538 BOOST_STATIC_CONSTANT(int, state_id = (get_state_id<stt,State>::value));
2539
2540 this->new_state_helper<State>(),
2541 create_state_helper<State>::set_sm(self);
2542
2543 visitor_helper(state_id,::boost::fusion::at_key<State>(self->m_substate_list),
2544 ::boost::mpl::bool_<has_accept_sig<State>::type::value>());
2545 }
2546 private:
2547
2548 template <class StateType>
2549 void visitor_helper(int id,StateType& astate, ::boost::mpl::true_ const & ) const
2550 {
2551 visitor_args<StateType,StateType::accept_sig::args_number>::
2552 template helper<StateType>(self,id,astate);
2553 }
2554 template <class StateType>
2555 void visitor_helper(int ,StateType& , ::boost::mpl::false_ const &) const
2556 {
2557
2558 }
2559
2560 library_sm* self;
2561 ContainingSM* containing_sm;
2562 };
2563
2564
2565 struct copy_helper
2566 {
2567 copy_helper(library_sm* sm):
2568 m_sm(sm){}
2569 template <class StateType>
2570 void operator()( ::boost::msm::wrap<StateType> const& )
2571 {
2572 BOOST_STATIC_CONSTANT(int, state_id = (get_state_id<stt,StateType>::type::value));
2573
2574 visitor_helper<StateType>(state_id);
2575
2576
2577 create_state_helper<StateType>::set_sm(m_sm);
2578 }
2579 template <class StateType>
2580 typename ::boost::enable_if<typename has_accept_sig<StateType>::type,void >::type
2581 visitor_helper(int id) const
2582 {
2583 visitor_args<StateType,StateType::accept_sig::args_number>::template helper<StateType>
2584 (m_sm,id,::boost::fusion::at_key<StateType>(m_sm->m_substate_list));
2585 }
2586 template <class StateType>
2587 typename ::boost::disable_if<typename has_accept_sig<StateType>::type,void >::type
2588 visitor_helper(int) const
2589 {
2590
2591 }
2592
2593 library_sm* m_sm;
2594 };
2595
2596 template <class region_id,int Dummy=0>
2597 struct region_copy_helper
2598 {
2599 static void do_copy(library_sm* self_,library_sm const& rhs)
2600 {
2601 self_->m_states[region_id::value] = rhs.m_states[region_id::value];
2602 region_copy_helper< ::boost::mpl::int_<region_id::value+1> >::do_copy(self_,rhs);
2603 }
2604 };
2605 template <int Dummy>
2606 struct region_copy_helper< ::boost::mpl::int_<nr_regions::value>,Dummy>
2607 {
2608
2609 static void do_copy(library_sm*,library_sm const& ){}
2610 };
2611
2612 void do_copy (library_sm const& rhs,
2613 ::boost::msm::back::dummy<0> = 0)
2614 {
2615
2616 region_copy_helper< ::boost::mpl::int_<0> >::do_copy(this,rhs);
2617 m_events_queue = rhs.m_events_queue;
2618 m_deferred_events_queue = rhs.m_deferred_events_queue;
2619 m_history = rhs.m_history;
2620 m_event_processing = rhs.m_event_processing;
2621 m_is_included = rhs.m_is_included;
2622 m_substate_list = rhs.m_substate_list;
2623
2624
2625 ::boost::mpl::for_each<state_list, ::boost::msm::wrap< ::boost::mpl::placeholders::_1> >
2626 (copy_helper(this));
2627 }
2628
2629
2630
2631 template<class Event,bool is_entry>
2632 struct entry_exit_helper
2633 {
2634 entry_exit_helper(int id,Event const& e,library_sm* self_):
2635 state_id(id),evt(e),self(self_){}
2636
2637 template <class IsEntry,class State>
2638 typename ::boost::enable_if<typename IsEntry::type,void >::type
2639 helper( ::boost::msm::back::dummy<0> = 0)
2640 {
2641 BOOST_STATIC_CONSTANT(int, id = (get_state_id<stt,State>::value));
2642 if (id == state_id)
2643 {
2644 execute_entry<State>(::boost::fusion::at_key<State>(self->m_substate_list),evt,*self);
2645 }
2646 }
2647
2648 template <class IsEntry,class State>
2649 typename boost::disable_if<typename IsEntry::type,void >::type
2650 helper( ::boost::msm::back::dummy<1> = 0)
2651 {
2652 BOOST_STATIC_CONSTANT(int, id = (get_state_id<stt,State>::value));
2653 if (id == state_id)
2654 {
2655 execute_exit<State>(::boost::fusion::at_key<State>(self->m_substate_list),evt,*self);
2656 }
2657 }
2658
2659 template <class State>
2660 void operator()( ::boost::msm::wrap<State> const&)
2661 {
2662 entry_exit_helper<Event,is_entry>::template helper< ::boost::mpl::bool_<is_entry>,State >();
2663 }
2664 private:
2665 int state_id;
2666 Event const& evt;
2667 library_sm* self;
2668 };
2669
2670
2671 template <class region_id,int Dummy=0>
2672 struct region_start_helper
2673 {
2674 template<class Event>
2675 static void do_start(library_sm* self_,Event const& incomingEvent)
2676 {
2677
2678 ::boost::mpl::for_each<state_list, ::boost::msm::wrap< ::boost::mpl::placeholders::_1> >
2679 (entry_exit_helper<Event,true>(self_->m_states[region_id::value],incomingEvent,self_));
2680 region_start_helper
2681 < ::boost::mpl::int_<region_id::value+1> >::do_start(self_,incomingEvent);
2682 }
2683 };
2684 template <int Dummy>
2685 struct region_start_helper< ::boost::mpl::int_<nr_regions::value>,Dummy>
2686 {
2687
2688 template<class Event>
2689 static void do_start(library_sm*,Event const& ){}
2690 };
2691
2692 template <class Event>
2693 void internal_start(Event const& incomingEvent)
2694 {
2695 region_start_helper< ::boost::mpl::int_<0> >::do_start(this,incomingEvent);
2696
2697 handle_eventless_transitions_helper<library_sm> eventless_helper(this,true);
2698 eventless_helper.process_completion_event();
2699 }
2700
2701 template <class StateType>
2702 struct find_region_id
2703 {
2704 template <int region,int Dummy=0>
2705 struct In
2706 {
2707 enum {region_index=region};
2708 };
2709
2710 template<int Dummy>
2711 struct In<-1,Dummy>
2712 {
2713 typedef typename build_orthogonal_regions<
2714 library_sm,
2715 initial_states
2716 >::type all_regions;
2717 enum {region_index= find_region_index<all_regions,StateType>::value };
2718 };
2719 enum {region_index = In<StateType::zone_index>::region_index };
2720 };
2721
2722 struct direct_event_start_helper
2723 {
2724 direct_event_start_helper(library_sm* self_):self(self_){}
2725
2726 template <class EventType,class FsmType>
2727 typename ::boost::disable_if<typename has_direct_entry<EventType>::type,void>::type
2728 operator()(EventType const& evt,FsmType& fsm, ::boost::msm::back::dummy<0> = 0)
2729 {
2730 (static_cast<Derived*>(self))->on_entry(evt,fsm);
2731 self->internal_start(evt);
2732 }
2733
2734
2735 template <class EventType,class FsmType>
2736 typename ::boost::enable_if<
2737 typename ::boost::mpl::and_<
2738 typename ::boost::mpl::not_< typename is_pseudo_entry<
2739 typename EventType::active_state>::type >::type,
2740 typename ::boost::mpl::and_<typename has_direct_entry<EventType>::type,
2741 typename ::boost::mpl::not_<typename ::boost::mpl::is_sequence
2742 <typename EventType::active_state>::type >::type
2743 >::type>::type,void
2744 >::type
2745 operator()(EventType const& evt,FsmType& fsm, ::boost::msm::back::dummy<1> = 0)
2746 {
2747 (static_cast<Derived*>(self))->on_entry(evt,fsm);
2748 int state_id = get_state_id<stt,typename EventType::active_state::wrapped_entry>::value;
2749 BOOST_STATIC_ASSERT(find_region_id<typename EventType::active_state::wrapped_entry>::region_index >= 0);
2750 BOOST_STATIC_ASSERT(find_region_id<typename EventType::active_state::wrapped_entry>::region_index < nr_regions::value);
2751
2752 self->m_states[find_region_id<typename EventType::active_state::wrapped_entry>::region_index] = state_id;
2753 self->internal_start(evt.m_event);
2754 }
2755
2756
2757 template <class EventType,class FsmType>
2758 typename ::boost::enable_if<
2759 typename ::boost::mpl::and_<
2760 typename ::boost::mpl::not_<
2761 typename is_pseudo_entry<typename EventType::active_state>::type >::type,
2762 typename ::boost::mpl::and_<typename has_direct_entry<EventType>::type,
2763 typename ::boost::mpl::is_sequence<
2764 typename EventType::active_state>::type
2765 >::type>::type,void
2766 >::type
2767 operator()(EventType const& evt,FsmType& fsm, ::boost::msm::back::dummy<2> = 0)
2768 {
2769 (static_cast<Derived*>(self))->on_entry(evt,fsm);
2770 ::boost::mpl::for_each<typename EventType::active_state,
2771 ::boost::msm::wrap< ::boost::mpl::placeholders::_1> >
2772 (fork_helper<EventType>(self,evt));
2773
2774 self->internal_start(evt.m_event);
2775 }
2776
2777
2778 template <class EventType,class FsmType>
2779 typename ::boost::enable_if<
2780 typename is_pseudo_entry<typename EventType::active_state >::type,void
2781 >::type
2782 operator()(EventType const& evt,FsmType& fsm, ::boost::msm::back::dummy<3> = 0)
2783 {
2784
2785 (static_cast<Derived*>(self))->on_entry(evt,fsm);
2786 int state_id = get_state_id<stt,typename EventType::active_state::wrapped_entry>::value;
2787 BOOST_STATIC_ASSERT(find_region_id<typename EventType::active_state::wrapped_entry>::region_index >= 0);
2788 BOOST_STATIC_ASSERT(find_region_id<typename EventType::active_state::wrapped_entry>::region_index < nr_regions::value);
2789
2790 self->m_states[find_region_id<typename EventType::active_state::wrapped_entry>::region_index] = state_id;
2791 self->internal_start(evt.m_event);
2792
2793
2794 self->process_event(evt.m_event);
2795 }
2796 private:
2797
2798 library_sm* self;
2799 template <class EventType>
2800 struct fork_helper
2801 {
2802 fork_helper(library_sm* self_,EventType const& evt_):
2803 helper_self(self_),helper_evt(evt_){}
2804 template <class StateType>
2805 void operator()( ::boost::msm::wrap<StateType> const& )
2806 {
2807 int state_id = get_state_id<stt,typename StateType::wrapped_entry>::value;
2808 BOOST_STATIC_ASSERT(find_region_id<typename StateType::wrapped_entry>::region_index >= 0);
2809 BOOST_STATIC_ASSERT(find_region_id<typename StateType::wrapped_entry>::region_index < nr_regions::value);
2810 helper_self->m_states[find_region_id<typename StateType::wrapped_entry>::region_index] = state_id;
2811 }
2812 private:
2813 library_sm* helper_self;
2814 EventType const& helper_evt;
2815 };
2816 };
2817
2818
2819 template <class region_id,int Dummy=0>
2820 struct region_entry_exit_helper
2821 {
2822 template<class Event>
2823 static void do_entry(library_sm* self_,Event const& incomingEvent)
2824 {
2825 self_->m_states[region_id::value] =
2826 self_->m_history.history_entry(incomingEvent)[region_id::value];
2827 region_entry_exit_helper
2828 < ::boost::mpl::int_<region_id::value+1> >::do_entry(self_,incomingEvent);
2829 }
2830 template<class Event>
2831 static void do_exit(library_sm* self_,Event const& incomingEvent)
2832 {
2833 ::boost::mpl::for_each<state_list, ::boost::msm::wrap< ::boost::mpl::placeholders::_1> >
2834 (entry_exit_helper<Event,false>(self_->m_states[region_id::value],incomingEvent,self_));
2835 region_entry_exit_helper
2836 < ::boost::mpl::int_<region_id::value+1> >::do_exit(self_,incomingEvent);
2837 }
2838 };
2839 template <int Dummy>
2840 struct region_entry_exit_helper< ::boost::mpl::int_<nr_regions::value>,Dummy>
2841 {
2842
2843 template<class Event>
2844 static void do_entry(library_sm*,Event const& ){}
2845 template<class Event>
2846 static void do_exit(library_sm*,Event const& ){}
2847 };
2848
2849 template <class Event,class FsmType>
2850 void do_entry(Event const& incomingEvent,FsmType& fsm)
2851 {
2852
2853 region_entry_exit_helper< ::boost::mpl::int_<0> >::do_entry(this,incomingEvent);
2854
2855 m_event_processing = true;
2856
2857 direct_event_start_helper(this)(incomingEvent,fsm);
2858
2859 m_event_processing = false;
2860
2861 handle_defer_helper<library_sm> defer_helper(m_deferred_events_queue);
2862 defer_helper.do_handle_deferred(true);
2863 process_message_queue(this);
2864 }
2865 template <class Event,class FsmType>
2866 void do_exit(Event const& incomingEvent,FsmType& fsm)
2867 {
2868
2869
2870 region_entry_exit_helper< ::boost::mpl::int_<0> >::do_exit(this,incomingEvent);
2871
2872 (static_cast<Derived*>(this))->on_exit(incomingEvent,fsm);
2873
2874 m_history.history_exit(this->m_states);
2875
2876 if (!m_history.process_deferred_events(incomingEvent))
2877 {
2878 clear_deferred_queue();
2879 }
2880 }
2881
2882
2883 #if defined (__IBMCPP__) || (defined(_MSC_VER) && (_MSC_VER < 1400))
2884 public:
2885 #endif
2886
2887 template <class Event>
2888 static ::boost::msm::back::HandledEnum call_no_transition(library_sm& , int , int , Event& )
2889 {
2890 return ::boost::msm::back::HANDLED_FALSE;
2891 }
2892
2893 template <class Event>
2894 static ::boost::msm::back::HandledEnum call_no_transition_internal(library_sm& , int , int , Event& )
2895 {
2896
2897
2898 return ::boost::msm::back::HANDLED_FALSE;
2899 }
2900
2901 template <class Event>
2902 static ::boost::msm::back::HandledEnum defer_transition(library_sm& fsm, int , int , Event& e)
2903 {
2904 fsm.defer_event(e);
2905 return ::boost::msm::back::HANDLED_DEFERRED;
2906 }
2907
2908
2909 template <class Event>
2910 static ::boost::msm::back::HandledEnum default_eventless_transition(library_sm&, int, int , Event&)
2911 {
2912 return ::boost::msm::back::HANDLED_FALSE;
2913 }
2914 #if defined (__IBMCPP__) || (defined(_MSC_VER) && (_MSC_VER < 1400))
2915 private:
2916 #endif
2917
2918 template <class StateType>
2919 void process_message_queue(StateType*,
2920 typename ::boost::disable_if<typename is_no_message_queue<StateType>::type,void >::type* = 0)
2921 {
2922
2923 while (!m_events_queue.m_events_queue.empty())
2924 {
2925 transition_fct next = m_events_queue.m_events_queue.front();
2926 m_events_queue.m_events_queue.pop_front();
2927 next();
2928 }
2929 }
2930 template <class StateType>
2931 void process_message_queue(StateType*,
2932 typename ::boost::enable_if<typename is_no_message_queue<StateType>::type,void >::type* = 0)
2933 {
2934
2935 }
2936
2937
2938 template <class EventType>
2939 static
2940 typename boost::enable_if<typename has_direct_entry<EventType>::type,typename EventType::contained_event const& >::type
2941 remove_direct_entry_event_wrapper(EventType const& evt,boost::msm::back::dummy<0> = 0)
2942 {
2943 return evt.m_event;
2944 }
2945 template <class EventType>
2946 static typename boost::disable_if<typename has_direct_entry<EventType>::type,EventType const& >::type
2947 remove_direct_entry_event_wrapper(EventType const& evt,boost::msm::back::dummy<1> = 0)
2948 {
2949
2950 return evt;
2951 }
2952
2953
2954
2955 template <class StateType,class EventType,class FsmType>
2956 static
2957 typename boost::enable_if<typename is_composite_state<StateType>::type,void >::type
2958 execute_entry(StateType& astate,EventType const& evt,FsmType& fsm,boost::msm::back::dummy<0> = 0)
2959 {
2960
2961 astate.do_entry(evt,fsm);
2962 }
2963
2964 template <class StateType,class EventType,class FsmType>
2965 static
2966 typename ::boost::disable_if<
2967 typename ::boost::mpl::or_<typename is_composite_state<StateType>::type,
2968 typename is_pseudo_exit<StateType>::type >::type,void >::type
2969 execute_entry(StateType& astate,EventType const& evt,FsmType& fsm, ::boost::msm::back::dummy<1> = 0)
2970 {
2971
2972 astate.on_entry(remove_direct_entry_event_wrapper(evt),fsm);
2973 }
2974
2975 template <class StateType,class EventType,class FsmType>
2976 static
2977 typename ::boost::enable_if<typename is_pseudo_exit<StateType>::type,void >::type
2978 execute_entry(StateType& astate,EventType const& evt,FsmType& fsm, ::boost::msm::back::dummy<2> = 0)
2979 {
2980
2981
2982 astate.on_entry(evt,fsm);
2983 astate.forward_event(evt);
2984 }
2985 template <class StateType,class EventType,class FsmType>
2986 static
2987 typename ::boost::enable_if<typename is_composite_state<StateType>::type,void >::type
2988 execute_exit(StateType& astate,EventType const& evt,FsmType& fsm, ::boost::msm::back::dummy<0> = 0)
2989 {
2990 astate.do_exit(evt,fsm);
2991 }
2992 template <class StateType,class EventType,class FsmType>
2993 static
2994 typename ::boost::disable_if<typename is_composite_state<StateType>::type,void >::type
2995 execute_exit(StateType& astate,EventType const& evt,FsmType& fsm, ::boost::msm::back::dummy<1> = 0)
2996 {
2997
2998 astate.on_exit(evt,fsm);
2999 }
3000
3001
3002 template <class StateType,class TargetType,class EventType,class FsmType>
3003 static
3004 typename ::boost::disable_if<
3005 typename ::boost::mpl::or_<typename has_explicit_entry_state<TargetType>::type,
3006 ::boost::mpl::is_sequence<TargetType> >::type,void>::type
3007 convert_event_and_execute_entry(StateType& astate,EventType const& evt, FsmType& fsm, ::boost::msm::back::dummy<1> = 0)
3008 {
3009
3010 execute_entry<StateType>(astate,evt,fsm);
3011 }
3012 template <class StateType,class TargetType,class EventType,class FsmType>
3013 static
3014 typename ::boost::enable_if<
3015 typename ::boost::mpl::or_<typename has_explicit_entry_state<TargetType>::type,
3016 ::boost::mpl::is_sequence<TargetType> >::type,void >::type
3017 convert_event_and_execute_entry(StateType& astate,EventType const& evt, FsmType& fsm, ::boost::msm::back::dummy<0> = 0)
3018 {
3019
3020 execute_entry(astate,msm::back11::direct_entry_event<TargetType,EventType>(evt),fsm);
3021 }
3022
3023
3024 template <class ContainingSM>
3025 void fill_states(ContainingSM* containing_sm=0)
3026 {
3027
3028 FsmCheckPolicy::template check_orthogonality<library_sm>();
3029
3030 FsmCheckPolicy::template check_unreachable_states<library_sm>();
3031
3032 BOOST_STATIC_CONSTANT(int, max_state = (mpl::size<state_list>::value));
3033
3034 m_visitors.fill_visitors(max_state);
3035 ::boost::fusion::for_each(m_substate_list,add_state<ContainingSM>(this,containing_sm));
3036
3037 }
3038
3039 private:
3040 template <class StateType,class Enable=void>
3041 struct msg_queue_helper
3042 {
3043 public:
3044 msg_queue_helper():m_events_queue(){}
3045 events_queue_t m_events_queue;
3046 };
3047 template <class StateType>
3048 struct msg_queue_helper<StateType,
3049 typename ::boost::enable_if<typename is_no_message_queue<StateType>::type >::type>
3050 {
3051 };
3052
3053 template <class Fsm,class Stt, class Event, class Compile>
3054 friend struct dispatch_table;
3055
3056
3057 int m_states[nr_regions::value];
3058 msg_queue_helper<library_sm> m_events_queue;
3059 deferred_msg_queue_helper
3060 <library_sm> m_deferred_events_queue;
3061 concrete_history m_history;
3062 bool m_event_processing;
3063 bool m_is_included;
3064 visitor_fct_helper<BaseState> m_visitors;
3065 substate_list m_substate_list;
3066 UpperFsm* m_upper_fsm = nullptr;
3067
3068
3069 };
3070
3071 } } }
3072 #endif