Ticket #9280: main.cc

File main.cc, 5.1 KB (added by Dmitry Banschikov <me@…>, 9 years ago)

Processing of deferred events for submachine

Line 
1#include <iostream>
2
3#include <boost/bind.hpp>
4#include <boost/msm/back/state_machine.hpp>
5#include <boost/msm/front/state_machine_def.hpp>
6#include <boost/shared_ptr.hpp>
7
8namespace msm = boost::msm;
9namespace mpl = boost::mpl;
10
11struct cmd_t {
12 cmd_t(int id) : id_(id) {}
13 virtual ~cmd_t() {}
14
15 int id_;
16};
17
18struct test_machine_front_t : public msm::front::state_machine_def<test_machine_front_t> {
19
20 struct ev_connected {};
21 struct ev_disconnected {};
22
23 // internal connected state events
24 struct ev_async_send_simple_cmd
25 {
26 ev_async_send_simple_cmd(boost::shared_ptr<cmd_t> op) : op_(op) {}
27 boost::shared_ptr<cmd_t> op_;
28 };
29
30 struct ev_async_send_cmd_with_reply
31 {
32 ev_async_send_cmd_with_reply(boost::shared_ptr<cmd_t> op) : op_(op) {}
33 boost::shared_ptr<cmd_t> op_;
34 };
35
36 struct ev_async_got_reply {};
37
38 // disconnected state
39 struct st_disconnected : public msm::front::state<> {};
40
41 // connected state is submachine
42 // front-end st_connected_
43 struct st_connected_ : public msm::front::state_machine_def<st_connected_>
44 {
45 struct st_ready : public msm::front::state<> {};
46
47 struct st_busy : public msm::front::state<>
48 {
49 typedef mpl::vector<ev_async_send_simple_cmd, ev_async_send_cmd_with_reply> deferred_events;
50 };
51
52 // the initial state of st_connected_
53 typedef st_ready initial_state;
54
55 void on_simple_cmd( const ev_async_send_simple_cmd& ev )
56 {
57 std::cout << "On simple cmd: " << ev.op_ << std::endl;
58
59 op_ = ev.op_;
60 }
61
62 void on_cmd_with_reply( const ev_async_send_cmd_with_reply& ev )
63 {
64 std::cout << "On cmd with reply: " << ev.op_->id_ << std::endl;
65 op_ = ev.op_;
66 }
67
68 void on_got_reply( const ev_async_got_reply& )
69 {
70 // std::cout << "On got reply" << std::endl;
71 op_.reset();
72 }
73
74 template <class Event, class Fsm>
75 void on_exit(Event const&, Fsm&)
76 {
77 std::cout << "On exit" << std::endl;
78 op_.reset();
79 }
80
81 typedef st_connected_ m;
82
83 // transition table for st_connected_
84 struct transition_table : mpl::vector<
85 // Start Event Next Action Guard
86 // +---------+-----------------------------+---------+----------------------+----------------+
87 a_row < st_ready, ev_async_send_cmd_with_reply, st_busy , &m::on_cmd_with_reply>,
88 a_row < st_ready, ev_async_send_simple_cmd , st_ready, &m::on_simple_cmd >,
89 a_row < st_busy , ev_async_got_reply , st_ready, &m::on_got_reply >
90 // +---------+-----------------------------+---------+----------------------+----------------+
91 > {};
92
93 typedef int no_message_queue;
94 typedef int no_exception_thrown;
95
96 boost::shared_ptr<cmd_t> op_;
97 };
98
99 // back-end st_connected_
100 typedef msm::back::state_machine<st_connected_> st_connected;
101
102 // the initial state of machine_
103 typedef st_disconnected initial_state;
104
105 // transition table for machine_
106 struct transition_table : mpl::vector<
107 // Start Event Next Action Guard
108 // +---------------+----------------+-----------------+--------------------+----------------------+
109 _row < st_disconnected, ev_connected , st_connected >,
110 _row < st_connected , ev_disconnected, st_disconnected >
111 // +---------------+----------------+-----------------+--------------------+----------------------+
112 > {};
113
114 // replaces the default no-transition response.
115 template <class FSM,class Event>
116 void no_transition(Event const&, FSM&, int)
117 {
118 assert("Client FSM no_transition");
119 }
120
121 typedef int no_message_queue;
122 typedef int no_exception_thrown;
123};
124
125struct test_machine_t : public msm::back::state_machine<test_machine_front_t, std::deque<boost::function<boost::msm::back::HandledEnum()> > > {};
126
127int main(int argc, char* argv[])
128{
129 test_machine_t machine;
130
131 machine.process_event(test_machine_front_t::ev_connected());
132 machine.process_event(test_machine_front_t::ev_async_send_cmd_with_reply(boost::shared_ptr<cmd_t>(new cmd_t(0))));
133 machine.process_event(test_machine_front_t::ev_async_send_cmd_with_reply(boost::shared_ptr<cmd_t>(new cmd_t(1))));
134 machine.process_event(test_machine_front_t::ev_async_send_cmd_with_reply(boost::shared_ptr<cmd_t>(new cmd_t(2))));
135 machine.process_event(test_machine_front_t::ev_async_send_cmd_with_reply(boost::shared_ptr<cmd_t>(new cmd_t(3))));
136 machine.process_event(test_machine_front_t::ev_async_send_cmd_with_reply(boost::shared_ptr<cmd_t>(new cmd_t(4))));
137 machine.process_event(test_machine_front_t::ev_disconnected());
138 machine.process_event(test_machine_front_t::ev_connected());
139 machine.process_event(test_machine_front_t::ev_async_send_cmd_with_reply(boost::shared_ptr<cmd_t>(new cmd_t(5))));
140 machine.process_event(test_machine_front_t::ev_async_got_reply());
141 return 0;
142}