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

📄 transitiontest.cpp

📁 Boost provides free peer-reviewed portable C++ source libraries. We emphasize libraries that work
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//////////////////////////////////////////////////////////////////////////////// Copyright 2004-2007 Andreas Huber Doenni// Distributed under the Boost Software License, Version 1.0. (See accompany-// ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)//////////////////////////////////////////////////////////////////////////////#include "OuterOrthogonal.hpp"#include "InnermostDefault.hpp"#include <boost/statechart/state_machine.hpp>#include <boost/statechart/null_exception_translator.hpp>#include <boost/statechart/exception_translator.hpp>#include <boost/statechart/event.hpp>#include <boost/statechart/transition.hpp>#include <boost/statechart/custom_reaction.hpp>#include <boost/mpl/list.hpp>#include <boost/test/test_tools.hpp>#include <typeinfo>#include <string>#include <vector>#include <iostream>#include <algorithm>#include <stdexcept>namespace sc = boost::statechart;namespace mpl = boost::mpl;typedef std::string ActionDescription();typedef ActionDescription * ActionDescriptionPtr;typedef std::vector< ActionDescriptionPtr > ActionDescriptionSequence;typedef ActionDescriptionSequence::const_iterator SequenceIterator;typedef void Action( ActionDescriptionSequence & );typedef Action * ActionPtr;template< class State >std::string EntryDescription(){  static const std::string entry = "Entry: ";  return entry + typeid( State ).name() + "\n";}template< class State >std::string ExitFnDescription(){  static const std::string exitFunction = "exit(): ";  return exitFunction + typeid( State ).name() + "\n";}template< class State >std::string DtorDescription(){  static const std::string destructor = "Destructor: ";  return destructor + typeid( State ).name() + "\n";}template< class Context, class Event >std::string TransDescription(){  static const std::string transition = "Transition: ";  static const std::string event = " with Event: ";  return transition + typeid( Context ).name() +    event + typeid( Event ).name() + "\n";}template< ActionPtr pAction >std::string ThrowDescription(){  static const std::string throwing = "Throwing exception in ";  ActionDescriptionSequence sequence;  pAction( sequence );  return throwing + sequence.front()();}template< class State >void Entry( ActionDescriptionSequence & sequence ){  sequence.push_back( &EntryDescription< State > );}template< class State >void ExitFn( ActionDescriptionSequence & sequence ){  sequence.push_back( &ExitFnDescription< State > );}template< class State >void Dtor( ActionDescriptionSequence & sequence ){  sequence.push_back( &DtorDescription< State > );}template< class State >void Exit( ActionDescriptionSequence & sequence ){  ExitFn< State >( sequence );  Dtor< State >( sequence );}template< class Context, class Event >void Trans( ActionDescriptionSequence & sequence ){  sequence.push_back( &TransDescription< Context, Event > );}template< ActionPtr pAction >void Throw( ActionDescriptionSequence & sequence ){  sequence.push_back( &ThrowDescription< pAction > );}const int arrayLength = 30;typedef ActionPtr ActionArray[ arrayLength ];class TransitionTestException : public std::runtime_error{  public:    TransitionTestException() : std::runtime_error( "Oh la la!" ) {}};// This test state machine is a beefed-up version of the one presented in// "Practical Statecharts in C/C++" by Miro Samek, CMP Books 2002struct A : sc::event< A > {};struct B : sc::event< B > {};struct C : sc::event< C > {};struct D : sc::event< D > {};struct E : sc::event< E > {};struct F : sc::event< F > {};struct G : sc::event< G > {};struct H : sc::event< H > {};template< class M > struct S0;template< class Translator >struct TransitionTest : sc::state_machine<  TransitionTest< Translator >, S0< TransitionTest< Translator > >,  std::allocator< void >, Translator >{  public:    //////////////////////////////////////////////////////////////////////////    TransitionTest() : pThrowAction_( 0 ), unconsumedEventCount_( 0 ) {}    ~TransitionTest()    {      // Since state destructors access the state machine object, we need to      // make sure that all states are destructed before this subtype      // portion is destructed.      this->terminate();    }    void CompareToExpectedActionSequence( ActionArray & actions )    {      expectedSequence_.clear();      // Copy all non-null pointers in actions into expectedSequence_      for ( ActionPtr * pCurrent = &actions[ 0 ];        ( pCurrent != &actions[ arrayLength ] ) && ( *pCurrent != 0 );        ++pCurrent )      {        ( *pCurrent )( expectedSequence_ );      }      if ( ( expectedSequence_.size() != actualSequence_.size() ) ||        !std::equal( expectedSequence_.begin(),          expectedSequence_.end(), actualSequence_.begin() ) )      {        std::string message = "\nExpected action sequence:\n";        for ( SequenceIterator pExpected = expectedSequence_.begin();          pExpected != expectedSequence_.end(); ++pExpected )        {          message += ( *pExpected )();        }        message += "\nActual action sequence:\n";        for ( SequenceIterator pActual = actualSequence_.begin();          pActual != actualSequence_.end(); ++pActual )        {          message += ( *pActual )();        }        BOOST_FAIL( message.c_str() );      }      actualSequence_.clear();    }    void ClearActualSequence()    {      actualSequence_.clear();    }    void ThrowAction( ActionPtr pThrowAction )    {      pThrowAction_ = pThrowAction;    }    template< class State >    void ActualEntry()    {      StoreActualAction< &Entry< State > >();    }    template< class State >    void ActualExitFunction()    {      StoreActualAction< &ExitFn< State > >();    }        template< class State >    void ActualDestructor()    {      StoreActualAction< &Dtor< State > >();    }        template< class Context, class Event >    void ActualTransition()    {      StoreActualAction< &Trans< Context, Event > >();    }    void unconsumed_event( const sc::event_base & )    {      ++unconsumedEventCount_;    }    unsigned int GetUnconsumedEventCount() const    {      return unconsumedEventCount_;    }  private:    //////////////////////////////////////////////////////////////////////////    template< ActionPtr pAction >    void StoreActualAction()    {      if ( pAction == pThrowAction_ )      {        Throw< pAction >( actualSequence_ );        throw TransitionTestException();      }      else      {        pAction( actualSequence_ );      }    }    ActionPtr pThrowAction_;    ActionDescriptionSequence actualSequence_;    ActionDescriptionSequence expectedSequence_;    unsigned int unconsumedEventCount_;};template< class M > struct S1;template< class M > struct S211;template< class M >struct S0 : Orthogonal0< S0< M >, M, S1< M > >{  typedef Orthogonal0< S0< M >, M, S1< M > > my_base;  public:    typedef sc::transition< E, S211< M > > reactions;    S0( typename my_base::my_context ctx ) : my_base( ctx ) {}    void Transit( const A & evt ) { TransitImpl( evt ); }    void Transit( const B & evt ) { TransitImpl( evt ); }    void Transit( const C & evt ) { TransitImpl( evt ); }    void Transit( const D & evt ) { TransitImpl( evt ); }    void Transit( const F & evt ) { TransitImpl( evt ); }    void Transit( const G & evt ) { TransitImpl( evt ); }    void Transit( const H & evt ) { TransitImpl( evt ); }  private:    template< class Event >    void TransitImpl( const Event & )    {      this->outermost_context().template ActualTransition< S0< M >, Event >();    }};  template< class M > struct S11;  template< class M > struct S21;  template< class M >  struct S2 : Orthogonal2< S2< M >, S0< M >, S21< M > >  {    typedef Orthogonal2< S2< M >, S0< M >, S21< M > > my_base;    typedef mpl::list<      sc::transition< C, S1< M >, S0< M >, &S0< M >::Transit >,      sc::transition< F, S11< M >, S0< M >, &S0< M >::Transit >    > reactions;    S2( typename my_base::my_context ctx ) : my_base( ctx ) {}  };    template< class M >    struct S21 : Orthogonal1<      S21< M >, typename S2< M >::template orthogonal< 2 >, S211< M > >    {      typedef Orthogonal1<        S21< M >, typename S2< M >::template orthogonal< 2 >, S211< M >      > my_base;      typedef mpl::list<        sc::transition< H, S21< M >, S0< M >, &S0< M >::Transit >,        sc::transition< B, S211< M >, S0< M >, &S0< M >::Transit >      > reactions;      S21( typename my_base::my_context ctx ) : my_base( ctx ) {}    };      template< class M >      struct S211 : InnermostDefault<        S211< M >, typename S21< M >::template orthogonal< 1 > >      {        typedef InnermostDefault<          S211< M >, typename S21< M >::template orthogonal< 1 > > my_base;        typedef mpl::list<          sc::transition< D, S21< M >, S0< M >, &S0< M >::Transit >,          sc::transition< G, S0< M > >        > reactions;        S211( typename my_base::my_context ctx ) : my_base( ctx ) {}      };  template< class M >  struct S1 : Orthogonal1< S1< M >, S0< M >, S11< M > >  {    typedef Orthogonal1< S1< M >, S0< M >, S11< M > > my_base;    typedef mpl::list<      sc::transition< A, S1< M >, S0< M >, &S0< M >::Transit >,      sc::transition< B, S11< M >, S0< M >, &S0< M >::Transit >,      sc::transition< C, S2< M >, S0< M >, &S0< M >::Transit >,      sc::transition< D, S0< M > >,      sc::transition< F, S211< M >, S0< M >, &S0< M >::Transit >    > reactions;    S1( typename my_base::my_context ctx ) : my_base( ctx ) {}  };    template< class M >    struct S11 : InnermostDefault<      S11< M >, typename S1< M >::template orthogonal< 1 > >    {      typedef InnermostDefault<        S11< M >, typename S1< M >::template orthogonal< 1 > > my_base;      typedef mpl::list<        sc::transition< G, S211< M >, S0< M >, &S0< M >::Transit >,        sc::custom_reaction< H >      > reactions;      S11( typename my_base::my_context ctx ) : my_base( ctx ) {}      sc::result react( const H & )      {        this->outermost_context().template ActualTransition< S11< M >, H >();        return this->discard_event();      }    };struct X1;struct TransitionEventBaseTest :  sc::state_machine< TransitionEventBaseTest, X1 >{  public:    TransitionEventBaseTest() : actionCallCounter_( 0 ) {}    void Transit( const sc::event_base & eventBase )    {      BOOST_REQUIRE(        ( dynamic_cast< const B * >( &eventBase ) != 0 ) ||        ( dynamic_cast< const D * >( &eventBase ) != 0 ) );      ++actionCallCounter_;    }    unsigned int GetActionCallCounter() const    {      return actionCallCounter_;    }  private:    unsigned int actionCallCounter_;};struct X2 : sc::simple_state< X2, TransitionEventBaseTest >{  typedef sc::transition< sc::event_base, X1,    TransitionEventBaseTest, &TransitionEventBaseTest::Transit > reactions;};struct X1 : sc::simple_state< X1, TransitionEventBaseTest >{  typedef sc::transition< sc::event_base, X2 > reactions;};template< class M >void TestTransitions( M & machine ){  machine.initiate();  ActionArray init =   {    Entry< S0< M > >,    Entry< S1< M > >,    Entry< Default0< S1< M > > >,    Entry< S11< M > >,    Entry< Default2< S1< M > > >,    Entry< Default1< S0< M > > >,    Entry< Default2< S0< M > > >  };  machine.CompareToExpectedActionSequence( init );  machine.process_event( A() );  ActionArray a1 =  {

⌨️ 快捷键说明

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