File indexing completed on 2025-01-18 09:52:32
0001 #ifndef BOOST_STATECHART_STATE_MACHINE_HPP_INCLUDED
0002 #define BOOST_STATECHART_STATE_MACHINE_HPP_INCLUDED
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <boost/statechart/event.hpp>
0012 #include <boost/statechart/null_exception_translator.hpp>
0013 #include <boost/statechart/result.hpp>
0014
0015 #include <boost/statechart/detail/rtti_policy.hpp>
0016 #include <boost/statechart/detail/state_base.hpp>
0017 #include <boost/statechart/detail/leaf_state.hpp>
0018 #include <boost/statechart/detail/node_state.hpp>
0019 #include <boost/statechart/detail/constructor.hpp>
0020 #include <boost/statechart/detail/avoid_unused_warning.hpp>
0021
0022 #include <boost/mpl/list.hpp>
0023 #include <boost/mpl/clear.hpp>
0024 #include <boost/mpl/if.hpp>
0025 #include <boost/mpl/at.hpp>
0026 #include <boost/mpl/integral_c.hpp>
0027 #include <boost/mpl/minus.hpp>
0028 #include <boost/mpl/equal_to.hpp>
0029
0030 #include <boost/intrusive_ptr.hpp>
0031 #include <boost/type_traits/is_pointer.hpp>
0032 #include <boost/type_traits/remove_reference.hpp>
0033 #include <boost/noncopyable.hpp>
0034 #include <boost/assert.hpp>
0035 #include <boost/static_assert.hpp>
0036 #include <boost/polymorphic_cast.hpp> // boost::polymorphic_downcast
0037
0038 #include <boost/config.hpp>
0039
0040 #include <boost/detail/allocator_utilities.hpp>
0041
0042 #ifdef BOOST_MSVC
0043 # pragma warning( push )
0044 # pragma warning( disable: 4702 )
0045 #endif
0046
0047 #include <map>
0048
0049 #ifdef BOOST_MSVC
0050 # pragma warning( pop )
0051 #endif
0052
0053 #include <memory> // std::allocator
0054 #include <typeinfo> // std::bad_cast
0055 #include <functional> // std::less
0056 #include <iterator>
0057
0058
0059
0060 namespace boost
0061 {
0062 namespace statechart
0063 {
0064 namespace detail
0065 {
0066
0067
0068
0069
0070 template< class StateBaseType, class EventBaseType, class IdType >
0071 class send_function
0072 {
0073 public:
0074
0075 send_function(
0076 StateBaseType & toState,
0077 const EventBaseType & evt,
0078 IdType eventType
0079 ) :
0080 toState_( toState ), evt_( evt ), eventType_( eventType )
0081 {
0082 }
0083
0084 result operator()()
0085 {
0086 return detail::result_utility::make_result(
0087 toState_.react_impl( evt_, eventType_ ) );
0088 }
0089
0090 private:
0091
0092
0093 send_function & operator=( const send_function & );
0094
0095 StateBaseType & toState_;
0096 const EventBaseType & evt_;
0097 IdType eventType_;
0098 };
0099
0100
0101
0102 struct state_cast_impl_pointer_target
0103 {
0104 public:
0105
0106 template< class StateBaseType >
0107 static const StateBaseType * deref_if_necessary(
0108 const StateBaseType * pState )
0109 {
0110 return pState;
0111 }
0112
0113 template< class Target, class IdType >
0114 static IdType type_id()
0115 {
0116 Target p = 0;
0117 return type_id_impl< IdType >( p );
0118 }
0119
0120 static bool found( const void * pFound )
0121 {
0122 return pFound != 0;
0123 }
0124
0125 template< class Target >
0126 static Target not_found()
0127 {
0128 return 0;
0129 }
0130
0131 private:
0132
0133 template< class IdType, class Type >
0134 static IdType type_id_impl( const Type * )
0135 {
0136 return Type::static_type();
0137 }
0138 };
0139
0140 struct state_cast_impl_reference_target
0141 {
0142 template< class StateBaseType >
0143 static const StateBaseType & deref_if_necessary(
0144 const StateBaseType * pState )
0145 {
0146 return *pState;
0147 }
0148
0149 template< class Target, class IdType >
0150 static IdType type_id()
0151 {
0152 return remove_reference< Target >::type::static_type();
0153 }
0154
0155 template< class Dummy >
0156 static bool found( const Dummy & )
0157 {
0158 return true;
0159 }
0160
0161 template< class Target >
0162 static Target not_found()
0163 {
0164 throw std::bad_cast();
0165 }
0166 };
0167
0168 template< class Target >
0169 struct state_cast_impl : public mpl::if_<
0170 is_pointer< Target >,
0171 state_cast_impl_pointer_target,
0172 state_cast_impl_reference_target
0173 >::type {};
0174
0175
0176
0177 template< class RttiPolicy >
0178 class history_key
0179 {
0180 public:
0181
0182 template< class HistorizedState >
0183 static history_key make_history_key()
0184 {
0185 return history_key(
0186 HistorizedState::context_type::static_type(),
0187 HistorizedState::orthogonal_position::value );
0188 }
0189
0190 typename RttiPolicy::id_type history_context_type() const
0191 {
0192 return historyContextType_;
0193 }
0194
0195 friend bool operator<(
0196 const history_key & left, const history_key & right )
0197 {
0198 return
0199 std::less< typename RttiPolicy::id_type >()(
0200 left.historyContextType_, right.historyContextType_ ) ||
0201 ( ( left.historyContextType_ == right.historyContextType_ ) &&
0202 ( left.historizedOrthogonalRegion_ <
0203 right.historizedOrthogonalRegion_ ) );
0204 }
0205
0206 private:
0207
0208 history_key(
0209 typename RttiPolicy::id_type historyContextType,
0210 orthogonal_position_type historizedOrthogonalRegion
0211 ) :
0212 historyContextType_( historyContextType ),
0213 historizedOrthogonalRegion_( historizedOrthogonalRegion )
0214 {
0215 }
0216
0217
0218 history_key & operator=( const history_key & );
0219
0220 const typename RttiPolicy::id_type historyContextType_;
0221 const orthogonal_position_type historizedOrthogonalRegion_;
0222 };
0223
0224
0225
0226 }
0227
0228
0229
0230
0231 template< class MostDerived,
0232 class InitialState,
0233 class Allocator = std::allocator< none >,
0234 class ExceptionTranslator = null_exception_translator >
0235 class state_machine : noncopyable
0236 {
0237 public:
0238
0239 typedef Allocator allocator_type;
0240 typedef detail::rtti_policy rtti_policy_type;
0241 typedef event_base event_base_type;
0242 typedef intrusive_ptr< const event_base_type > event_base_ptr_type;
0243
0244 void initiate()
0245 {
0246 terminate();
0247
0248 {
0249 terminator guard( *this, 0 );
0250 detail::result_utility::get_result( translator_(
0251 initial_construct_function( *this ),
0252 exception_event_handler( *this ) ) );
0253 guard.dismiss();
0254 }
0255
0256 process_queued_events();
0257 }
0258
0259 void terminate()
0260 {
0261 terminator guard( *this, 0 );
0262 detail::result_utility::get_result( translator_(
0263 terminate_function( *this ),
0264 exception_event_handler( *this ) ) );
0265 guard.dismiss();
0266 }
0267
0268 bool terminated() const
0269 {
0270 return pOutermostState_ == 0;
0271 }
0272
0273 void process_event( const event_base_type & evt )
0274 {
0275 if ( send_event( evt ) == detail::do_defer_event )
0276 {
0277 deferredEventQueue_.push_back( evt.intrusive_from_this() );
0278 }
0279
0280 process_queued_events();
0281 }
0282
0283 template< class Target >
0284 Target state_cast() const
0285 {
0286 typedef detail::state_cast_impl< Target > impl;
0287
0288 for ( typename state_list_type::const_iterator pCurrentLeafState =
0289 currentStates_.begin();
0290 pCurrentLeafState != currentStatesEnd_;
0291 ++pCurrentLeafState )
0292 {
0293 const state_base_type * pCurrentState(
0294 get_pointer( *pCurrentLeafState ) );
0295
0296 while ( pCurrentState != 0 )
0297 {
0298
0299
0300 #ifndef BOOST_NO_EXCEPTIONS
0301 try
0302 #endif
0303 {
0304 Target result = dynamic_cast< Target >(
0305 impl::deref_if_necessary( pCurrentState ) );
0306
0307 if ( impl::found( result ) )
0308 {
0309 return result;
0310 }
0311 }
0312 #ifndef BOOST_NO_EXCEPTIONS
0313
0314
0315 catch ( const std::bad_cast & ) {}
0316 #endif
0317
0318 pCurrentState = pCurrentState->outer_state_ptr();
0319 }
0320 }
0321
0322 return impl::template not_found< Target >();
0323 }
0324
0325 template< class Target >
0326 Target state_downcast() const
0327 {
0328 typedef detail::state_cast_impl< Target > impl;
0329
0330 typename rtti_policy_type::id_type targetType =
0331 impl::template type_id< Target, rtti_policy_type::id_type >();
0332
0333 for ( typename state_list_type::const_iterator pCurrentLeafState =
0334 currentStates_.begin();
0335 pCurrentLeafState != currentStatesEnd_;
0336 ++pCurrentLeafState )
0337 {
0338 const state_base_type * pCurrentState(
0339 get_pointer( *pCurrentLeafState ) );
0340
0341 while ( pCurrentState != 0 )
0342 {
0343 if ( pCurrentState->dynamic_type() == targetType )
0344 {
0345 return static_cast< Target >(
0346 impl::deref_if_necessary( pCurrentState ) );
0347 }
0348
0349 pCurrentState = pCurrentState->outer_state_ptr();
0350 }
0351 }
0352
0353 return impl::template not_found< Target >();
0354 }
0355
0356 typedef detail::state_base< allocator_type, rtti_policy_type >
0357 state_base_type;
0358
0359 class state_iterator : public std::iterator<
0360 std::forward_iterator_tag,
0361 state_base_type, std::ptrdiff_t
0362 #ifndef BOOST_MSVC_STD_ITERATOR
0363 , const state_base_type *, const state_base_type &
0364 #endif
0365 >
0366 {
0367 public:
0368
0369 explicit state_iterator(
0370 typename state_base_type::state_list_type::const_iterator
0371 baseIterator
0372 ) : baseIterator_( baseIterator ) {}
0373
0374 const state_base_type & operator*() const { return **baseIterator_; }
0375 const state_base_type * operator->() const
0376 {
0377 return &**baseIterator_;
0378 }
0379
0380 state_iterator & operator++() { ++baseIterator_; return *this; }
0381 state_iterator operator++( int )
0382 {
0383 return state_iterator( baseIterator_++ );
0384 }
0385
0386 bool operator==( const state_iterator & right ) const
0387 {
0388 return baseIterator_ == right.baseIterator_;
0389 }
0390 bool operator!=( const state_iterator & right ) const
0391 {
0392 return !( *this == right );
0393 }
0394
0395 private:
0396 typename state_base_type::state_list_type::const_iterator
0397 baseIterator_;
0398 };
0399
0400 state_iterator state_begin() const
0401 {
0402 return state_iterator( currentStates_.begin() );
0403 }
0404
0405 state_iterator state_end() const
0406 {
0407 return state_iterator( currentStatesEnd_ );
0408 }
0409
0410 void unconsumed_event( const event_base & ) {}
0411
0412 protected:
0413
0414 state_machine() :
0415 currentStatesEnd_( currentStates_.end() ),
0416 pOutermostState_( 0 ),
0417 isInnermostCommonOuter_( false ),
0418 performFullExit_( true ),
0419 pTriggeringEvent_( 0 )
0420 {
0421 }
0422
0423
0424
0425 virtual ~state_machine()
0426 {
0427 terminate_impl( false );
0428 }
0429
0430 void post_event( const event_base_ptr_type & pEvent )
0431 {
0432 post_event_impl( pEvent );
0433 }
0434
0435 void post_event( const event_base & evt )
0436 {
0437 post_event_impl( evt );
0438 }
0439
0440 public:
0441
0442
0443
0444
0445 template<
0446 class HistoryContext,
0447 detail::orthogonal_position_type orthogonalPosition >
0448 void clear_shallow_history()
0449 {
0450
0451
0452
0453
0454
0455
0456 BOOST_STATIC_ASSERT( HistoryContext::shallow_history::value );
0457
0458 typedef typename mpl::at_c<
0459 typename HistoryContext::inner_initial_list,
0460 orthogonalPosition >::type historized_state;
0461
0462 store_history_impl(
0463 shallowHistoryMap_,
0464 history_key_type::make_history_key< historized_state >(),
0465 0 );
0466 }
0467
0468 template<
0469 class HistoryContext,
0470 detail::orthogonal_position_type orthogonalPosition >
0471 void clear_deep_history()
0472 {
0473
0474
0475
0476
0477
0478
0479 BOOST_STATIC_ASSERT( HistoryContext::deep_history::value );
0480
0481 typedef typename mpl::at_c<
0482 typename HistoryContext::inner_initial_list,
0483 orthogonalPosition >::type historized_state;
0484
0485 store_history_impl(
0486 deepHistoryMap_,
0487 history_key_type::make_history_key< historized_state >(),
0488 0 );
0489 }
0490
0491 const event_base_type * triggering_event() const
0492 {
0493 return pTriggeringEvent_;
0494 }
0495
0496 public:
0497
0498
0499
0500
0501 typedef MostDerived inner_context_type;
0502 typedef mpl::integral_c< detail::orthogonal_position_type, 0 >
0503 inner_orthogonal_position;
0504 typedef mpl::integral_c< detail::orthogonal_position_type, 1 >
0505 no_of_orthogonal_regions;
0506
0507 typedef MostDerived outermost_context_type;
0508 typedef state_machine outermost_context_base_type;
0509 typedef state_machine * inner_context_ptr_type;
0510 typedef typename state_base_type::node_state_base_ptr_type
0511 node_state_base_ptr_type;
0512 typedef typename state_base_type::leaf_state_ptr_type leaf_state_ptr_type;
0513 typedef typename state_base_type::state_list_type state_list_type;
0514
0515 typedef mpl::clear< mpl::list<> >::type context_type_list;
0516
0517 typedef mpl::bool_< false > shallow_history;
0518 typedef mpl::bool_< false > deep_history;
0519 typedef mpl::bool_< false > inherited_deep_history;
0520
0521 void post_event_impl( const event_base_ptr_type & pEvent )
0522 {
0523 BOOST_ASSERT( get_pointer( pEvent ) != 0 );
0524 eventQueue_.push_back( pEvent );
0525 }
0526
0527 void post_event_impl( const event_base & evt )
0528 {
0529 post_event_impl( evt.intrusive_from_this() );
0530 }
0531
0532 detail::reaction_result react_impl(
0533 const event_base_type &,
0534 typename rtti_policy_type::id_type )
0535 {
0536 return detail::do_forward_event;
0537 }
0538
0539 void exit_impl(
0540 inner_context_ptr_type &,
0541 typename state_base_type::node_state_base_ptr_type &,
0542 bool ) {}
0543
0544 void set_outermost_unstable_state(
0545 typename state_base_type::node_state_base_ptr_type &
0546 pOutermostUnstableState )
0547 {
0548 pOutermostUnstableState = 0;
0549 }
0550
0551
0552
0553
0554 template< class Context >
0555 Context & context()
0556 {
0557
0558
0559 return *polymorphic_downcast< MostDerived * >( this );
0560 }
0561
0562 template< class Context >
0563 const Context & context() const
0564 {
0565
0566
0567 return *polymorphic_downcast< const MostDerived * >( this );
0568 }
0569
0570 outermost_context_type & outermost_context()
0571 {
0572 return *polymorphic_downcast< MostDerived * >( this );
0573 }
0574
0575 const outermost_context_type & outermost_context() const
0576 {
0577 return *polymorphic_downcast< const MostDerived * >( this );
0578 }
0579
0580 outermost_context_base_type & outermost_context_base()
0581 {
0582 return *this;
0583 }
0584
0585 const outermost_context_base_type & outermost_context_base() const
0586 {
0587 return *this;
0588 }
0589
0590 void terminate_as_reaction( state_base_type & theState )
0591 {
0592 terminate_impl( theState, performFullExit_ );
0593 pOutermostUnstableState_ = 0;
0594 }
0595
0596 void terminate_as_part_of_transit( state_base_type & theState )
0597 {
0598 terminate_impl( theState, performFullExit_ );
0599 isInnermostCommonOuter_ = true;
0600 }
0601
0602 void terminate_as_part_of_transit( state_machine & )
0603 {
0604 terminate_impl( *pOutermostState_, performFullExit_ );
0605 isInnermostCommonOuter_ = true;
0606 }
0607
0608
0609 template< class State >
0610 void add( const intrusive_ptr< State > & pState )
0611 {
0612
0613
0614 node_state_base_ptr_type pNewOutermostUnstableStateCandidate =
0615 add_impl( pState, *pState );
0616
0617 if ( isInnermostCommonOuter_ ||
0618 ( is_in_highest_orthogonal_region< State >() &&
0619 ( get_pointer( pOutermostUnstableState_ ) ==
0620 pState->State::outer_state_ptr() ) ) )
0621 {
0622 isInnermostCommonOuter_ = false;
0623 pOutermostUnstableState_ = pNewOutermostUnstableStateCandidate;
0624 }
0625 }
0626
0627
0628 void add_inner_state(
0629 detail::orthogonal_position_type position,
0630 state_base_type * pOutermostState )
0631 {
0632 BOOST_ASSERT( position == 0 );
0633 detail::avoid_unused_warning( position );
0634 pOutermostState_ = pOutermostState;
0635 }
0636
0637 void remove_inner_state( detail::orthogonal_position_type position )
0638 {
0639 BOOST_ASSERT( position == 0 );
0640 detail::avoid_unused_warning( position );
0641 pOutermostState_ = 0;
0642 }
0643
0644
0645 void release_events()
0646 {
0647 eventQueue_.splice( eventQueue_.begin(), deferredEventQueue_ );
0648 }
0649
0650
0651 template< class HistorizedState >
0652 void store_shallow_history()
0653 {
0654
0655
0656
0657 store_history_impl(
0658 shallowHistoryMap_,
0659 history_key_type::make_history_key< HistorizedState >(),
0660 reinterpret_cast< void (*)() >( &HistorizedState::deep_construct ) );
0661 }
0662
0663 template< class DefaultState >
0664 void construct_with_shallow_history(
0665 const typename DefaultState::context_ptr_type & pContext )
0666 {
0667 construct_with_history_impl< DefaultState >(
0668 shallowHistoryMap_, pContext );
0669 }
0670
0671
0672 template< class HistorizedState, class LeafState >
0673 void store_deep_history()
0674 {
0675 typedef typename detail::make_context_list<
0676 typename HistorizedState::context_type,
0677 LeafState >::type history_context_list;
0678 typedef detail::constructor<
0679 history_context_list, outermost_context_base_type > constructor_type;
0680
0681
0682
0683 store_history_impl(
0684 deepHistoryMap_,
0685 history_key_type::make_history_key< HistorizedState >(),
0686 reinterpret_cast< void (*)() >( &constructor_type::construct ) );
0687 }
0688
0689 template< class DefaultState >
0690 void construct_with_deep_history(
0691 const typename DefaultState::context_ptr_type & pContext )
0692 {
0693 construct_with_history_impl< DefaultState >(
0694 deepHistoryMap_, pContext );
0695 }
0696
0697 private:
0698
0699 void initial_construct()
0700 {
0701 InitialState::initial_deep_construct(
0702 *polymorphic_downcast< MostDerived * >( this ) );
0703 }
0704
0705 class initial_construct_function
0706 {
0707 public:
0708
0709 initial_construct_function( state_machine & machine ) :
0710 machine_( machine )
0711 {
0712 }
0713
0714 result operator()()
0715 {
0716 machine_.initial_construct();
0717 return detail::result_utility::make_result(
0718 detail::do_discard_event );
0719 }
0720
0721 private:
0722
0723
0724 initial_construct_function & operator=(
0725 const initial_construct_function & );
0726
0727 state_machine & machine_;
0728 };
0729 friend class initial_construct_function;
0730
0731 class terminate_function
0732 {
0733 public:
0734
0735 terminate_function( state_machine & machine ) : machine_( machine ) {}
0736
0737 result operator()()
0738 {
0739 machine_.terminate_impl( true );
0740 return detail::result_utility::make_result(
0741 detail::do_discard_event );
0742 }
0743
0744 private:
0745
0746
0747 terminate_function & operator=( const terminate_function & );
0748
0749 state_machine & machine_;
0750 };
0751 friend class terminate_function;
0752
0753 template< class ExceptionEvent >
0754 detail::reaction_result handle_exception_event(
0755 const ExceptionEvent & exceptionEvent,
0756 state_base_type * pCurrentState )
0757 {
0758 if ( terminated() )
0759 {
0760
0761 throw;
0762 }
0763
0764
0765
0766
0767
0768
0769
0770
0771 state_base_type * const pOutermostUnstableState =
0772 get_pointer( pOutermostUnstableState_ );
0773 state_base_type * const pHandlingState = pOutermostUnstableState == 0 ?
0774 pCurrentState : pOutermostUnstableState;
0775
0776 BOOST_ASSERT( pHandlingState != 0 );
0777 terminator guard( *this, &exceptionEvent );
0778
0779
0780 guard.dismiss();
0781
0782
0783
0784
0785
0786
0787 performFullExit_ = false;
0788 const detail::reaction_result reactionResult = pHandlingState->react_impl(
0789 exceptionEvent, exceptionEvent.dynamic_type() );
0790
0791
0792
0793 performFullExit_ = true;
0794
0795 if ( ( reactionResult != detail::do_discard_event ) ||
0796 ( get_pointer( pOutermostUnstableState_ ) != 0 ) )
0797 {
0798 throw;
0799 }
0800
0801 return detail::do_discard_event;
0802 }
0803
0804 class exception_event_handler
0805 {
0806 public:
0807
0808 exception_event_handler(
0809 state_machine & machine,
0810 state_base_type * pCurrentState = 0
0811 ) :
0812 machine_( machine ),
0813 pCurrentState_( pCurrentState )
0814 {
0815 }
0816
0817 template< class ExceptionEvent >
0818 result operator()(
0819 const ExceptionEvent & exceptionEvent )
0820 {
0821 return detail::result_utility::make_result(
0822 machine_.handle_exception_event(
0823 exceptionEvent, pCurrentState_ ) );
0824 }
0825
0826 private:
0827
0828
0829 exception_event_handler & operator=(
0830 const exception_event_handler & );
0831
0832 state_machine & machine_;
0833 state_base_type * pCurrentState_;
0834 };
0835 friend class exception_event_handler;
0836
0837 class terminator
0838 {
0839 public:
0840
0841 terminator(
0842 state_machine & machine, const event_base * pNewTriggeringEvent ) :
0843 machine_( machine ),
0844 pOldTriggeringEvent_(machine_.pTriggeringEvent_),
0845 dismissed_( false )
0846 {
0847 machine_.pTriggeringEvent_ = pNewTriggeringEvent;
0848 }
0849
0850 ~terminator()
0851 {
0852 if ( !dismissed_ ) { machine_.terminate_impl( false ); }
0853 machine_.pTriggeringEvent_ = pOldTriggeringEvent_;
0854 }
0855
0856 void dismiss() { dismissed_ = true; }
0857
0858 private:
0859
0860
0861 terminator & operator=( const terminator & );
0862
0863 state_machine & machine_;
0864 const event_base_type * const pOldTriggeringEvent_;
0865 bool dismissed_;
0866 };
0867 friend class terminator;
0868
0869
0870 detail::reaction_result send_event( const event_base_type & evt )
0871 {
0872 terminator guard( *this, &evt );
0873 BOOST_ASSERT( get_pointer( pOutermostUnstableState_ ) == 0 );
0874 const typename rtti_policy_type::id_type eventType = evt.dynamic_type();
0875 detail::reaction_result reactionResult = detail::do_forward_event;
0876
0877 for (
0878 typename state_list_type::iterator pState = currentStates_.begin();
0879 ( reactionResult == detail::do_forward_event ) &&
0880 ( pState != currentStatesEnd_ );
0881 ++pState )
0882 {
0883
0884
0885 reactionResult = detail::result_utility::get_result( translator_(
0886 detail::send_function<
0887 state_base_type, event_base_type, rtti_policy_type::id_type >(
0888 **pState, evt, eventType ),
0889 exception_event_handler( *this, get_pointer( *pState ) ) ) );
0890 }
0891
0892 guard.dismiss();
0893
0894 if ( reactionResult == detail::do_forward_event )
0895 {
0896 polymorphic_downcast< MostDerived * >( this )->unconsumed_event( evt );
0897 }
0898
0899 return reactionResult;
0900 }
0901
0902
0903 void process_queued_events()
0904 {
0905 while ( !eventQueue_.empty() )
0906 {
0907 event_base_ptr_type pEvent = eventQueue_.front();
0908 eventQueue_.pop_front();
0909
0910 if ( send_event( *pEvent ) == detail::do_defer_event )
0911 {
0912 deferredEventQueue_.push_back( pEvent );
0913 }
0914 }
0915 }
0916
0917
0918 void terminate_impl( bool performFullExit )
0919 {
0920 performFullExit_ = true;
0921
0922 if ( !terminated() )
0923 {
0924 terminate_impl( *pOutermostState_, performFullExit );
0925 }
0926
0927 eventQueue_.clear();
0928 deferredEventQueue_.clear();
0929 shallowHistoryMap_.clear();
0930 deepHistoryMap_.clear();
0931 }
0932
0933 void terminate_impl( state_base_type & theState, bool performFullExit )
0934 {
0935 isInnermostCommonOuter_ = false;
0936
0937
0938
0939
0940 if ( get_pointer( pOutermostUnstableState_ ) != 0 )
0941 {
0942 theState.remove_from_state_list(
0943 currentStatesEnd_, pOutermostUnstableState_, performFullExit );
0944 }
0945
0946
0947
0948
0949
0950 else if ( currentStates_.begin() == --currentStatesEnd_ )
0951 {
0952
0953
0954
0955 leaf_state_ptr_type & pState = *currentStatesEnd_;
0956 pState->exit_impl(
0957 pState, pOutermostUnstableState_, performFullExit );
0958 }
0959 else
0960 {
0961 BOOST_ASSERT( currentStates_.size() > 1 );
0962
0963 theState.remove_from_state_list(
0964 ++currentStatesEnd_, pOutermostUnstableState_, performFullExit );
0965 }
0966 }
0967
0968
0969 node_state_base_ptr_type add_impl(
0970 const leaf_state_ptr_type & pState,
0971 detail::leaf_state< allocator_type, rtti_policy_type > & )
0972 {
0973 if ( currentStatesEnd_ == currentStates_.end() )
0974 {
0975 pState->set_list_position(
0976 currentStates_.insert( currentStatesEnd_, pState ) );
0977 }
0978 else
0979 {
0980 *currentStatesEnd_ = pState;
0981 pState->set_list_position( currentStatesEnd_ );
0982 ++currentStatesEnd_;
0983 }
0984
0985 return 0;
0986 }
0987
0988 node_state_base_ptr_type add_impl(
0989 const node_state_base_ptr_type & pState,
0990 state_base_type & )
0991 {
0992 return pState;
0993 }
0994
0995 template< class State >
0996 static bool is_in_highest_orthogonal_region()
0997 {
0998 return mpl::equal_to<
0999 typename State::orthogonal_position,
1000 mpl::minus<
1001 typename State::context_type::no_of_orthogonal_regions,
1002 mpl::integral_c< detail::orthogonal_position_type, 1 > >
1003 >::value;
1004 }
1005
1006
1007 typedef detail::history_key< rtti_policy_type > history_key_type;
1008
1009 typedef std::map<
1010 history_key_type, void (*)(),
1011 std::less< history_key_type >,
1012 typename boost::detail::allocator::rebind_to<
1013 allocator_type, std::pair< const history_key_type, void (*)() >
1014 >::type
1015 > history_map_type;
1016
1017 void store_history_impl(
1018 history_map_type & historyMap,
1019 const history_key_type & historyId,
1020 void (*pConstructFunction)() )
1021 {
1022 historyMap[ historyId ] = pConstructFunction;
1023 }
1024
1025 template< class DefaultState >
1026 void construct_with_history_impl(
1027 history_map_type & historyMap,
1028 const typename DefaultState::context_ptr_type & pContext )
1029 {
1030 typename history_map_type::iterator pFoundSlot = historyMap.find(
1031 history_key_type::make_history_key< DefaultState >() );
1032
1033 if ( ( pFoundSlot == historyMap.end() ) || ( pFoundSlot->second == 0 ) )
1034 {
1035
1036 DefaultState::deep_construct(
1037 pContext, *polymorphic_downcast< MostDerived * >( this ) );
1038 }
1039 else
1040 {
1041 typedef void construct_function(
1042 const typename DefaultState::context_ptr_type &,
1043 typename DefaultState::outermost_context_base_type & );
1044
1045
1046
1047 construct_function * const pConstructFunction =
1048 reinterpret_cast< construct_function * >( pFoundSlot->second );
1049 (*pConstructFunction)(
1050 pContext, *polymorphic_downcast< MostDerived * >( this ) );
1051 }
1052 }
1053
1054 typedef std::list<
1055 event_base_ptr_type,
1056 typename boost::detail::allocator::rebind_to<
1057 allocator_type, event_base_ptr_type >::type
1058 > event_queue_type;
1059
1060 typedef std::map<
1061 const state_base_type *, event_queue_type,
1062 std::less< const state_base_type * >,
1063 typename boost::detail::allocator::rebind_to<
1064 allocator_type,
1065 std::pair< const state_base_type * const, event_queue_type >
1066 >::type
1067 > deferred_map_type;
1068
1069
1070 event_queue_type eventQueue_;
1071 event_queue_type deferredEventQueue_;
1072 state_list_type currentStates_;
1073 typename state_list_type::iterator currentStatesEnd_;
1074 state_base_type * pOutermostState_;
1075 bool isInnermostCommonOuter_;
1076 node_state_base_ptr_type pOutermostUnstableState_;
1077 ExceptionTranslator translator_;
1078 bool performFullExit_;
1079 history_map_type shallowHistoryMap_;
1080 history_map_type deepHistoryMap_;
1081 const event_base_type * pTriggeringEvent_;
1082 };
1083
1084
1085
1086 }
1087 }
1088
1089
1090
1091 #endif