ActiveStateSetBeforeTransition.cpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. // Copyright 2010 Christophe Henry
  2. // henry UNDERSCORE christophe AT hotmail DOT com
  3. // This is an extended version of the state machine available in the boost::mpl library
  4. // Distributed under the same license as the original.
  5. // Copyright for the original version:
  6. // Copyright 2005 David Abrahams and Aleksey Gurtovoy. Distributed
  7. // under the Boost Software License, Version 1.0. (See accompanying
  8. // file LICENSE_1_0.txt or copy at
  9. // http://www.boost.org/LICENSE_1_0.txt)
  10. #include <iostream>
  11. // back-end
  12. #include <boost/msm/back/state_machine.hpp>
  13. //front-end
  14. #include <boost/msm/front/state_machine_def.hpp>
  15. // functors
  16. #include <boost/msm/front/functor_row.hpp>
  17. #include <boost/msm/front/euml/common.hpp>
  18. using namespace std;
  19. namespace msm = boost::msm;
  20. namespace mpl = boost::mpl;
  21. using namespace msm::front;
  22. namespace // Concrete FSM implementation
  23. {
  24. // events
  25. struct disconnect {};
  26. struct connect {};
  27. // flag
  28. struct is_connected{};
  29. // front-end: define the FSM structure
  30. struct Connection_ : public msm::front::state_machine_def<Connection_>
  31. {
  32. // when a transition is about to be taken, we already update our currently active state(s)
  33. typedef msm::active_state_switch_before_transition active_state_switch_policy;
  34. // The list of FSM states
  35. struct Connected : public msm::front::state<>
  36. {
  37. // in this state, we are connected
  38. typedef mpl::vector1<is_connected> flag_list;
  39. template <class Event,class FSM>
  40. void on_entry(Event const&,FSM& ) {std::cout << "entering: Connected" << std::endl;}
  41. template <class Event,class FSM>
  42. void on_exit(Event const&,FSM& ) {std::cout << "leaving: Connected" << std::endl;}
  43. };
  44. struct Disconnected : public msm::front::state<>
  45. {
  46. template <class Event,class FSM>
  47. void on_entry(Event const& ,FSM&) {std::cout << "entering: Disconnected" << std::endl;}
  48. template <class Event,class FSM>
  49. void on_exit(Event const&,FSM& ) {std::cout << "leaving: Disconnected" << std::endl;}
  50. };
  51. // transition actions
  52. struct SignalConnect
  53. {
  54. template <class EVT,class FSM,class SourceState,class TargetState>
  55. void operator()(EVT const&, FSM& fsm,SourceState& ,TargetState& )
  56. {
  57. // by default, this would be wrong (shows false)
  58. cout << "SignalConnect. Connected? " << std::boolalpha << fsm.template is_flag_active<is_connected>() << endl;
  59. }
  60. };
  61. struct SignalDisconnect
  62. {
  63. template <class EVT,class FSM,class SourceState,class TargetState>
  64. void operator()(EVT const&, FSM& fsm,SourceState& ,TargetState& )
  65. {
  66. // by default, this would be wrong (shows true)
  67. cout << "SignalDisconnect. Connected? " << std::boolalpha << fsm.template is_flag_active<is_connected>() << endl;
  68. }
  69. };
  70. // the initial state of the player SM. Must be defined
  71. typedef Disconnected initial_state;
  72. // Transition table for player
  73. struct transition_table : mpl::vector<
  74. // Start Event Next Action Guard
  75. // +--------------+-------------+--------------+---------------------------+----------------------+
  76. Row < Connected , disconnect , Disconnected , SignalDisconnect , none >,
  77. Row < Disconnected , connect , Connected , SignalConnect , none >
  78. // +--------------+-------------+--------------+---------------------------+----------------------+
  79. > {};
  80. // Replaces the default no-transition response.
  81. template <class FSM,class Event>
  82. void no_transition(Event const& e, FSM&,int state)
  83. {
  84. std::cout << "no transition from state " << state
  85. << " on event " << typeid(e).name() << std::endl;
  86. }
  87. };
  88. // Pick a back-end
  89. typedef msm::back::state_machine<Connection_> Connection;
  90. void test()
  91. {
  92. Connection connection;
  93. // needed to start the highest-level SM. This will call on_entry and mark the start of the SM
  94. connection.start();
  95. // signal a connection
  96. connection.process_event(connect());
  97. // signal a disconnection
  98. connection.process_event(disconnect());
  99. connection.stop();
  100. }
  101. }
  102. int main()
  103. {
  104. test();
  105. return 0;
  106. }