| // Copyright 2008 Christophe Henry |
| // henry UNDERSCORE christophe AT hotmail DOT com |
| // This is an extended version of the state machine available in the boost::mpl library |
| // Distributed under the same license as the original. |
| // Copyright for the original version: |
| // Copyright 2005 David Abrahams and Aleksey Gurtovoy. Distributed |
| // under the Boost Software License, Version 1.0. (See accompanying |
| // file LICENSE_1_0.txt or copy at |
| // http://www.boost.org/LICENSE_1_0.txt) |
| |
| #ifndef BOOST_MSM_BACK_HISTORY_POLICIES_H |
| #define BOOST_MSM_BACK_HISTORY_POLICIES_H |
| |
| #include <boost/mpl/contains.hpp> |
| |
| namespace boost { namespace msm { namespace back |
| { |
| |
| // policy classes |
| |
| // Default: no history used |
| template <int NumberOfRegions> |
| class NoHistoryImpl |
| { |
| public: |
| NoHistoryImpl(){} |
| ~NoHistoryImpl(){} |
| void set_initial_states(int* const initial_states) |
| { |
| for (int i=0;i<NumberOfRegions;++i) |
| m_initialStates[i] = initial_states[i]; |
| } |
| void history_exit(int* const ) |
| { |
| // ignore |
| } |
| // returns the state where the state machine should be at start |
| template <class Event> |
| const int* history_entry(Event const& ) |
| { |
| // always come back to the original state |
| return m_initialStates; |
| } |
| NoHistoryImpl<NumberOfRegions>& operator=(NoHistoryImpl<NumberOfRegions> const& rhs) |
| { |
| for (int i=0; i<NumberOfRegions;++i) |
| { |
| m_initialStates[i] = rhs.m_initialStates[i]; |
| } |
| return *this; |
| } |
| template<class Archive> |
| void serialize(Archive & ar, const unsigned int) |
| { |
| ar & m_initialStates; |
| } |
| private: |
| int m_initialStates[NumberOfRegions]; |
| }; |
| |
| // not UML standard. Always activates history, no matter which event generated the transition |
| template <int NumberOfRegions> |
| class AlwaysHistoryImpl |
| { |
| public: |
| AlwaysHistoryImpl(){} |
| ~AlwaysHistoryImpl(){} |
| void set_initial_states(int* const initial_states) |
| { |
| for (int i=0;i<NumberOfRegions;++i) |
| m_initialStates[i] = initial_states[i]; |
| } |
| void history_exit(int* const current_states) |
| { |
| for (int i=0;i<NumberOfRegions;++i) |
| m_initialStates[i] = current_states[i]; |
| } |
| // returns the state where the state machine should be at start |
| template <class Event> |
| const int* history_entry(Event const& ) |
| { |
| // always load back the last active state |
| return m_initialStates; |
| } |
| AlwaysHistoryImpl<NumberOfRegions>& operator=(AlwaysHistoryImpl<NumberOfRegions> const& rhs) |
| { |
| for (int i=0; i<NumberOfRegions;++i) |
| { |
| m_initialStates[i] = rhs.m_initialStates[i]; |
| } |
| return *this; |
| } |
| template<class Archive> |
| void serialize(Archive & ar, const unsigned int) |
| { |
| ar & m_initialStates; |
| } |
| private: |
| int m_initialStates[NumberOfRegions]; |
| }; |
| |
| // UML Shallow history. For deep history, just use this policy for all the contained state machines |
| template <class Events,int NumberOfRegions> |
| class ShallowHistoryImpl |
| { |
| public: |
| ShallowHistoryImpl(){} |
| ~ShallowHistoryImpl(){} |
| void set_initial_states(int* const initial_states) |
| { |
| for (int i=0;i<NumberOfRegions;++i) |
| { |
| m_currentStates[i] = initial_states[i]; |
| m_initialStates[i] = initial_states[i]; |
| } |
| } |
| void history_exit(int* const current_states) |
| { |
| for (int i=0;i<NumberOfRegions;++i) |
| m_currentStates[i] = current_states[i]; |
| } |
| // returns the state where the state machine should be at start |
| template <class Event> |
| const int* history_entry(Event const&) |
| { |
| if ( ::boost::mpl::contains<Events,Event>::value) |
| { |
| return m_currentStates; |
| } |
| // not one of our events, no history |
| return m_initialStates; |
| } |
| ShallowHistoryImpl<Events,NumberOfRegions>& operator=(ShallowHistoryImpl<Events,NumberOfRegions> const& rhs) |
| { |
| for (int i=0; i<NumberOfRegions;++i) |
| { |
| m_initialStates[i] = rhs.m_initialStates[i]; |
| m_currentStates[i] = rhs.m_currentStates[i]; |
| } |
| return *this; |
| } |
| template<class Archive> |
| void serialize(Archive & ar, const unsigned int) |
| { |
| ar & m_initialStates; |
| ar & m_currentStates; |
| } |
| private: |
| int m_initialStates[NumberOfRegions]; |
| int m_currentStates[NumberOfRegions]; |
| }; |
| |
| struct NoHistory |
| { |
| template <int NumberOfRegions> |
| struct apply |
| { |
| typedef NoHistoryImpl<NumberOfRegions> type; |
| }; |
| }; |
| struct AlwaysHistory |
| { |
| template <int NumberOfRegions> |
| struct apply |
| { |
| typedef AlwaysHistoryImpl<NumberOfRegions> type; |
| }; |
| }; |
| template <class Events> |
| struct ShallowHistory |
| { |
| template <int NumberOfRegions> |
| struct apply |
| { |
| typedef ShallowHistoryImpl<Events,NumberOfRegions> type; |
| }; |
| }; |
| } } }//boost::msm::back |
| #endif //BOOST_MSM_BACK_HISTORY_POLICIES_H |