Keyboard.cpp 5.7 KB

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