You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and dots ('.'), can be up to 35 characters long. Letters must be lowercase.
182 lines
5.0 KiB
182 lines
5.0 KiB
// 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 |
|
{ |
|
typedef int history_policy; |
|
template <int NumberOfRegions> |
|
struct apply |
|
{ |
|
typedef NoHistoryImpl<NumberOfRegions> type; |
|
}; |
|
}; |
|
struct AlwaysHistory |
|
{ |
|
typedef int history_policy; |
|
template <int NumberOfRegions> |
|
struct apply |
|
{ |
|
typedef AlwaysHistoryImpl<NumberOfRegions> type; |
|
}; |
|
}; |
|
template <class Events> |
|
struct ShallowHistory |
|
{ |
|
typedef int history_policy; |
|
template <int NumberOfRegions> |
|
struct apply |
|
{ |
|
typedef ShallowHistoryImpl<Events,NumberOfRegions> type; |
|
}; |
|
}; |
|
} } }//boost::msm::back |
|
#endif //BOOST_MSM_BACK_HISTORY_POLICIES_H
|
|
|