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 //////////////////////////////////////////////////////////////////////////////
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
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>
23 #include <boost/mpl/list.hpp>
24 #include <boost/config.hpp>
30 # pragma warning( disable: 304 ) // access control not specified
31 # pragma warning( disable: 981 ) // operands are evaluated in unspecified order
36 namespace sc = boost::statechart;
37 namespace mpl = boost::mpl;
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 > {};
48 struct Keyboard : sc::state_machine< Keyboard, Active > {};
53 struct Active: sc::simple_state<
54 Active, Keyboard, mpl::list< NumLockOff, CapsLockOff, ScrollLockOff > >
56 typedef sc::custom_reaction< EvRequestShutdown > reactions;
58 sc::result react( const EvRequestShutdown & );
61 struct NumLockOn : sc::simple_state< NumLockOn, Active::orthogonal< 0 > >
63 typedef sc::transition< EvNumLockPressed, NumLockOff > reactions;
66 struct NumLockOff : sc::simple_state< NumLockOff, Active::orthogonal< 0 > >
68 typedef sc::transition< EvNumLockPressed, NumLockOn > reactions;
71 struct CapsLockOn : sc::simple_state< CapsLockOn, Active::orthogonal< 1 > >
73 typedef sc::transition< EvCapsLockPressed, CapsLockOff > reactions;
76 struct CapsLockOff : sc::simple_state< CapsLockOff, Active::orthogonal< 1 > >
78 typedef sc::transition< EvCapsLockPressed, CapsLockOn > reactions;
81 struct ScrollLockOn : sc::simple_state< ScrollLockOn, Active::orthogonal< 2 > >
83 typedef sc::transition< EvScrollLockPressed, ScrollLockOff > reactions;
86 struct ScrollLockOff : sc::simple_state< ScrollLockOff, Active::orthogonal< 2 > >
88 typedef sc::transition< EvScrollLockPressed, ScrollLockOn > reactions;
91 sc::result Active::react( const EvRequestShutdown & )
93 if ( ( state_downcast< const NumLockOff * >() != 0 ) &&
94 ( state_downcast< const CapsLockOff * >() != 0 ) &&
95 ( state_downcast< const ScrollLockOff * >() != 0 ) )
97 std::cout << "Shutdown request accepted\n";
102 std::cout << "Ignoring shutdown request\n\n";
103 return discard_event();
108 //////////////////////////////////////////////////////////////////////////////
109 void DisplayStateConfiguration( const Keyboard & keyboard )
111 char orthogonalRegion = 'a';
113 for ( Keyboard::state_iterator pLeafState = keyboard.state_begin();
114 pLeafState != keyboard.state_end(); ++pLeafState )
116 std::cout << "Orthogonal region " << orthogonalRegion << ": ";
118 const Keyboard::state_base_type * pState = &*pLeafState;
120 while ( pState != 0 )
122 if ( pState != &*pLeafState )
127 #ifdef BOOST_STATECHART_USE_NATIVE_RTTI
128 std::cout << std::setw( 15 ) << typeid( *pState ).name();
130 std::cout << std::setw( 15 ) <<
131 pState->custom_dynamic_type_ptr< char >();
133 pState = pState->outer_state_ptr();
144 //////////////////////////////////////////////////////////////////////////////
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" );
157 std::cout << "Boost.Statechart Keyboard example\n\n";
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() );
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() );