]> git.proxmox.com Git - ceph.git/blame - 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
CommitLineData
7c673cae
FG
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
22using namespace std;
23namespace msm = boost::msm;
24namespace mpl = boost::mpl;
25using namespace msm::front;
26
27namespace // 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
115int main()
116{
117 test();
118 return 0;
119}