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 | // back-end |
12 | #include <boost/msm/back11/state_machine.hpp> |
13 | //front-end |
14 | #include <boost/msm/front/state_machine_def.hpp> |
15 | #include <boost/msm/front/functor_row.hpp> |
16 | |
17 | #ifndef BOOST_MSM_NONSTANDALONE_TEST |
18 | #define BOOST_TEST_MODULE back11_set_states_test |
19 | #endif |
20 | #include <boost/test/unit_test.hpp> |
21 | |
22 | namespace msm = boost::msm; |
23 | namespace mpl = boost::mpl; |
24 | namespace fusion = boost::fusion; |
25 | using namespace msm::front; |
26 | |
27 | namespace |
28 | { |
29 | struct InputEvent {}; |
30 | struct ExitEvent |
31 | { |
32 | ExitEvent() = default; |
33 | template <typename T> |
34 | ExitEvent(const T&) {}; |
35 | }; |
36 | |
37 | struct State : public boost::msm::front::state<> |
38 | { |
39 | template <class Event, class FSM> |
40 | void on_entry(Event const& e, FSM& fsm) |
41 | { |
42 | std::cout << "State - on_entry" << "\n" ; |
43 | }; |
44 | |
45 | template <class Event, class FSM> |
46 | void on_exit(Event const& e, FSM& fsm) |
47 | { |
48 | std::cout << "State - on_exit" << "\n" ; |
49 | } |
50 | }; |
51 | |
52 | struct TerminateState : public boost::msm::front::terminate_state<> |
53 | { |
54 | template <class Event, class FSM> |
55 | void on_entry(Event const& e, FSM& fsm) |
56 | { |
57 | std::cout << "TerminateState - on_entry" << "\n" ; |
58 | }; |
59 | |
60 | template <class Event, class FSM> |
61 | void on_exit(Event const& e, FSM& fsm) |
62 | { |
63 | std::cout << "TerminateState - on_exit" << "\n" ; |
64 | } |
65 | }; |
66 | |
67 | struct PseudoExitState : public boost::msm::front::exit_pseudo_state<ExitEvent> |
68 | { |
69 | }; |
70 | |
71 | struct SubFsm_ : public msm::front::state_machine_def<SubFsm_> |
72 | { |
73 | template <class Event, class FSM> |
74 | void on_entry(Event const& e, FSM& fsm) |
75 | { |
76 | std::cout << "SubFsm - on_entry" << "\n" ; |
77 | }; |
78 | |
79 | template <class Event, class FSM> |
80 | void on_exit(Event const& e, FSM& fsm) |
81 | { |
82 | std::cout << "SubFsm - on_exit" << "\n" ; |
83 | } |
84 | |
85 | typedef State initial_state; |
86 | |
87 | struct transition_table : mpl::vector< |
88 | Row< State, InputEvent, PseudoExitState, none, none > |
89 | > {}; |
90 | |
91 | template <class FSM, class Event> |
92 | void no_transition(Event const& e, FSM&, int state) |
93 | { |
94 | std::cout << "SubFsm: no transition from state " << state |
95 | << " on event " << typeid(e).name() << std::endl; |
96 | } |
97 | }; |
98 | typedef msm::back11::state_machine<SubFsm_> SubFsm; |
99 | |
100 | struct Fsm_ : public msm::front::state_machine_def<Fsm_> |
101 | { |
102 | template <class Event, class FSM> |
103 | void on_entry(Event const& e, FSM& fsm) |
104 | { |
105 | std::cout << "Fsm - on_entry" << "\n" ; |
106 | }; |
107 | |
108 | template <class Event, class FSM> |
109 | void on_exit(Event const& e, FSM& fsm) |
110 | { |
111 | std::cout << "Fsm - on_exit" << "\n" ; |
112 | } |
113 | |
114 | typedef SubFsm initial_state; |
115 | |
116 | struct transition_table : mpl::vector< |
117 | Row< SubFsm::exit_pt<PseudoExitState>, ExitEvent, TerminateState, none, none > |
118 | > {}; |
119 | |
120 | template <class FSM, class Event> |
121 | void no_transition(Event const& e, FSM&, int state) |
122 | { |
123 | std::cout << "Fsm: no transition from state " << state |
124 | << " on event " << typeid(e).name() << std::endl; |
125 | } |
126 | }; |
127 | typedef msm::back11::state_machine<Fsm_> Fsm; |
128 | |
129 | |
130 | BOOST_AUTO_TEST_CASE(back11_set_states_test) |
131 | { |
132 | InputEvent input_event; |
133 | |
134 | std::cout << "\nSubFsms created in constructor\n" ; |
135 | Fsm fsm_subfsms_created_in_constructor(boost::msm::back::states_ |
136 | << SubFsm()); |
137 | fsm_subfsms_created_in_constructor.start(); |
138 | fsm_subfsms_created_in_constructor.process_event(evt&: input_event); |
139 | |
140 | std::cout << "\nSubFsms created through set_states method\n" ; |
141 | Fsm fsm_subfsms_created_thorugh_constructor; |
142 | fsm_subfsms_created_thorugh_constructor.set_states(boost::msm::back::states_ |
143 | << SubFsm()); |
144 | fsm_subfsms_created_thorugh_constructor.start(); |
145 | fsm_subfsms_created_thorugh_constructor.process_event(evt&: input_event); |
146 | } |
147 | } |
148 | |
149 | |