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