comparison DEPENDENCIES/generic/include/boost/msm/back/state_machine.hpp @ 101:c530137014c0

Update Boost headers (1.58.0)
author Chris Cannam
date Mon, 07 Sep 2015 11:12:49 +0100
parents 2665513ce2d3
children
comparison
equal deleted inserted replaced
100:793467b5e61c 101:c530137014c0
264 }; 264 };
265 265
266 template <class StateType,class Enable=int> 266 template <class StateType,class Enable=int>
267 struct deferred_msg_queue_helper 267 struct deferred_msg_queue_helper
268 { 268 {
269 void clear(){}
269 }; 270 };
270 template <class StateType> 271 template <class StateType>
271 struct deferred_msg_queue_helper<StateType, 272 struct deferred_msg_queue_helper<StateType,
272 typename ::boost::enable_if< 273 typename ::boost::enable_if<
273 typename ::boost::msm::back::has_fsm_deferred_events<StateType>::type,int >::type> 274 typename ::boost::msm::back::has_fsm_deferred_events<StateType>::type,int >::type>
274 { 275 {
275 public: 276 public:
276 deferred_msg_queue_helper():m_deferred_events_queue(){} 277 deferred_msg_queue_helper():m_deferred_events_queue(){}
278 void clear()
279 {
280 m_deferred_events_queue.clear();
281 }
277 deferred_events_queue_t m_deferred_events_queue; 282 deferred_events_queue_t m_deferred_events_queue;
278 }; 283 };
279 284
280 public: 285 public:
281 // tags 286 // tags
337 m_forward = fct; 342 m_forward = fct;
338 } 343 }
339 exit_pt():m_forward(){} 344 exit_pt():m_forward(){}
340 // by assignments, we keep our forwarding functor unchanged as our containing SM did not change 345 // by assignments, we keep our forwarding functor unchanged as our containing SM did not change
341 template <class RHS> 346 template <class RHS>
342 exit_pt(RHS& rhs):m_forward(){} 347 exit_pt(RHS&):m_forward(){}
343 exit_pt<ExitPoint>& operator= (const exit_pt<ExitPoint>& ) 348 exit_pt<ExitPoint>& operator= (const exit_pt<ExitPoint>& )
344 { 349 {
345 return *this; 350 return *this;
346 } 351 }
347 private: 352 private:
1267 1272
1268 transition_fct f = ::boost::bind(pf,this,evt); 1273 transition_fct f = ::boost::bind(pf,this,evt);
1269 m_events_queue.m_events_queue.push_back(f); 1274 m_events_queue.m_events_queue.push_back(f);
1270 } 1275 }
1271 template <class EventType> 1276 template <class EventType>
1272 void enqueue_event_helper(EventType const& evt, ::boost::mpl::true_ const &) 1277 void enqueue_event_helper(EventType const& , ::boost::mpl::true_ const &)
1273 { 1278 {
1274 // no queue 1279 // no queue
1275 } 1280 }
1276 1281
1277 void execute_queued_events_helper(::boost::mpl::false_ const &) 1282 void execute_queued_events_helper(::boost::mpl::false_ const &)
1283 {
1284 while(!m_events_queue.m_events_queue.empty())
1285 {
1286 transition_fct to_call = m_events_queue.m_events_queue.front();
1287 m_events_queue.m_events_queue.pop_front();
1288 to_call();
1289 }
1290 }
1291 void execute_queued_events_helper(::boost::mpl::true_ const &)
1292 {
1293 // no queue required
1294 }
1295 void execute_single_queued_event_helper(::boost::mpl::false_ const &)
1278 { 1296 {
1279 transition_fct to_call = m_events_queue.m_events_queue.front(); 1297 transition_fct to_call = m_events_queue.m_events_queue.front();
1280 m_events_queue.m_events_queue.pop_front(); 1298 m_events_queue.m_events_queue.pop_front();
1281 to_call(); 1299 to_call();
1282 } 1300 }
1283 void execute_queued_events_helper(::boost::mpl::true_ const &) 1301 void execute_single_queued_event_helper(::boost::mpl::true_ const &)
1284 { 1302 {
1285 // no queue required 1303 // no queue required
1286 } 1304 }
1287
1288 // enqueues an event in the message queue 1305 // enqueues an event in the message queue
1289 // call execute_queued_events to process all queued events. 1306 // call execute_queued_events to process all queued events.
1290 // Be careful if you do this during event processing, the event will be processed immediately 1307 // Be careful if you do this during event processing, the event will be processed immediately
1291 // and not kept in the queue 1308 // and not kept in the queue
1292 template <class EventType> 1309 template <class EventType>
1298 // empty the queue and process events 1315 // empty the queue and process events
1299 void execute_queued_events() 1316 void execute_queued_events()
1300 { 1317 {
1301 execute_queued_events_helper(typename is_no_message_queue<library_sm>::type()); 1318 execute_queued_events_helper(typename is_no_message_queue<library_sm>::type());
1302 } 1319 }
1303 1320 void execute_single_queued_event()
1321 {
1322 execute_single_queued_event_helper(typename is_no_message_queue<library_sm>::type());
1323 }
1304 typename events_queue_t::size_type get_message_queue_size() const 1324 typename events_queue_t::size_type get_message_queue_size() const
1305 { 1325 {
1306 return m_events_queue.m_events_queue.size(); 1326 return m_events_queue.m_events_queue.size();
1307 } 1327 }
1308 1328
1312 } 1332 }
1313 1333
1314 const events_queue_t& get_message_queue() const 1334 const events_queue_t& get_message_queue() const
1315 { 1335 {
1316 return m_events_queue.m_events_queue; 1336 return m_events_queue.m_events_queue;
1337 }
1338
1339 void clear_deferred_queue()
1340 {
1341 m_deferred_events_queue.clear();
1317 } 1342 }
1318 1343
1319 deferred_events_queue_t& get_deferred_queue() 1344 deferred_events_queue_t& get_deferred_queue()
1320 { 1345 {
1321 return m_deferred_events_queue.m_deferred_events_queue; 1346 return m_deferred_events_queue.m_deferred_events_queue;
1355 typename has_do_serialize<T>::type, 1380 typename has_do_serialize<T>::type,
1356 typename is_composite_state<T>::type 1381 typename is_composite_state<T>::type
1357 >::type 1382 >::type
1358 ,void 1383 ,void
1359 >::type 1384 >::type
1360 operator()(T& t) const 1385 operator()(T&) const
1361 { 1386 {
1362 // no state to serialize 1387 // no state to serialize
1363 } 1388 }
1364 Archive& ar_; 1389 Archive& ar_;
1365 }; 1390 };
1692 // no terminate/interrupt states detected 1717 // no terminate/interrupt states detected
1693 return false; 1718 return false;
1694 } 1719 }
1695 // the following functions handle pre/post-process handling of a message queue 1720 // the following functions handle pre/post-process handling of a message queue
1696 template <class StateType,class EventType> 1721 template <class StateType,class EventType>
1697 bool do_pre_msg_queue_helper(EventType const& evt, ::boost::mpl::true_ const &) 1722 bool do_pre_msg_queue_helper(EventType const&, ::boost::mpl::true_ const &)
1698 { 1723 {
1699 // no message queue needed 1724 // no message queue needed
1700 return true; 1725 return true;
1701 } 1726 }
1702 template <class StateType,class EventType> 1727 template <class StateType,class EventType>
1746 { 1771 {
1747 // give a chance to the concrete state machine to handle 1772 // give a chance to the concrete state machine to handle
1748 this->exception_caught(evt,*this,e); 1773 this->exception_caught(evt,*this,e);
1749 } 1774 }
1750 BOOST_CATCH_END 1775 BOOST_CATCH_END
1751 return HANDLED_FALSE; 1776 return HANDLED_TRUE;
1752 } 1777 }
1753 // handling of deferred events 1778 // handling of deferred events
1754 // if none is found in the SM, take the following empty main version 1779 // if none is found in the SM, take the following empty main version
1755 template <class StateType, class Enable = int> 1780 template <class StateType, class Enable = int>
1756 struct handle_defer_helper 1781 struct handle_defer_helper
2597 m_event_processing = true; 2622 m_event_processing = true;
2598 // if the event is generating a direct entry/fork, set the current state(s) to the direct state(s) 2623 // if the event is generating a direct entry/fork, set the current state(s) to the direct state(s)
2599 direct_event_start_helper(this)(incomingEvent,fsm); 2624 direct_event_start_helper(this)(incomingEvent,fsm);
2600 // handle messages which were generated and blocked in the init calls 2625 // handle messages which were generated and blocked in the init calls
2601 m_event_processing = false; 2626 m_event_processing = false;
2627 // look for deferred events waiting
2628 handle_defer_helper<library_sm> defer_helper(m_deferred_events_queue);
2629 defer_helper.do_post_handle_deferred(HANDLED_TRUE);
2602 process_message_queue(this); 2630 process_message_queue(this);
2603 } 2631 }
2604 template <class Event,class FsmType> 2632 template <class Event,class FsmType>
2605 void do_exit(Event const& incomingEvent,FsmType& fsm) 2633 void do_exit(Event const& incomingEvent,FsmType& fsm)
2606 { 2634 {
2609 region_entry_exit_helper< ::boost::mpl::int_<0> >::do_exit(this,incomingEvent); 2637 region_entry_exit_helper< ::boost::mpl::int_<0> >::do_exit(this,incomingEvent);
2610 // then call our own exit 2638 // then call our own exit
2611 (static_cast<Derived*>(this))->on_exit(incomingEvent,fsm); 2639 (static_cast<Derived*>(this))->on_exit(incomingEvent,fsm);
2612 // give the history a chance to handle this (or not). 2640 // give the history a chance to handle this (or not).
2613 m_history.history_exit(this->m_states); 2641 m_history.history_exit(this->m_states);
2642 // history decides what happens with deferred events
2643 if (!m_history.process_deferred_events(incomingEvent))
2644 {
2645 clear_deferred_queue();
2646 }
2614 } 2647 }
2615 2648
2616 // the IBM and VC<8 compilers seem to have problems with the friend declaration of dispatch_table 2649 // the IBM and VC<8 compilers seem to have problems with the friend declaration of dispatch_table
2617 #if defined (__IBMCPP__) || (defined(_MSC_VER) && (_MSC_VER < 1400)) 2650 #if defined (__IBMCPP__) || (defined(_MSC_VER) && (_MSC_VER < 1400))
2618 public: 2651 public: