• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //////////////////////////////////////////////////////////////////////////////
2 // Copyright 2002-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 //////////////////////////////////////////////////////////////////////////////
10 // The following example program demonstrates the use of orthogonal states and
11 // state_downcast to query the state of orthogonal regions.
12 // Moreover, the use of the state type information interface is also shown.
13 //////////////////////////////////////////////////////////////////////////////
14 // #define BOOST_STATECHART_USE_NATIVE_RTTI
15 
16 
17 #include <boost/statechart/event.hpp>
18 #include <boost/statechart/state_machine.hpp>
19 #include <boost/statechart/simple_state.hpp>
20 #include <boost/statechart/transition.hpp>
21 #include <boost/statechart/custom_reaction.hpp>
22 
23 #include <boost/mpl/list.hpp>
24 #include <boost/config.hpp>
25 
26 #include <iostream>
27 #include <iomanip>
28 
29 #ifdef BOOST_INTEL
30 #  pragma warning( disable: 304 ) // access control not specified
31 #  pragma warning( disable: 981 ) // operands are evaluated in unspecified order
32 #endif
33 
34 
35 
36 namespace sc = boost::statechart;
37 namespace mpl = boost::mpl;
38 
39 
40 
41 //////////////////////////////////////////////////////////////////////////////
42 struct EvNumLockPressed : sc::event< EvNumLockPressed > {};
43 struct EvCapsLockPressed : sc::event< EvCapsLockPressed > {};
44 struct EvScrollLockPressed : sc::event< EvScrollLockPressed > {};
45 struct EvRequestShutdown : sc::event< EvRequestShutdown > {};
46 
47 struct Active;
48 struct Keyboard : sc::state_machine< Keyboard, Active > {};
49 
50 struct NumLockOff;
51 struct CapsLockOff;
52 struct ScrollLockOff;
53 struct Active: sc::simple_state<
54   Active, Keyboard, mpl::list< NumLockOff, CapsLockOff, ScrollLockOff > >
55 {
56   typedef sc::custom_reaction< EvRequestShutdown > reactions;
57 
58   sc::result react( const EvRequestShutdown & );
59 };
60 
61   struct NumLockOn : sc::simple_state< NumLockOn, Active::orthogonal< 0 > >
62   {
63     typedef sc::transition< EvNumLockPressed, NumLockOff > reactions;
64   };
65 
66   struct NumLockOff : sc::simple_state< NumLockOff, Active::orthogonal< 0 > >
67   {
68     typedef sc::transition< EvNumLockPressed, NumLockOn > reactions;
69   };
70 
71   struct CapsLockOn : sc::simple_state< CapsLockOn, Active::orthogonal< 1 > >
72   {
73     typedef sc::transition< EvCapsLockPressed, CapsLockOff > reactions;
74   };
75 
76   struct CapsLockOff : sc::simple_state< CapsLockOff, Active::orthogonal< 1 > >
77   {
78     typedef sc::transition< EvCapsLockPressed, CapsLockOn > reactions;
79   };
80 
81   struct ScrollLockOn : sc::simple_state< ScrollLockOn, Active::orthogonal< 2 > >
82   {
83     typedef sc::transition< EvScrollLockPressed, ScrollLockOff > reactions;
84   };
85 
86   struct ScrollLockOff : sc::simple_state< ScrollLockOff, Active::orthogonal< 2 > >
87   {
88     typedef sc::transition< EvScrollLockPressed, ScrollLockOn > reactions;
89   };
90 
react(const EvRequestShutdown &)91 sc::result Active::react( const EvRequestShutdown & )
92 {
93   if ( ( state_downcast< const NumLockOff * >() != 0 ) &&
94         ( state_downcast< const CapsLockOff * >() != 0 ) &&
95         ( state_downcast< const ScrollLockOff * >() != 0 ) )
96   {
97     std::cout << "Shutdown request accepted\n";
98     return terminate();
99   }
100   else
101   {
102     std::cout << "Ignoring shutdown request\n\n";
103     return discard_event();
104   }
105 }
106 
107 
108 //////////////////////////////////////////////////////////////////////////////
DisplayStateConfiguration(const Keyboard & keyboard)109 void DisplayStateConfiguration( const Keyboard & keyboard )
110 {
111   char orthogonalRegion = 'a';
112 
113   for ( Keyboard::state_iterator pLeafState = keyboard.state_begin();
114     pLeafState != keyboard.state_end(); ++pLeafState )
115   {
116     std::cout << "Orthogonal region " << orthogonalRegion << ": ";
117 
118     const Keyboard::state_base_type * pState = &*pLeafState;
119 
120     while ( pState != 0 )
121     {
122       if ( pState != &*pLeafState )
123       {
124         std::cout << " -> ";
125       }
126 
127       #ifdef BOOST_STATECHART_USE_NATIVE_RTTI
128       std::cout << std::setw( 15 ) << typeid( *pState ).name();
129       #else
130       std::cout << std::setw( 15 ) <<
131         pState->custom_dynamic_type_ptr< char >();
132       #endif
133       pState = pState->outer_state_ptr();
134     }
135 
136     std::cout << "\n";
137     ++orthogonalRegion;
138   }
139 
140   std::cout << "\n";
141 }
142 
143 
144 //////////////////////////////////////////////////////////////////////////////
main()145 int main()
146 {
147   #ifndef BOOST_STATECHART_USE_NATIVE_RTTI
148   Active::custom_static_type_ptr( "Active" );
149   NumLockOn::custom_static_type_ptr( "NumLockOn" );
150   NumLockOff::custom_static_type_ptr( "NumLockOff" );
151   CapsLockOn::custom_static_type_ptr( "CapsLockOn" );
152   CapsLockOff::custom_static_type_ptr( "CapsLockOff" );
153   ScrollLockOn::custom_static_type_ptr( "ScrollLockOn" );
154   ScrollLockOff::custom_static_type_ptr( "ScrollLockOff" );
155   #endif
156 
157   std::cout << "Boost.Statechart Keyboard example\n\n";
158   Keyboard keyboard;
159   keyboard.initiate();
160   DisplayStateConfiguration( keyboard );
161   keyboard.process_event( EvNumLockPressed() );
162   DisplayStateConfiguration( keyboard );
163   keyboard.process_event( EvRequestShutdown() );
164   keyboard.process_event( EvCapsLockPressed() );
165   DisplayStateConfiguration( keyboard );
166   keyboard.process_event( EvRequestShutdown() );
167   keyboard.process_event( EvScrollLockPressed() );
168   DisplayStateConfiguration( keyboard );
169   keyboard.process_event( EvRequestShutdown() );
170 
171   keyboard.process_event( EvNumLockPressed() );
172   DisplayStateConfiguration( keyboard );
173   keyboard.process_event( EvRequestShutdown() );
174   keyboard.process_event( EvCapsLockPressed() );
175   DisplayStateConfiguration( keyboard );
176   keyboard.process_event( EvRequestShutdown() );
177   keyboard.process_event( EvScrollLockPressed() );
178   DisplayStateConfiguration( keyboard );
179   keyboard.process_event( EvRequestShutdown() );
180 
181   return 0;
182 }
183