使用C++实现一套简单的状态机模型――原理解析(二)

2015-07-20 17:12:11 来源: 作者: 浏览: 6
States(){return false;}; void SetInitState( const std::string& strState ){}; public: virtual void Entry(){}; virtual std::string Exit(){return "";}; }; 该模板类使用第一个模板参数类的类名作为其继承类的状态,并使用GetCurrentState方法提供获取功能。比如上例中的状态名为class CSimpleState_Download_From_A。这个模板类继承于CLocalStoreAccess模板类,使得继承类具有可以“访问”第三个模板参数类――“数据库”类的能力――不具备“存储”能力。同时该类还暴露了两个方法――Entry和Exit,他们分别用于在进出该状态时,让状态机调用。
状态和存储类都介绍完了,我们就剩下调度状态变化的状态机类和复合状态类。其实从某种程度上说,复合状态是一种简单的状态机,它们在很多地方存在共性。我们从状态机类入口,进行讲解。首先看下上一文中的例子
class CMachine_Download_Run_App :
    public AutoStateChart::CAutoStateChartMachine
  
状态机类需要继承于CAutoStateChartMachine模板类,该类声明如下:
	template
  
   
	class CAutoStateChartMachine:
		public boost::enable_shared_from_this
   
    >, public CLocalStoreAccess
    
      { public: typedef LocalStore SelfStore; typedef T Self; public: CAutoStateChartMachine(){m_spStore.reset();}; virtual ~CAutoStateChartMachine(){}; private: virtual bool Transition(){return false;}; public: void StartMachine() { if ( !m_spStore ) { m_spStore = boost::make_shared
     
      >(); m_spStore->Init(); SetStore( m_spStore->m_pFunc ); } while( Transition()){}; }; private: void Init(){}; public: bool IsCompositeStates(){return false;}; protected: std::string m_strCurrentState; std::string m_strCondition; MapString m_MapCompositeStatesSubState; boost::shared_ptr
      
       > m_spStore; };
      
     
    
   
  
我们先看下这个类的成员变量。m_strCurrentState保存了状态机在跳转中的当前状态,m_strCondition保存了状态机中当前状态之前的状态的输出,它用于决定状态跳转方向。m_MapCompositeStatesSubState用于保存状态机中离开复合状态时的最后状态,即它记录复合状态机的浅历史。m_spStore指向“数据库”类对象。
该模板类最重要的函数就是StartMachine,它在第一次被调用时创建了“数据库”类对象。然后死循环调用Transition方法。Tansition方法是个虚方法,它是整个模型的核心。状态机类需要实现自己的Transition方法,以使得状态机可以运转起来。

我们再看下复合状态类的基础模板

	template
  
   
	class CCompositeStates:
		public CAutoStateChartBase
   
    { BOOST_TYPEOF_REGISTER_TYPE(T) public: CCompositeStates(){}; ~CCompositeStates(){}; private: virtual bool Transition(){return false;}; public: virtual void Entry(){while(Transition());}; virtual std::string Exit(){return m_strCondition;}; public: std::string GetCurrentState(){return m_strCurrentState;}; bool IsCompositeStates(){return true;}; void SetInitState( const std::string& strState ){ m_strCurrentState = strState; }; protected: std::string m_strCurrentState; std::string m_strCondition; MapString m_MapCompositeStatesSubState; };
   
  
因为复合状态也是一种状态,所以它也要有Entry和Exit两种方法。而其Entry方法就是调用Transition方法。该模板类的Transition方法也是虚方法,这意味着继承于该模板类的方法也要去实现Transition。
于是所有的重心都集中于Transition方法的实现。
为了让代码美观,我参考了MFC中使用宏简洁代码的思路,设计了如下的宏:
#define STARTSTATE(state)														\
	do {																		\
		boost::shared_ptr
  
    sp = boost::make_shared
   
    (); \ sp->SetStore( m_pFunc ); \ if ( sp->IsCompositeStates() ) { \ std::string strState = typeid(state).name(); \ BOOST_AUTO(it, m_MapCompositeStatesSubState.find(strState)); \ if ( m_MapCompositeStatesSubState.end() != it ) { \ sp->SetInitState(it->second); \ if ( DEBUGFRAMEFLAG ) { \ std::string strInitState = it->second; \ std::cout<<"CompositeStates SetInitState:"<
    
     Entry(); \ m_strCondition = sp->Exit(); \ if ( sp->IsCompositeStates() ) { \ std::string strState = typeid(state).name(); \ std::string strInnerState = sp->GetCurrentState(); \ m_MapCompositeStatesSubState[strState] = strInnerState; \ if ( DEBUGFRAMEFLAG ) { \ std::cout<<"CompositeStates SaveState:"<
     
       然后复合状态类和状态机类只要使用这些宏去组织状态跳转,就可以清晰的描述过程了。
      

-->

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: