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_BACK_HISTORY_POLICIES_H 12 #define BOOST_MSM_BACK_HISTORY_POLICIES_H 13 14 #include <boost/mpl/contains.hpp> 15 16 namespace boost { namespace msm { namespace back 17 { 18 19 // policy classes 20 21 // Default: no history used 22 template <int NumberOfRegions> 23 class NoHistoryImpl 24 { 25 public: NoHistoryImpl()26 NoHistoryImpl(){} ~NoHistoryImpl()27 ~NoHistoryImpl(){} set_initial_states(int * const initial_states)28 void set_initial_states(int* const initial_states) 29 { 30 for (int i=0;i<NumberOfRegions;++i) 31 m_initialStates[i] = initial_states[i]; 32 } history_exit(int * const)33 void history_exit(int* const ) 34 { 35 // ignore 36 } 37 // returns the state where the state machine should be at start 38 template <class Event> history_entry(Event const &)39 const int* history_entry(Event const& ) 40 { 41 // always come back to the original state 42 return m_initialStates; 43 } operator =(NoHistoryImpl<NumberOfRegions> const & rhs)44 NoHistoryImpl<NumberOfRegions>& operator=(NoHistoryImpl<NumberOfRegions> const& rhs) 45 { 46 for (int i=0; i<NumberOfRegions;++i) 47 { 48 m_initialStates[i] = rhs.m_initialStates[i]; 49 } 50 return *this; 51 } 52 // this policy deletes all waiting deferred events 53 template <class Event> process_deferred_events(Event const &) const54 bool process_deferred_events(Event const&)const 55 { 56 return false; 57 } 58 template<class Archive> serialize(Archive & ar,const unsigned int)59 void serialize(Archive & ar, const unsigned int) 60 { 61 ar & m_initialStates; 62 } 63 private: 64 int m_initialStates[NumberOfRegions]; 65 }; 66 67 // not UML standard. Always activates history, no matter which event generated the transition 68 template <int NumberOfRegions> 69 class AlwaysHistoryImpl 70 { 71 public: AlwaysHistoryImpl()72 AlwaysHistoryImpl(){} ~AlwaysHistoryImpl()73 ~AlwaysHistoryImpl(){} set_initial_states(int * const initial_states)74 void set_initial_states(int* const initial_states) 75 { 76 for (int i=0;i<NumberOfRegions;++i) 77 m_initialStates[i] = initial_states[i]; 78 } history_exit(int * const current_states)79 void history_exit(int* const current_states) 80 { 81 for (int i=0;i<NumberOfRegions;++i) 82 m_initialStates[i] = current_states[i]; 83 } 84 // returns the state where the state machine should be at start 85 template <class Event> history_entry(Event const &)86 const int* history_entry(Event const& ) 87 { 88 // always load back the last active state 89 return m_initialStates; 90 } operator =(AlwaysHistoryImpl<NumberOfRegions> const & rhs)91 AlwaysHistoryImpl<NumberOfRegions>& operator=(AlwaysHistoryImpl<NumberOfRegions> const& rhs) 92 { 93 for (int i=0; i<NumberOfRegions;++i) 94 { 95 m_initialStates[i] = rhs.m_initialStates[i]; 96 } 97 return *this; 98 } 99 // the history policy keeps all deferred events until next reentry 100 template <class Event> process_deferred_events(Event const &) const101 bool process_deferred_events(Event const&)const 102 { 103 return true; 104 } 105 106 template<class Archive> serialize(Archive & ar,const unsigned int)107 void serialize(Archive & ar, const unsigned int) 108 { 109 ar & m_initialStates; 110 } 111 private: 112 int m_initialStates[NumberOfRegions]; 113 }; 114 115 // UML Shallow history. For deep history, just use this policy for all the contained state machines 116 template <class Events,int NumberOfRegions> 117 class ShallowHistoryImpl 118 { 119 public: ShallowHistoryImpl()120 ShallowHistoryImpl(){} ~ShallowHistoryImpl()121 ~ShallowHistoryImpl(){} set_initial_states(int * const initial_states)122 void set_initial_states(int* const initial_states) 123 { 124 for (int i=0;i<NumberOfRegions;++i) 125 { 126 m_currentStates[i] = initial_states[i]; 127 m_initialStates[i] = initial_states[i]; 128 } 129 } history_exit(int * const current_states)130 void history_exit(int* const current_states) 131 { 132 for (int i=0;i<NumberOfRegions;++i) 133 m_currentStates[i] = current_states[i]; 134 } 135 // returns the state where the state machine should be at start 136 template <class Event> history_entry(Event const &)137 const int* history_entry(Event const&) 138 { 139 if ( ::boost::mpl::contains<Events,Event>::value) 140 { 141 return m_currentStates; 142 } 143 // not one of our events, no history 144 return m_initialStates; 145 } operator =(ShallowHistoryImpl<Events,NumberOfRegions> const & rhs)146 ShallowHistoryImpl<Events,NumberOfRegions>& operator=(ShallowHistoryImpl<Events,NumberOfRegions> const& rhs) 147 { 148 for (int i=0; i<NumberOfRegions;++i) 149 { 150 m_initialStates[i] = rhs.m_initialStates[i]; 151 m_currentStates[i] = rhs.m_currentStates[i]; 152 } 153 return *this; 154 } 155 // the history policy keeps deferred events until next reentry if coming from our history event 156 template <class Event> process_deferred_events(Event const &) const157 bool process_deferred_events(Event const&)const 158 { 159 return ::boost::mpl::contains<Events,Event>::value; 160 } 161 template<class Archive> serialize(Archive & ar,const unsigned int)162 void serialize(Archive & ar, const unsigned int) 163 { 164 ar & m_initialStates; 165 ar & m_currentStates; 166 } 167 private: 168 int m_initialStates[NumberOfRegions]; 169 int m_currentStates[NumberOfRegions]; 170 }; 171 172 struct NoHistory 173 { 174 typedef int history_policy; 175 template <int NumberOfRegions> 176 struct apply 177 { 178 typedef NoHistoryImpl<NumberOfRegions> type; 179 }; 180 }; 181 struct AlwaysHistory 182 { 183 typedef int history_policy; 184 template <int NumberOfRegions> 185 struct apply 186 { 187 typedef AlwaysHistoryImpl<NumberOfRegions> type; 188 }; 189 }; 190 template <class Events> 191 struct ShallowHistory 192 { 193 typedef int history_policy; 194 template <int NumberOfRegions> 195 struct apply 196 { 197 typedef ShallowHistoryImpl<Events,NumberOfRegions> type; 198 }; 199 }; 200 } } }//boost::msm::back 201 #endif //BOOST_MSM_BACK_HISTORY_POLICIES_H 202