--- /dev/null
+//////////////////////////////////////////////////////////////////////////////
+// Copyright 2002-2006 Andreas Huber Doenni
+// Distributed under the Boost Software License, Version 1.0. (See accompany-
+// ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//////////////////////////////////////////////////////////////////////////////
+
+
+
+//////////////////////////////////////////////////////////////////////////////
+// The following example program demonstrates the use of orthogonal states and
+// state_downcast to query the state of orthogonal regions.
+// Moreover, the use of the state type information interface is also shown.
+//////////////////////////////////////////////////////////////////////////////
+// #define BOOST_STATECHART_USE_NATIVE_RTTI
+
+
+#include <boost/statechart/event.hpp>
+#include <boost/statechart/state_machine.hpp>
+#include <boost/statechart/simple_state.hpp>
+#include <boost/statechart/transition.hpp>
+#include <boost/statechart/custom_reaction.hpp>
+
+#include <boost/mpl/list.hpp>
+#include <boost/config.hpp>
+
+#include <iostream>
+#include <iomanip>
+
+#ifdef BOOST_INTEL
+# pragma warning( disable: 304 ) // access control not specified
+# pragma warning( disable: 981 ) // operands are evaluated in unspecified order
+#endif
+
+
+
+namespace sc = boost::statechart;
+namespace mpl = boost::mpl;
+
+
+
+//////////////////////////////////////////////////////////////////////////////
+struct EvNumLockPressed : sc::event< EvNumLockPressed > {};
+struct EvCapsLockPressed : sc::event< EvCapsLockPressed > {};
+struct EvScrollLockPressed : sc::event< EvScrollLockPressed > {};
+struct EvRequestShutdown : sc::event< EvRequestShutdown > {};
+
+struct Active;
+struct Keyboard : sc::state_machine< Keyboard, Active > {};
+
+struct NumLockOff;
+struct CapsLockOff;
+struct ScrollLockOff;
+struct Active: sc::simple_state<
+ Active, Keyboard, mpl::list< NumLockOff, CapsLockOff, ScrollLockOff > >
+{
+ typedef sc::custom_reaction< EvRequestShutdown > reactions;
+
+ sc::result react( const EvRequestShutdown & );
+};
+
+ struct NumLockOn : sc::simple_state< NumLockOn, Active::orthogonal< 0 > >
+ {
+ typedef sc::transition< EvNumLockPressed, NumLockOff > reactions;
+ };
+
+ struct NumLockOff : sc::simple_state< NumLockOff, Active::orthogonal< 0 > >
+ {
+ typedef sc::transition< EvNumLockPressed, NumLockOn > reactions;
+ };
+
+ struct CapsLockOn : sc::simple_state< CapsLockOn, Active::orthogonal< 1 > >
+ {
+ typedef sc::transition< EvCapsLockPressed, CapsLockOff > reactions;
+ };
+
+ struct CapsLockOff : sc::simple_state< CapsLockOff, Active::orthogonal< 1 > >
+ {
+ typedef sc::transition< EvCapsLockPressed, CapsLockOn > reactions;
+ };
+
+ struct ScrollLockOn : sc::simple_state< ScrollLockOn, Active::orthogonal< 2 > >
+ {
+ typedef sc::transition< EvScrollLockPressed, ScrollLockOff > reactions;
+ };
+
+ struct ScrollLockOff : sc::simple_state< ScrollLockOff, Active::orthogonal< 2 > >
+ {
+ typedef sc::transition< EvScrollLockPressed, ScrollLockOn > reactions;
+ };
+
+sc::result Active::react( const EvRequestShutdown & )
+{
+ if ( ( state_downcast< const NumLockOff * >() != 0 ) &&
+ ( state_downcast< const CapsLockOff * >() != 0 ) &&
+ ( state_downcast< const ScrollLockOff * >() != 0 ) )
+ {
+ std::cout << "Shutdown request accepted\n";
+ return terminate();
+ }
+ else
+ {
+ std::cout << "Ignoring shutdown request\n\n";
+ return discard_event();
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+void DisplayStateConfiguration( const Keyboard & keyboard )
+{
+ char orthogonalRegion = 'a';
+
+ for ( Keyboard::state_iterator pLeafState = keyboard.state_begin();
+ pLeafState != keyboard.state_end(); ++pLeafState )
+ {
+ std::cout << "Orthogonal region " << orthogonalRegion << ": ";
+
+ const Keyboard::state_base_type * pState = &*pLeafState;
+
+ while ( pState != 0 )
+ {
+ if ( pState != &*pLeafState )
+ {
+ std::cout << " -> ";
+ }
+
+ #ifdef BOOST_STATECHART_USE_NATIVE_RTTI
+ std::cout << std::setw( 15 ) << typeid( *pState ).name();
+ #else
+ std::cout << std::setw( 15 ) <<
+ pState->custom_dynamic_type_ptr< char >();
+ #endif
+ pState = pState->outer_state_ptr();
+ }
+
+ std::cout << "\n";
+ ++orthogonalRegion;
+ }
+
+ std::cout << "\n";
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+int main()
+{
+ #ifndef BOOST_STATECHART_USE_NATIVE_RTTI
+ Active::custom_static_type_ptr( "Active" );
+ NumLockOn::custom_static_type_ptr( "NumLockOn" );
+ NumLockOff::custom_static_type_ptr( "NumLockOff" );
+ CapsLockOn::custom_static_type_ptr( "CapsLockOn" );
+ CapsLockOff::custom_static_type_ptr( "CapsLockOff" );
+ ScrollLockOn::custom_static_type_ptr( "ScrollLockOn" );
+ ScrollLockOff::custom_static_type_ptr( "ScrollLockOff" );
+ #endif
+
+ std::cout << "Boost.Statechart Keyboard example\n\n";
+ Keyboard keyboard;
+ keyboard.initiate();
+ DisplayStateConfiguration( keyboard );
+ keyboard.process_event( EvNumLockPressed() );
+ DisplayStateConfiguration( keyboard );
+ keyboard.process_event( EvRequestShutdown() );
+ keyboard.process_event( EvCapsLockPressed() );
+ DisplayStateConfiguration( keyboard );
+ keyboard.process_event( EvRequestShutdown() );
+ keyboard.process_event( EvScrollLockPressed() );
+ DisplayStateConfiguration( keyboard );
+ keyboard.process_event( EvRequestShutdown() );
+
+ keyboard.process_event( EvNumLockPressed() );
+ DisplayStateConfiguration( keyboard );
+ keyboard.process_event( EvRequestShutdown() );
+ keyboard.process_event( EvCapsLockPressed() );
+ DisplayStateConfiguration( keyboard );
+ keyboard.process_event( EvRequestShutdown() );
+ keyboard.process_event( EvScrollLockPressed() );
+ DisplayStateConfiguration( keyboard );
+ keyboard.process_event( EvRequestShutdown() );
+
+ return 0;
+}