1 // Copyright 2008 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 #ifndef BOOST_MSM_FRONT_STATEMACHINE_DEF_H
12 #define BOOST_MSM_FRONT_STATEMACHINE_DEF_H
13 
14 #include <exception>
15 #include <boost/assert.hpp>
16 
17 #include <boost/mpl/vector.hpp>
18 
19 #include <boost/msm/row_tags.hpp>
20 #include <boost/msm/back/common_types.hpp>
21 #include <boost/msm/front/states.hpp>
22 #include <boost/msm/front/completion_event.hpp>
23 #include <boost/msm/front/common_states.hpp>
24 
25 namespace boost { namespace msm { namespace front
26 {
27 
28 template<class Derived,class BaseState = default_base_state>
29 struct state_machine_def :  public boost::msm::front::detail::state_base<BaseState>
30 {
31     // tags
32     // default: no flag
33     typedef ::boost::mpl::vector0<>               flag_list;
34     typedef ::boost::mpl::vector0<>               internal_flag_list;
35     //default: no deferred events
36     typedef ::boost::mpl::vector0<>               deferred_events;
37     // customization (message queue, exceptions)
38     typedef ::boost::mpl::vector0<>               configuration;
39 
40     typedef BaseState                             BaseAllStates;
41     template<
42         typename T1
43         , class Event
44         , typename T2
45         , void (Derived::*action)(Event const&)
46     >
47     struct a_row
48     {
49         typedef a_row_tag row_type_tag;
50         typedef T1 Source;
51         typedef T2 Target;
52         typedef Event Evt;
53         template <class FSM,class SourceState,class TargetState,class AllStates>
action_callboost::msm::front::state_machine_def::a_row54         static ::boost::msm::back::HandledEnum action_call(FSM& fsm,Event const& evt,SourceState&,TargetState&, AllStates&)
55         {
56             // in this front-end, we don't need to know source and target states
57             (fsm.*action)(evt);
58             return ::boost::msm::back::HANDLED_TRUE;
59         }
60     };
61 
62     template<
63         typename T1
64         , class Event
65         , typename T2
66     >
67     struct _row
68     {
69         typedef _row_tag row_type_tag;
70         typedef T1 Source;
71         typedef T2 Target;
72         typedef Event Evt;
73     };
74 
75     template<
76         typename T1
77         , class Event
78         , typename T2
79         , void (Derived::*action)(Event const&)
80         , bool (Derived::*guard)(Event const&)
81     >
82     struct row
83     {
84         typedef row_tag row_type_tag;
85         typedef T1 Source;
86         typedef T2 Target;
87         typedef Event Evt;
88         template <class FSM,class SourceState,class TargetState, class AllStates>
action_callboost::msm::front::state_machine_def::row89         static ::boost::msm::back::HandledEnum action_call(FSM& fsm,Event const& evt,SourceState&,TargetState&,AllStates&)
90         {
91             // in this front-end, we don't need to know source and target states
92             (fsm.*action)(evt);
93             return ::boost::msm::back::HANDLED_TRUE;
94         }
95         template <class FSM,class SourceState,class TargetState,class AllStates>
guard_callboost::msm::front::state_machine_def::row96         static bool guard_call(FSM& fsm,Event const& evt,SourceState&,TargetState&,AllStates&)
97         {
98             // in this front-end, we don't need to know source and target states
99             return (fsm.*guard)(evt);
100         }
101     };
102     template<
103         typename T1
104         , class Event
105         , typename T2
106         , bool (Derived::*guard)(Event const&)
107     >
108     struct g_row
109     {
110         typedef g_row_tag row_type_tag;
111         typedef T1 Source;
112         typedef T2 Target;
113         typedef Event Evt;
114         template <class FSM,class SourceState,class TargetState,class AllStates>
guard_callboost::msm::front::state_machine_def::g_row115         static bool guard_call(FSM& fsm,Event const& evt,SourceState&,TargetState&,AllStates&)
116         {
117             // in this front-end, we don't need to know source and target states
118             return (fsm.*guard)(evt);
119         }
120     };
121     // internal transitions
122     template<
123         typename T1
124         , class Event
125         , void (Derived::*action)(Event const&)
126     >
127     struct a_irow
128     {
129         typedef a_irow_tag row_type_tag;
130         typedef T1 Source;
131         typedef T1 Target;
132         typedef Event Evt;
133         template <class FSM,class SourceState,class TargetState,class AllStates>
action_callboost::msm::front::state_machine_def::a_irow134         static ::boost::msm::back::HandledEnum action_call(FSM& fsm,Event const& evt,SourceState&,TargetState&,AllStates&)
135         {
136             // in this front-end, we don't need to know source and target states
137             (fsm.*action)(evt);
138             return ::boost::msm::back::HANDLED_TRUE;
139         }
140     };
141 
142     template<
143         typename T1
144         , class Event
145         , void (Derived::*action)(Event const&)
146         , bool (Derived::*guard)(Event const&)
147     >
148     struct irow
149     {
150         typedef irow_tag row_type_tag;
151         typedef T1 Source;
152         typedef T1 Target;
153         typedef Event Evt;
154         template <class FSM,class SourceState,class TargetState,class AllStates>
action_callboost::msm::front::state_machine_def::irow155         static ::boost::msm::back::HandledEnum action_call(FSM& fsm,Event const& evt,SourceState&,TargetState&,AllStates&)
156         {
157             // in this front-end, we don't need to know source and target states
158             (fsm.*action)(evt);
159             return ::boost::msm::back::HANDLED_TRUE;
160         }
161         template <class FSM,class SourceState,class TargetState,class AllStates>
guard_callboost::msm::front::state_machine_def::irow162         static bool guard_call(FSM& fsm,Event const& evt,SourceState&,TargetState&,AllStates&)
163         {
164             // in this front-end, we don't need to know source and target states
165             return (fsm.*guard)(evt);
166         }
167     };
168     template<
169         typename T1
170         , class Event
171         , bool (Derived::*guard)(Event const&)
172     >
173     struct g_irow
174     {
175         typedef g_irow_tag row_type_tag;
176         typedef T1 Source;
177         typedef T1 Target;
178         typedef Event Evt;
179         template <class FSM,class SourceState,class TargetState,class AllStates>
guard_callboost::msm::front::state_machine_def::g_irow180         static bool guard_call(FSM& fsm,Event const& evt,SourceState&,TargetState&,AllStates&)
181         {
182             // in this front-end, we don't need to know source and target states
183             return (fsm.*guard)(evt);
184         }
185     };
186     // internal row withou action or guard. Does nothing except forcing the event to be ignored.
187     template<
188         typename T1
189         , class Event
190     >
191     struct _irow
192     {
193         typedef _irow_tag row_type_tag;
194         typedef T1 Source;
195         typedef T1 Target;
196         typedef Event Evt;
197     };
198 protected:
199     // Default no-transition handler. Can be replaced in the Derived SM class.
200     template <class FSM,class Event>
no_transitionboost::msm::front::state_machine_def201     void no_transition(Event const& ,FSM&, int )
202     {
203         BOOST_ASSERT(false);
204     }
205     // default exception handler. Can be replaced in the Derived SM class.
206     template <class FSM,class Event>
exception_caughtboost::msm::front::state_machine_def207     void exception_caught (Event const&,FSM&,std::exception& )
208     {
209         BOOST_ASSERT(false);
210     }
211 };
212 
213 
214 } } }// boost::msm::front
215 #endif //BOOST_MSM_FRONT_STATEMACHINE_DEF_H
216 
217