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
36namespace sc = boost::statechart;
37namespace mpl = boost::mpl;
38
39
40
41//////////////////////////////////////////////////////////////////////////////
42struct EvNumLockPressed : sc::event< EvNumLockPressed > {};
43struct EvCapsLockPressed : sc::event< EvCapsLockPressed > {};
44struct EvScrollLockPressed : sc::event< EvScrollLockPressed > {};
45struct EvRequestShutdown : sc::event< EvRequestShutdown > {};
46
47struct Active;
48struct Keyboard : sc::state_machine< Keyboard, Active > {};
49
50struct NumLockOff;
51struct CapsLockOff;
52struct ScrollLockOff;
53struct 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
91sc::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//////////////////////////////////////////////////////////////////////////////
109void 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//////////////////////////////////////////////////////////////////////////////
145int main()
146{
147 #ifndef BOOST_STATECHART_USE_NATIVE_RTTI
148 Active::custom_static_type_ptr( pCustomId: "Active" );
149 NumLockOn::custom_static_type_ptr( pCustomId: "NumLockOn" );
150 NumLockOff::custom_static_type_ptr( pCustomId: "NumLockOff" );
151 CapsLockOn::custom_static_type_ptr( pCustomId: "CapsLockOn" );
152 CapsLockOff::custom_static_type_ptr( pCustomId: "CapsLockOff" );
153 ScrollLockOn::custom_static_type_ptr( pCustomId: "ScrollLockOn" );
154 ScrollLockOff::custom_static_type_ptr( pCustomId: "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( evt: EvNumLockPressed() );
162 DisplayStateConfiguration( keyboard );
163 keyboard.process_event( evt: EvRequestShutdown() );
164 keyboard.process_event( evt: EvCapsLockPressed() );
165 DisplayStateConfiguration( keyboard );
166 keyboard.process_event( evt: EvRequestShutdown() );
167 keyboard.process_event( evt: EvScrollLockPressed() );
168 DisplayStateConfiguration( keyboard );
169 keyboard.process_event( evt: EvRequestShutdown() );
170
171 keyboard.process_event( evt: EvNumLockPressed() );
172 DisplayStateConfiguration( keyboard );
173 keyboard.process_event( evt: EvRequestShutdown() );
174 keyboard.process_event( evt: EvCapsLockPressed() );
175 DisplayStateConfiguration( keyboard );
176 keyboard.process_event( evt: EvRequestShutdown() );
177 keyboard.process_event( evt: EvScrollLockPressed() );
178 DisplayStateConfiguration( keyboard );
179 keyboard.process_event( evt: EvRequestShutdown() );
180
181 return 0;
182}
183

source code of boost/libs/statechart/example/Keyboard/Keyboard.cpp