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() );