Advertisement
Guest User

Untitled

a guest
Oct 22nd, 2016
65
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.13 KB | None | 0 0
  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
  4. // library
  5. // Distributed under the same license as the original.
  6. // Copyright for the original version:
  7. // Copyright 2005 David Abrahams and Aleksey Gurtovoy. Distributed
  8. // under the Boost Software License, Version 1.0. (See accompanying
  9. // file LICENSE_1_0.txt or copy at
  10. // http://www.boost.org/LICENSE_1_0.txt)
  11.  
  12. #include <chrono>
  13. #include <iostream>
  14. #include <thread>
  15. // back-end
  16. #include <boost/msm/back/state_machine.hpp>
  17. // front-end
  18. #include <boost/msm/front/state_machine_def.hpp>
  19. // functors
  20. #include <boost/msm/front/euml/common.hpp>
  21. #include <boost/msm/front/functor_row.hpp>
  22.  
  23. namespace msm = boost::msm;
  24. namespace mpl = boost::mpl;
  25. using namespace boost::msm::front;
  26.  
  27. namespace {
  28. // events
  29. struct event1 {};
  30.  
  31. // front-end: define the FSM structure
  32. struct my_machine_ : public msm::front::state_machine_def<my_machine_> {
  33.   // The list of FSM states
  34.   struct State1 : public msm::front::state<> {
  35.     // every (optional) entry/exit methods get the event passed.
  36.     template <class Event, class FSM> void on_entry(Event const &, FSM &) {
  37.       std::cout << "entering: State1" << std::endl;
  38.     }
  39.     template <class Event, class FSM> void on_exit(Event const &, FSM &) {
  40.       std::cout << "leaving: State1" << std::endl;
  41.     }
  42.   };
  43.   struct State2 : public msm::front::state<> {
  44.     template <class Event, class FSM> void on_entry(Event const &, FSM &) {
  45.       std::cout << "entering: State2" << std::endl;
  46.     }
  47.     template <class Event, class FSM> void on_exit(Event const &, FSM &) {
  48.       std::cout << "leaving: State2" << std::endl;
  49.     }
  50.   };
  51.  
  52.   struct State3 : public msm::front::state<> {
  53.     // when stopped, the CD is loaded
  54.     template <class Event, class FSM> void on_entry(Event const &, FSM &) {
  55.       std::cout << "entering: State3" << std::endl;
  56.     }
  57.     template <class Event, class FSM> void on_exit(Event const &, FSM &) {
  58.       std::cout << "leaving: State3" << std::endl;
  59.     }
  60.   };
  61.  
  62.   struct State4 : public msm::front::state<> {
  63.     template <class Event, class FSM> void on_entry(Event const &, FSM &) {
  64.       std::cout << "entering: State4" << std::endl;
  65.     }
  66.     template <class Event, class FSM> void on_exit(Event const &, FSM &) {
  67.       std::cout << "leaving: State4" << std::endl;
  68.     }
  69.   };
  70.  
  71.   // the initial state of the player SM. Must be defined
  72.   typedef State1 initial_state;
  73.  
  74.   // transition actions
  75.   struct State2ToState3 {
  76.     template <class EVT, class FSM, class SourceState, class TargetState>
  77.     void operator()(EVT const &, FSM &, SourceState &, TargetState &) {
  78.       std::cout << "my_machine::State2ToState3" << std::endl;
  79.     }
  80.   };
  81.   struct State3ToState4 {
  82.     template <class EVT, class FSM, class SourceState, class TargetState>
  83.     void operator()(EVT const &, FSM &, SourceState &, TargetState &) {
  84.       std::cout << "my_machine::State3ToState4" << std::endl;
  85.     }
  86.   };
  87.  
  88.   struct BlockingCall {
  89.     template <class EVT, class FSM, class SourceState, class TargetState>
  90.     void operator()(EVT const &, FSM &, SourceState &, TargetState &) {
  91.       std::cout << "my_machine::Waiting for a thing to happen..." << std::endl;
  92.       // Pretend I'm actually waiting for something
  93.       std::this_thread::sleep_for(std::chrono::milliseconds(100));
  94.       std::cout << "my_machine::OMG the the thing happened!" << std::endl;
  95.     }
  96.   };
  97.  
  98.   // guard conditions
  99.   struct always_true {
  100.     template <class EVT, class FSM, class SourceState, class TargetState>
  101.     bool operator()(EVT const &evt, FSM &fsm, SourceState &src,
  102.                     TargetState &tgt) {
  103.       std::cout << "always_true" << std::endl;
  104.       return true;
  105.     }
  106.   };
  107.   struct always_false {
  108.     template <class EVT, class FSM, class SourceState, class TargetState>
  109.     bool operator()(EVT const &evt, FSM &fsm, SourceState &src,
  110.                     TargetState &tgt) {
  111.       std::cout << "always_false" << std::endl;
  112.       return true;
  113.     }
  114.   };
  115.  
  116.   typedef my_machine_ p; // makes transition table cleaner
  117.  
  118.   // Transition table for player
  119.   // clang-format off
  120.         struct transition_table : mpl::vector<
  121.             //    Start     Event         Next      Action               Guard
  122.             //  +---------+-------------+---------+---------------------+----------------------+
  123.             Row < State1  , none        , State2                                               >,
  124.             Row < State2  , none        , State3  , State2ToState3                             >,
  125.             Row < State3  , none        , State4  , none                , always_false         >,
  126.             //  +---------+-------------+---------+---------------------+----------------------+
  127.             Row < State3  , none        , State4  , State3ToState4      , always_true          >,
  128.             Row < State4  , none        , State1                                               >
  129.             //  +---------+-------------+---------+---------------------+----------------------+
  130.         > {};
  131.   // clang-format on
  132.   // Replaces the default no-transition response.
  133.   template <class FSM, class Event>
  134.   void no_transition(Event const &e, FSM &, int state) {
  135.     std::cout << "no transition from state " << state << " on event "
  136.               << typeid(e).name() << std::endl;
  137.   }
  138. };
  139. // Pick a back-end
  140. typedef msm::back::state_machine<my_machine_> my_machine;
  141.  
  142. //
  143. // Testing utilities.
  144. //
  145. static char const *const state_names[] = {"State1", "State2", "State3",
  146.                                           "State4"};
  147. void pstate(my_machine const &p) {
  148.   std::cout << " -> " << state_names[p.current_state()[0]] << std::endl;
  149. }
  150.  
  151. void test() {
  152.   my_machine p;
  153.  
  154.   // needed to start the highest-level SM. This will call on_entry and mark the
  155.   // start of the SM
  156.   // in this case it will also immediately trigger all anonymous transitions
  157.   p.start();
  158.   // this event will bring us back to the initial state and thus, a new "loop"
  159.   // will be started
  160.   p.process_event(event1());
  161. }
  162. }
  163.  
  164. int main() {
  165.   test();
  166.   return 0;
  167. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement