]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/msm/doc/HTML/examples/ActiveStateSetBeforeTransition.cpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / msm / doc / HTML / examples / ActiveStateSetBeforeTransition.cpp
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
11 #include <iostream>
12 // back-end
13 #include <boost/msm/back/state_machine.hpp>
14
15 //front-end
16 #include <boost/msm/front/state_machine_def.hpp>
17 // functors
18 #include <boost/msm/front/functor_row.hpp>
19 #include <boost/msm/front/euml/common.hpp>
20
21
22 using namespace std;
23 namespace msm = boost::msm;
24 namespace mpl = boost::mpl;
25 using namespace msm::front;
26
27 namespace // Concrete FSM implementation
28 {
29 // events
30 struct disconnect {};
31 struct connect {};
32
33 // flag
34 struct is_connected{};
35 // front-end: define the FSM structure
36 struct Connection_ : public msm::front::state_machine_def<Connection_>
37 {
38 // when a transition is about to be taken, we already update our currently active state(s)
39 typedef msm::active_state_switch_before_transition active_state_switch_policy;
40
41 // The list of FSM states
42 struct Connected : public msm::front::state<>
43 {
44 // in this state, we are connected
45 typedef mpl::vector1<is_connected> flag_list;
46 template <class Event,class FSM>
47 void on_entry(Event const&,FSM& ) {std::cout << "entering: Connected" << std::endl;}
48 template <class Event,class FSM>
49 void on_exit(Event const&,FSM& ) {std::cout << "leaving: Connected" << std::endl;}
50 };
51 struct Disconnected : public msm::front::state<>
52 {
53 template <class Event,class FSM>
54 void on_entry(Event const& ,FSM&) {std::cout << "entering: Disconnected" << std::endl;}
55 template <class Event,class FSM>
56 void on_exit(Event const&,FSM& ) {std::cout << "leaving: Disconnected" << std::endl;}
57 };
58
59 // transition actions
60 struct SignalConnect
61 {
62 template <class EVT,class FSM,class SourceState,class TargetState>
63 void operator()(EVT const&, FSM& fsm,SourceState& ,TargetState& )
64 {
65 // by default, this would be wrong (shows false)
66 cout << "SignalConnect. Connected? " << std::boolalpha << fsm.template is_flag_active<is_connected>() << endl;
67 }
68 };
69 struct SignalDisconnect
70 {
71 template <class EVT,class FSM,class SourceState,class TargetState>
72 void operator()(EVT const&, FSM& fsm,SourceState& ,TargetState& )
73 {
74 // by default, this would be wrong (shows true)
75 cout << "SignalDisconnect. Connected? " << std::boolalpha << fsm.template is_flag_active<is_connected>() << endl;
76 }
77 };
78
79 // the initial state of the player SM. Must be defined
80 typedef Disconnected initial_state;
81
82 // Transition table for player
83 struct transition_table : mpl::vector<
84 // Start Event Next Action Guard
85 // +--------------+-------------+--------------+---------------------------+----------------------+
86 Row < Connected , disconnect , Disconnected , SignalDisconnect , none >,
87 Row < Disconnected , connect , Connected , SignalConnect , none >
88 // +--------------+-------------+--------------+---------------------------+----------------------+
89 > {};
90 // Replaces the default no-transition response.
91 template <class FSM,class Event>
92 void no_transition(Event const& e, FSM&,int state)
93 {
94 std::cout << "no transition from state " << state
95 << " on event " << typeid(e).name() << std::endl;
96 }
97 };
98 // Pick a back-end
99 typedef msm::back::state_machine<Connection_> Connection;
100
101
102 void test()
103 {
104 Connection connection;
105 // needed to start the highest-level SM. This will call on_entry and mark the start of the SM
106 connection.start();
107 // signal a connection
108 connection.process_event(connect());
109 // signal a disconnection
110 connection.process_event(disconnect());
111 connection.stop();
112 }
113 }
114
115 int main()
116 {
117 test();
118 return 0;
119 }