• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //////////////////////////////////////////////////////////////////////////////
2 // Copyright 2005-2006 Andreas Huber Doenni
3 // Distributed under the Boost Software License, Version 1.0. (See accompany-
4 // ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5 //////////////////////////////////////////////////////////////////////////////
6 
7 
8 
9 #include <boost/statechart/state_machine.hpp>
10 #include <boost/statechart/event.hpp>
11 #include <boost/statechart/simple_state.hpp>
12 #include <boost/statechart/transition.hpp>
13 
14 #include <boost/mpl/list.hpp>
15 
16 #include <boost/test/test_tools.hpp>
17 
18 #include <set>
19 #include <map>
20 #include <string>
21 
22 
23 
24 namespace sc = boost::statechart;
25 namespace mpl = boost::mpl;
26 
27 
28 
29 struct EvToA : sc::event< EvToA > {};
30 struct EvToB : sc::event< EvToB > {};
31 struct EvToD : sc::event< EvToD > {};
32 struct EvToE : sc::event< EvToE > {};
33 
34 struct A;
35 struct StateIterationTest : sc::state_machine< StateIterationTest, A >
36 {
37   public:
38     //////////////////////////////////////////////////////////////////////////
39     StateIterationTest();
40 
AssertInStateStateIterationTest41     void AssertInState( const std::string & stateNames ) const
42     {
43       stateNamesCache_.clear();
44 
45       for ( state_iterator currentState = state_begin();
46         currentState != state_end(); ++currentState )
47       {
48         const StateNamesMap::const_iterator found =
49           stateNamesMap_.find( currentState->dynamic_type() );
50         BOOST_REQUIRE( found != stateNamesMap_.end() );
51         stateNamesCache_.insert( found->second );
52       }
53 
54       std::string::const_iterator expectedName = stateNames.begin();
55 
56       BOOST_REQUIRE( stateNames.size() == stateNamesCache_.size() );
57 
58       for ( StateNamesCache::const_iterator actualName =
59         stateNamesCache_.begin();
60         actualName != stateNamesCache_.end(); ++actualName, ++expectedName )
61       {
62         BOOST_REQUIRE( ( *actualName )[ 0 ] == *expectedName );
63       }
64     }
65 
66   private:
67     //////////////////////////////////////////////////////////////////////////
68     typedef std::map< state_base_type::id_type, std::string > StateNamesMap;
69     typedef std::set< std::string > StateNamesCache;
70 
71     StateNamesMap stateNamesMap_;
72     mutable StateNamesCache stateNamesCache_;
73 };
74 
75 struct C;
76 struct D;
77 struct B : sc::simple_state< B, StateIterationTest, mpl::list< C, D > >
78 {
79   typedef sc::transition< EvToA, A > reactions;
80 };
81 
82 struct A : sc::simple_state< A, StateIterationTest >
83 {
84   typedef sc::transition< EvToB, B > reactions;
85 };
86 
87   struct F;
88   struct G;
89   struct E : sc::simple_state< E, B::orthogonal< 1 >, mpl::list< F, G > >
90   {
91     typedef sc::transition< EvToD, D > reactions;
92   };
93 
94     struct F : sc::simple_state< F, E::orthogonal< 0 > > {};
95     struct G : sc::simple_state< G, E::orthogonal< 1 > > {};
96 
97   struct C : sc::simple_state< C, B::orthogonal< 0 > > {};
98   struct D : sc::simple_state< D, B::orthogonal< 1 > >
99   {
100     typedef sc::transition< EvToE, E > reactions;
101   };
102 
StateIterationTest()103 StateIterationTest::StateIterationTest()
104 {
105   // We're not using custom type information to make this test work even when
106   // BOOST_STATECHART_USE_NATIVE_RTTI is defined
107   stateNamesMap_[ A::static_type() ] = "A";
108   stateNamesMap_[ B::static_type() ] = "B";
109   stateNamesMap_[ C::static_type() ] = "C";
110   stateNamesMap_[ D::static_type() ] = "D";
111   stateNamesMap_[ E::static_type() ] = "E";
112   stateNamesMap_[ F::static_type() ] = "F";
113   stateNamesMap_[ G::static_type() ] = "G";
114 }
115 
116 
test_main(int,char * [])117 int test_main( int, char* [] )
118 {
119   StateIterationTest machine;
120   machine.AssertInState( "" );
121 
122   machine.initiate();
123   machine.AssertInState( "A" );
124 
125   machine.process_event( EvToB() );
126   machine.AssertInState( "CD" );
127 
128   machine.process_event( EvToA() );
129   machine.AssertInState( "A" );
130 
131   machine.process_event( EvToB() );
132   machine.AssertInState( "CD" );
133 
134   machine.process_event( EvToE() );
135   machine.AssertInState( "CFG" );
136 
137   machine.process_event( EvToD() );
138   machine.AssertInState( "CD" );
139 
140   machine.process_event( EvToE() );
141   machine.AssertInState( "CFG" );
142 
143   machine.process_event( EvToA() );
144   machine.AssertInState( "A" );
145 
146   machine.terminate();
147   machine.AssertInState( "" );
148 
149   return 0;
150 }
151