⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 state_machine.hpp

📁 support vector clustering for vc++
💻 HPP
📖 第 1 页 / 共 3 页
字号:
    class initial_construct_function
    {
      public:
        //////////////////////////////////////////////////////////////////////
        initial_construct_function( state_machine & machine ) :
          machine_( machine )
        {
        }

        result operator()()
        {
          machine_.initial_construct();
          return detail::result_utility::make_result(
            detail::do_discard_event ); // there is nothing to be consumed
        }

      private:
        //////////////////////////////////////////////////////////////////////
        state_machine & machine_;
    };
    friend class initial_construct_function;

    class terminate_function
    {
      public:
        //////////////////////////////////////////////////////////////////////
        terminate_function( state_machine & machine ) : machine_( machine ) {}

        result operator()()
        {
          machine_.terminate_impl( true );
          return detail::result_utility::make_result(
            detail::do_discard_event ); // there is nothing to be consumed
        }

      private:
        //////////////////////////////////////////////////////////////////////
        state_machine & machine_;
    };
    friend class terminate_function;

    template< class ExceptionEvent >
    detail::reaction_result handle_exception_event(
      const ExceptionEvent & exceptionEvent,
      state_base_type * pCurrentState )
    {
      if ( terminated() )
      {
        // there is no state that could handle the exception -> bail out
        throw;
      }

      // If we are stable, an event handler has thrown.
      // Otherwise, either a state constructor, a transition action or an exit
      // function has thrown and the state machine is now in an invalid state.
      // This situation can be resolved by the exception event handler
      // function by orderly transiting to another state or terminating.
      // As a result of this, the machine must not be unstable when this
      // function is left.
      state_base_type * const pOutermostUnstableState =
        get_pointer( pOutermostUnstableState_ );
      state_base_type * const pHandlingState = pOutermostUnstableState == 0 ?
        pCurrentState : pOutermostUnstableState;

      BOOST_ASSERT( pHandlingState != 0 );

      // Setting a member variable to a special value for the duration of a
      // call surely looks like a kludge (normally it should be a parameter of
      // the call). However, in this case it is unavoidable because the call
      // below could result in a call to user code where passing through an
      // additional bool parameter is not acceptable.
      performFullExit_ = false;
      const detail::reaction_result reactionResult = pHandlingState->react_impl(
        exceptionEvent, exceptionEvent.dynamic_type() );
      // If the above call throws then performFullExit_ will obviously not be
      // set back to true. In this case the termination triggered by the
      // scope guard further up in the call stack will take care of this.
      performFullExit_ = true;

      if ( ( reactionResult != detail::do_discard_event ) ||
        ( get_pointer( pOutermostUnstableState_ ) != 0 ) )
      {
        throw;
      }

      return detail::do_discard_event;
    }

    class exception_event_handler
    {
      public:
        //////////////////////////////////////////////////////////////////////
        exception_event_handler(
          state_machine & machine,
          state_base_type * pCurrentState = 0
        ) :
          machine_( machine ),
          pCurrentState_( pCurrentState )
        {
        }

        template< class ExceptionEvent >
        result operator()(
          const ExceptionEvent & exceptionEvent )
        {
          return detail::result_utility::make_result(
            machine_.handle_exception_event(
              exceptionEvent, pCurrentState_ ) );
        }

      private:
        //////////////////////////////////////////////////////////////////////
        state_machine & machine_;
        state_base_type * pCurrentState_;
    };
    friend class exception_event_handler;

    class terminator
    {
      public:
        terminator( state_machine & machine ) :
          machine_( machine ), dismissed_( false ) {}
        ~terminator()
        {
          if ( !dismissed_ ) { machine_.terminate_impl( false ); }
        }
        void dismiss() { dismissed_ = true; }

      private:
        state_machine & machine_;
        bool dismissed_;
    };
    friend class terminator;


    void send_event( const event_base_type & evt )
    {
      terminator guard( *this );
      BOOST_ASSERT( get_pointer( pOutermostUnstableState_ ) == 0 );
      const typename rtti_policy_type::id_type eventType = evt.dynamic_type();
      detail::reaction_result reactionResult = detail::do_forward_event;
      
      for (
        typename state_list_type::iterator pState = currentStates_.begin();
        ( reactionResult == detail::do_forward_event ) &&
          ( pState != currentStatesEnd_ );
        ++pState )
      {
        // CAUTION: The following statement could modify our state list!
        // We must not continue iterating if the event was consumed
        reactionResult = detail::result_utility::get_result( translator_(
          detail::send_function<
            state_base_type, event_base_type, rtti_policy_type::id_type >(
              **pState, evt, eventType ),
          exception_event_handler( *this, get_pointer( *pState ) ) ) );
      }

      guard.dismiss();

      if ( reactionResult == detail::do_forward_event )
      {
        polymorphic_downcast< MostDerived * >( this )->unconsumed_event( evt );
      }
    }


    void process_queued_events()
    {
      while ( !eventQueue_.empty() )
      {
        const event_base_ptr_type pCurrentEvent( eventQueue_.front() );
        eventQueue_.pop_front();
        send_event( *pCurrentEvent );
      }
    }


    void terminate_impl( bool performFullExit )
    {
      performFullExit_ = true;

      if ( !terminated() )
      {
        // this also empties deferredMap_
        terminate_impl( *pOutermostState_, performFullExit );
      }

      eventQueue_.clear();
      shallowHistoryMap_.clear();
      deepHistoryMap_.clear();
    }

    void terminate_impl( state_base_type & theState, bool performFullExit )
    {
      isInnermostCommonOuter_ = false;

      // If pOutermostUnstableState_ == 0, we know for sure that
      // currentStates_.size() > 0, otherwise theState couldn't be alive any
      // more
      if ( get_pointer( pOutermostUnstableState_ ) != 0 )
      {
        theState.remove_from_state_list(
          currentStatesEnd_, pOutermostUnstableState_, performFullExit );
      }
      // Optimization: We want to find out whether currentStates_ has size 1
      // and if yes use the optimized implementation below. Since
      // list<>::size() is implemented quite inefficiently in some std libs
      // it is best to just decrement the currentStatesEnd_ here and
      // increment it again, if the test failed.
      else if ( currentStates_.begin() == --currentStatesEnd_ )
      {
        // The machine is stable and there is exactly one innermost state.
        // The following optimization is only correct for a stable machine
        // without orthogonal regions.
        leaf_state_ptr_type & pState = *currentStatesEnd_;
        pState->exit_impl(
          pState, pOutermostUnstableState_, performFullExit );
      }
      else
      {
        BOOST_ASSERT( currentStates_.size() > 1 );
        // The machine is stable and there are multiple innermost states
        theState.remove_from_state_list(
          ++currentStatesEnd_, pOutermostUnstableState_, performFullExit );
      }
    }


    node_state_base_ptr_type add_impl(
      const leaf_state_ptr_type & pState,
      detail::leaf_state< allocator_type, rtti_policy_type > & )
    {
      if ( currentStatesEnd_ == currentStates_.end() )
      {
        pState->set_list_position( 
          currentStates_.insert( currentStatesEnd_, pState ) );
      }
      else
      {
        *currentStatesEnd_ = pState;
        pState->set_list_position( currentStatesEnd_ );
        ++currentStatesEnd_;
      }

      return 0;
    }

    node_state_base_ptr_type add_impl(
      const node_state_base_ptr_type & pState,
      state_base_type & )
    {
      return pState;
    }

    template< class State >
    static bool is_in_highest_orthogonal_region()
    {
      return mpl::equal_to<
        typename State::orthogonal_position,
        mpl::minus< 
          typename State::context_type::no_of_orthogonal_regions,
          mpl::integral_c< detail::orthogonal_position_type, 1 > >
      >::value;
    }


    typedef detail::history_key< rtti_policy_type > history_key_type;

    typedef std::map<
      history_key_type, void (*)(),
      std::less< history_key_type >,
      typename boost::detail::allocator::rebind_to<
        allocator_type, std::pair< const history_key_type, void (*)() >
      >::type
    > history_map_type;

    void store_history_impl(
      history_map_type & historyMap,
      const history_key_type & historyId,
      void (*pConstructFunction)() )
    {
      historyMap[ historyId ] = pConstructFunction;
    }

    template< class DefaultState >
    void construct_with_history_impl(
      history_map_type & historyMap,
      const typename DefaultState::context_ptr_type & pContext )
    {
      typename history_map_type::iterator pFoundSlot = historyMap.find(
        history_key_type::make_history_key< DefaultState >() );
      
      if ( ( pFoundSlot == historyMap.end() ) || ( pFoundSlot->second == 0 ) )
      {
        // We have never entered this state before or history was cleared
        DefaultState::deep_construct(
          pContext, *polymorphic_downcast< MostDerived * >( this ) );
      }
      else
      {
        typedef void construct_function(
          const typename DefaultState::context_ptr_type &,
          typename DefaultState::outermost_context_base_type & );
        // 5.2.10.6 declares that reinterpret_casting a function pointer to a
        // different function pointer and back must yield the same value. The
        // following reinterpret_cast is the second half of such a sequence.
        construct_function * const pConstructFunction =
          reinterpret_cast< construct_function * >( pFoundSlot->second );
        (*pConstructFunction)(
          pContext, *polymorphic_downcast< MostDerived * >( this ) );
      }
    }

    typedef std::list<
      event_base_ptr_type,
      typename boost::detail::allocator::rebind_to<
        allocator_type, event_base_ptr_type >::type
    > event_queue_type;

    typedef std::map<
      const state_base_type *, event_queue_type,
      std::less< const state_base_type * >,
      typename boost::detail::allocator::rebind_to<
        allocator_type,
        std::pair< const state_base_type * const, event_queue_type >
      >::type
    > deferred_map_type;


    event_queue_type eventQueue_;
    deferred_map_type deferredMap_;
    state_list_type currentStates_;
    typename state_list_type::iterator currentStatesEnd_;
    state_base_type * pOutermostState_;
    bool isInnermostCommonOuter_;
    node_state_base_ptr_type pOutermostUnstableState_;
    ExceptionTranslator translator_;
    bool performFullExit_;
    history_map_type shallowHistoryMap_;
    history_map_type deepHistoryMap_;
};



} // namespace statechart
} // namespace boost



#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -