diff options
author | Chanho Park <chanho61.park@samsung.com> | 2014-12-11 18:55:56 +0900 |
---|---|---|
committer | Chanho Park <chanho61.park@samsung.com> | 2014-12-11 18:55:56 +0900 |
commit | 08c1e93fa36a49f49325a07fe91ff92c964c2b6c (patch) | |
tree | 7a7053ceb8874b28ec4b868d4c49b500008a102e /boost/msm | |
parent | bb4dd8289b351fae6b55e303f189127a394a1edd (diff) | |
download | boost-08c1e93fa36a49f49325a07fe91ff92c964c2b6c.tar.gz boost-08c1e93fa36a49f49325a07fe91ff92c964c2b6c.tar.bz2 boost-08c1e93fa36a49f49325a07fe91ff92c964c2b6c.zip |
Imported Upstream version 1.57.0upstream/1.57.0
Diffstat (limited to 'boost/msm')
-rw-r--r-- | boost/msm/back/favor_compile_time.hpp | 3 | ||||
-rw-r--r-- | boost/msm/back/history_policies.hpp | 19 | ||||
-rw-r--r-- | boost/msm/back/metafunctions.hpp | 38 | ||||
-rw-r--r-- | boost/msm/back/state_machine.hpp | 66 | ||||
-rw-r--r-- | boost/msm/front/euml/common.hpp | 50 | ||||
-rw-r--r-- | boost/msm/front/euml/stt_grammar.hpp | 4 | ||||
-rw-r--r-- | boost/msm/front/states.hpp | 8 | ||||
-rwxr-xr-x[-rw-r--r--] | boost/msm/mpl_graph/mpl_graph.hpp | 0 |
8 files changed, 157 insertions, 31 deletions
diff --git a/boost/msm/back/favor_compile_time.hpp b/boost/msm/back/favor_compile_time.hpp index 74f40019bd..c19b5f4be5 100644 --- a/boost/msm/back/favor_compile_time.hpp +++ b/boost/msm/back/favor_compile_time.hpp @@ -38,7 +38,8 @@ struct process_any_event_helper if ( ! finished && ::boost::any_cast<Event>(&any_event)!=0) { finished = true; - res = self->process_event(::boost::any_cast<Event>(any_event)); + res = self->process_event_internal(::boost::any_cast<Event>(any_event),false); + } } private: diff --git a/boost/msm/back/history_policies.hpp b/boost/msm/back/history_policies.hpp index 4dfa021378..4b2af5866a 100644 --- a/boost/msm/back/history_policies.hpp +++ b/boost/msm/back/history_policies.hpp @@ -49,6 +49,12 @@ public: } return *this; } + // this policy deletes all waiting deferred events + template <class Event> + bool process_deferred_events(Event const&)const + { + return false; + } template<class Archive> void serialize(Archive & ar, const unsigned int) { @@ -90,6 +96,13 @@ public: } return *this; } + // the history policy keeps all deferred events until next reentry + template <class Event> + bool process_deferred_events(Event const&)const + { + return true; + } + template<class Archive> void serialize(Archive & ar, const unsigned int) { @@ -139,6 +152,12 @@ public: } return *this; } + // the history policy keeps deferred events until next reentry if coming from our history event + template <class Event> + bool process_deferred_events(Event const&)const + { + return ::boost::mpl::contains<Events,Event>::value; + } template<class Archive> void serialize(Archive & ar, const unsigned int) { diff --git a/boost/msm/back/metafunctions.hpp b/boost/msm/back/metafunctions.hpp index a1ffc35616..ae06b08ff5 100644 --- a/boost/msm/back/metafunctions.hpp +++ b/boost/msm/back/metafunctions.hpp @@ -46,6 +46,8 @@ #include <boost/type_traits/is_same.hpp> #include <boost/utility/enable_if.hpp> +#include <boost/msm/row_tags.hpp> + // mpl_graph graph implementation and depth first search #include <boost/msm/mpl_graph/incidence_list_graph.hpp> #include <boost/msm/mpl_graph/depth_first_search.hpp> @@ -202,7 +204,6 @@ struct get_initial_states States, typename ::boost::mpl::push_back< ::boost::mpl::vector0<>,States>::type >::type type; }; - // returns a mpl::int_ containing the size of a region. If the argument is not a sequence, returns 1 template <class region> struct get_number_of_regions @@ -935,6 +936,41 @@ is_exit_state_active(FSM&) return false; } +// transformation metafunction to end interrupt flags +template <class Event> +struct transform_to_end_interrupt +{ + typedef boost::msm::EndInterruptFlag<Event> type; +}; +// transform a sequence of events into another one of EndInterruptFlag<Event> +template <class Events> +struct apply_end_interrupt_flag +{ + typedef typename + ::boost::mpl::transform< + Events,transform_to_end_interrupt< ::boost::mpl::placeholders::_1> >::type type; +}; +// returns a mpl vector containing all end interrupt events if sequence, otherwise the same event +template <class Event> +struct get_interrupt_events +{ + typedef typename ::boost::mpl::eval_if< + ::boost::mpl::is_sequence<Event>, + boost::msm::back::apply_end_interrupt_flag<Event>, + boost::mpl::vector1<boost::msm::EndInterruptFlag<Event> > >::type type; +}; + +template <class Events> +struct build_interrupt_state_flag_list +{ + typedef ::boost::mpl::vector<boost::msm::InterruptedFlag> first_part; + typedef typename ::boost::mpl::insert_range< + first_part, + typename ::boost::mpl::end< first_part >::type, + Events + >::type type; +}; + } } }//boost::msm::back #endif // BOOST_MSM_BACK_METAFUNCTIONS_H diff --git a/boost/msm/back/state_machine.hpp b/boost/msm/back/state_machine.hpp index b6181cd252..9c0a3e786d 100644 --- a/boost/msm/back/state_machine.hpp +++ b/boost/msm/back/state_machine.hpp @@ -17,6 +17,8 @@ #include <numeric> #include <utility> +#include <boost/detail/no_exceptions_support.hpp> + #include <boost/mpl/contains.hpp> #include <boost/mpl/deref.hpp> #include <boost/mpl/assert.hpp> @@ -264,6 +266,7 @@ private: template <class StateType,class Enable=int> struct deferred_msg_queue_helper { + void clear(){} }; template <class StateType> struct deferred_msg_queue_helper<StateType, @@ -272,6 +275,10 @@ private: { public: deferred_msg_queue_helper():m_deferred_events_queue(){} + void clear() + { + m_deferred_events_queue.clear(); + } deferred_events_queue_t m_deferred_events_queue; }; @@ -337,7 +344,7 @@ private: exit_pt():m_forward(){} // by assignments, we keep our forwarding functor unchanged as our containing SM did not change template <class RHS> - exit_pt(RHS& rhs):m_forward(){} + exit_pt(RHS&):m_forward(){} exit_pt<ExitPoint>& operator= (const exit_pt<ExitPoint>& ) { return *this; @@ -1267,22 +1274,34 @@ private: m_events_queue.m_events_queue.push_back(f); } template <class EventType> - void enqueue_event_helper(EventType const& evt, ::boost::mpl::true_ const &) + void enqueue_event_helper(EventType const& , ::boost::mpl::true_ const &) { // no queue } void execute_queued_events_helper(::boost::mpl::false_ const &) { + while(!m_events_queue.m_events_queue.empty()) + { + transition_fct to_call = m_events_queue.m_events_queue.front(); + m_events_queue.m_events_queue.pop_front(); + to_call(); + } + } + void execute_queued_events_helper(::boost::mpl::true_ const &) + { + // no queue required + } + void execute_single_queued_event_helper(::boost::mpl::false_ const &) + { transition_fct to_call = m_events_queue.m_events_queue.front(); m_events_queue.m_events_queue.pop_front(); to_call(); } - void execute_queued_events_helper(::boost::mpl::true_ const &) + void execute_single_queued_event_helper(::boost::mpl::true_ const &) { // no queue required } - // enqueues an event in the message queue // call execute_queued_events to process all queued events. // Be careful if you do this during event processing, the event will be processed immediately @@ -1298,7 +1317,10 @@ private: { execute_queued_events_helper(typename is_no_message_queue<library_sm>::type()); } - + void execute_single_queued_event() + { + execute_single_queued_event_helper(typename is_no_message_queue<library_sm>::type()); + } typename events_queue_t::size_type get_message_queue_size() const { return m_events_queue.m_events_queue.size(); @@ -1314,6 +1336,11 @@ private: return m_events_queue.m_events_queue; } + void clear_deferred_queue() + { + m_deferred_events_queue.clear(); + } + deferred_events_queue_t& get_deferred_queue() { return m_deferred_events_queue.m_deferred_events_queue; @@ -1355,7 +1382,7 @@ private: >::type ,void >::type - operator()(T& t) const + operator()(T&) const { // no state to serialize } @@ -1652,8 +1679,6 @@ private: if (this != &rhs) { Derived::operator=(rhs); - // initialize our list of states with the ones defined in Derived::initial_state - fill_states(this); do_copy(rhs); } return *this; @@ -1694,7 +1719,7 @@ private: } // the following functions handle pre/post-process handling of a message queue template <class StateType,class EventType> - bool do_pre_msg_queue_helper(EventType const& evt, ::boost::mpl::true_ const &) + bool do_pre_msg_queue_helper(EventType const&, ::boost::mpl::true_ const &) { // no message queue needed return true; @@ -1734,16 +1759,21 @@ private: template <class StateType,class EventType> HandledEnum do_process_helper(EventType const& evt, ::boost::mpl::false_ const &, bool is_direct_call) { - try + // when compiling without exception support there is no formal parameter "e" in the catch handler. + // Declaring a local variable here does not hurt and will be "used" to make the code in the handler + // compilable although the code will never be executed. + std::exception e; + BOOST_TRY { return this->do_process_event(evt,is_direct_call); } - catch (std::exception& e) + BOOST_CATCH (std::exception& e) { // give a chance to the concrete state machine to handle this->exception_caught(evt,*this,e); - } - return HANDLED_FALSE; + } + BOOST_CATCH_END + return HANDLED_TRUE; } // handling of deferred events // if none is found in the SM, take the following empty main version @@ -1971,7 +2001,7 @@ private: ret_handled = handled; } - // process completion transitions BEFORE any other event in the pool (UML Standard 2.3 ยง15.3.14) + // process completion transitions BEFORE any other event in the pool (UML Standard 2.3 15.3.14) handle_eventless_transitions_helper<library_sm> eventless_helper(this,(handled == HANDLED_TRUE)); eventless_helper.process_completion_event(); @@ -2594,6 +2624,9 @@ BOOST_PP_REPEAT(BOOST_PP_ADD(BOOST_MSM_VISITOR_ARG_SIZE,1), MSM_VISITOR_ARGS_EXE direct_event_start_helper(this)(incomingEvent,fsm); // handle messages which were generated and blocked in the init calls m_event_processing = false; + // look for deferred events waiting + handle_defer_helper<library_sm> defer_helper(m_deferred_events_queue); + defer_helper.do_post_handle_deferred(HANDLED_TRUE); process_message_queue(this); } template <class Event,class FsmType> @@ -2606,6 +2639,11 @@ BOOST_PP_REPEAT(BOOST_PP_ADD(BOOST_MSM_VISITOR_ARG_SIZE,1), MSM_VISITOR_ARGS_EXE (static_cast<Derived*>(this))->on_exit(incomingEvent,fsm); // give the history a chance to handle this (or not). m_history.history_exit(this->m_states); + // history decides what happens with deferred events + if (!m_history.process_deferred_events(incomingEvent)) + { + clear_deferred_queue(); + } } // the IBM and VC<8 compilers seem to have problems with the friend declaration of dispatch_table diff --git a/boost/msm/front/euml/common.hpp b/boost/msm/front/euml/common.hpp index f9a9cc46fa..fff03d6dca 100644 --- a/boost/msm/front/euml/common.hpp +++ b/boost/msm/front/euml/common.hpp @@ -951,7 +951,7 @@ struct Fsm_ : euml_action<Fsm_<Index> > } template <class EVT,class FSM,class SourceState,class TargetState> typename transition_action_result<EVT,FSM,SourceState,TargetState>::type - operator()(EVT const& evt ,FSM& fsm,SourceState& ,TargetState&)const + operator()(EVT const& ,FSM& fsm,SourceState& ,TargetState&)const { return fsm.get_attribute(Index()); } @@ -2455,7 +2455,7 @@ Exit_Pt_Helper const exit_pt_ = Exit_Pt_Helper(); #define BOOST_MSM_EUML_ACTION(instance_name) \ struct instance_name ## _impl; \ - struct instance_name ## _helper : msm::front::euml::euml_action<instance_name ## _impl> \ + struct instance_name ## _helper : boost::msm::front::euml::euml_action<instance_name ## _impl> \ { \ instance_name ## _helper(){} \ typedef instance_name ## _impl action_name; \ @@ -2465,7 +2465,7 @@ Exit_Pt_Helper const exit_pt_ = Exit_Pt_Helper(); #define BOOST_MSM_EUML_DECLARE_ACTION(instance_name) \ struct instance_name ; \ - struct instance_name ## _helper : msm::front::euml::euml_action<instance_name > \ + struct instance_name ## _helper : boost::msm::front::euml::euml_action<instance_name > \ { \ instance_name ## _helper(){} \ typedef instance_name action_name; \ @@ -2474,13 +2474,13 @@ Exit_Pt_Helper const exit_pt_ = Exit_Pt_Helper(); #define BOOST_MSM_EUML_EVENT(instance_name) \ - struct instance_name ## _helper : msm::front::euml::euml_event<instance_name ## _helper>{ \ + struct instance_name ## _helper : boost::msm::front::euml::euml_event<instance_name ## _helper>{ \ instance_name ## _helper(){} \ instance_name ## _helper const& operator()() const {return *this;} }; \ static instance_name ## _helper instance_name; // an event matching any event -struct kleene_ : msm::front::euml::euml_event<kleene_>, public boost::any +struct kleene_ : boost::msm::front::euml::euml_event<kleene_>, public boost::any { kleene_() : boost::any(){} template<typename ValueType> @@ -2489,7 +2489,7 @@ struct kleene_ : msm::front::euml::euml_event<kleene_>, public boost::any static kleene_ kleene; #define BOOST_MSM_EUML_DECLARE_EVENT(instance_name) \ - struct instance_name : msm::front::euml::euml_event<instance_name >{ \ + struct instance_name : boost::msm::front::euml::euml_event<instance_name >{ \ instance_name(){} \ instance_name const& operator()() const {return *this;} }; @@ -2527,10 +2527,12 @@ static kleene_ kleene; BOOST_PP_CAT(instance,_helper) operator() \ (BOOST_PP_ENUM(n, MSM_EUML_EVENT_INSTANCE_HELPER_EXECUTE1, ~ ))const{ \ return BOOST_PP_CAT(instance,_helper) (BOOST_PP_ENUM(n, MSM_EUML_EVENT_INSTANCE_HELPER_EXECUTE2, ~ ));} + +#if defined(FUSION_MAX_MAP_SIZE) -#define BOOST_MSM_EUML_EVENT_WITH_ATTRIBUTES(instance_name, attributes_name) \ +#define BOOST_MSM_EUML_EVENT_WITH_ATTRIBUTES(instance_name, attributes_name) \ struct instance_name ## _helper : \ - msm::front::euml::euml_event<instance_name ## _helper> , public attributes_name \ + boost::msm::front::euml::euml_event<instance_name ## _helper> , public attributes_name \ { \ template <class T,int checked_size> struct size_helper \ { \ @@ -2552,16 +2554,44 @@ static kleene_ kleene; }; \ static instance_name ## _helper instance_name; +#else + +#define BOOST_MSM_EUML_EVENT_WITH_ATTRIBUTES(instance_name, attributes_name) \ + struct instance_name ## _helper : \ + boost::msm::front::euml::euml_event<instance_name ## _helper> , public attributes_name \ + { \ + template <class T,int checked_size> struct size_helper \ + { \ + typedef typename ::boost::mpl::less_equal< \ + typename ::boost::fusion::result_of::size<T>::type, \ + ::boost::mpl::int_<checked_size> >::type type; \ + }; \ + BOOST_PP_CAT(instance_name,_helper()) : attributes_name(){} \ + typedef attributes_name::attributes_type attribute_map; \ + typedef ::boost::fusion::result_of::as_vector<attribute_map>::type attribute_vec; \ + BOOST_PP_REPEAT_FROM_TO(1,BOOST_PP_ADD(10 ,1), \ + MSM_EUML_EVENT_HELPER_CONSTRUCTORS, (instance_name,attributes_name)) \ + BOOST_PP_REPEAT_FROM_TO(1,BOOST_PP_ADD(10 ,1), \ + MSM_EUML_EVENT_INSTANCE_HELPER_ATTRIBUTE_MAP, ~) \ + BOOST_PP_CAT(instance_name,_helper) operator()(){ \ + return BOOST_PP_CAT(instance_name,_helper)();} \ + BOOST_PP_REPEAT_FROM_TO(1,BOOST_PP_ADD(10 ,1), \ + MSM_EUML_EVENT_INSTANCE_HELPER_OPERATOR_IMPL, instance_name) \ + }; \ + static instance_name ## _helper instance_name; + +#endif + #define BOOST_MSM_EUML_EVENT_NAME(instance_name) instance_name ## _helper #define BOOST_MSM_EUML_FLAG_NAME(instance_name) instance_name ## _helper #define BOOST_MSM_EUML_FLAG(instance_name) \ - struct instance_name ## _helper : msm::front::euml::euml_flag<instance_name ## _helper>{}; \ + struct instance_name ## _helper : boost::msm::front::euml::euml_flag<instance_name ## _helper>{}; \ static instance_name ## _helper instance_name; #define BOOST_MSM_EUML_DECLARE_FLAG(instance_name) \ - struct instance_name : msm::front::euml::euml_flag<instance_name >{}; + struct instance_name : boost::msm::front::euml::euml_flag<instance_name >{}; #define BOOST_MSM_EUML_STATE_NAME(instance_name) instance_name ## _helper diff --git a/boost/msm/front/euml/stt_grammar.hpp b/boost/msm/front/euml/stt_grammar.hpp index 35252c5546..592364b895 100644 --- a/boost/msm/front/euml/stt_grammar.hpp +++ b/boost/msm/front/euml/stt_grammar.hpp @@ -239,7 +239,7 @@ typename ::boost::mpl::eval_if< typename proto::matches<Expr,BuildStt>::type, boost::result_of<BuildStt(Expr)>, make_invalid_type>::type -build_stt(Expr const& expr) +build_stt(Expr const&) { return typename boost::result_of<BuildStt(Expr)>::type(); } @@ -270,7 +270,7 @@ typename ::boost::mpl::eval_if< typename proto::matches<Expr,BuildInternalStt>::type, boost::result_of<BuildInternalStt(Expr)>, make_invalid_type>::type -build_internal_stt(Expr const& expr) +build_internal_stt(Expr const&) { return typename boost::result_of<BuildInternalStt(Expr)>::type(); } diff --git a/boost/msm/front/states.hpp b/boost/msm/front/states.hpp index a909f63f7b..73f8169da2 100644 --- a/boost/msm/front/states.hpp +++ b/boost/msm/front/states.hpp @@ -15,6 +15,7 @@ #include <boost/mpl/vector.hpp> #include <boost/msm/front/common_states.hpp> #include <boost/msm/row_tags.hpp> +#include <boost/msm/back/metafunctions.hpp> namespace boost { namespace msm { namespace front { @@ -74,9 +75,10 @@ struct interrupt_state : public boost::msm::front::detail::state_base<BASE>, SMP { // tags typedef ::boost::mpl::vector0<> flag_list; - typedef ::boost::mpl::vector<boost::msm::InterruptedFlag, - boost::msm::EndInterruptFlag<EndInterruptEvent> > - internal_flag_list; + typedef typename boost::msm::back::build_interrupt_state_flag_list< + typename boost::msm::back::get_interrupt_events<EndInterruptEvent>::type + >::type internal_flag_list; + //default: no deferred events typedef ::boost::mpl::vector0<> deferred_events; }; diff --git a/boost/msm/mpl_graph/mpl_graph.hpp b/boost/msm/mpl_graph/mpl_graph.hpp index ec2db14c74..ec2db14c74 100644..100755 --- a/boost/msm/mpl_graph/mpl_graph.hpp +++ b/boost/msm/mpl_graph/mpl_graph.hpp |