// Test.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
using namespace std;
class CEventBase
{
virtual void dummy(){};
};
class CStateBase
{
public:
virtual void next(CEventBase * e){}
};
#define DEFINE_STATE(state) template <typename T>\
class state : public CStateBase\
{\
public:\
T*t;\
state(T*_t){t = _t;}\
void next(CEventBase * e)\
{\
#define ACCEPT_EVENT_AND_NEWSTATE(evnt,newstate) if (dynamic_cast<evnt*>(e) != nullptr)\
{\
t->doStateChange(this, dynamic_cast<evnt*>(e));\
t->setNewState( new newstate<T>(t));\
} \
#define END_DEFINE_STATE }\
};\
class CMyObject
{
public:
CMyObject(){m_nowState = nullptr;}
CMyObject(CStateBase*s){m_nowState = s;}
CStateBase * m_nowState;
void processEvent(CEventBase * e)
{
if (m_nowState)
{
m_nowState->next(e);
}
}
void setNewState(CStateBase*s)
{
if (m_nowState)
{
delete m_nowState;
}
m_nowState = s;
}
};
//////////////////////////////////////////////////////////////////////////
//user defined objects, events and states from here
/////////////////////////////////////////////////////////////////////////
以下是测试,实现如下状态转移图:
/////////////////event definition
class CEventA : public CEventBase{};
class CEventB : public CEventBase{};
class CEventC : public CEventBase{};
class CEventD : public CEventBase{};
class CEventE : public CEventBase{};
class CEventF : public CEventBase{};
////////////////class definition with path diagram
DEFINE_STATE(CState1)
ACCEPT_EVENT_AND_NEWSTATE(CEventA,CState2)
ACCEPT_EVENT_AND_NEWSTATE(CEventB,CState3)
END_DEFINE_STATE
DEFINE_STATE(CState2)
ACCEPT_EVENT_AND_NEWSTATE(CEventC,CState2)
END_DEFINE_STATE
DEFINE_STATE(CState3)
ACCEPT_EVENT_AND_NEWSTATE(CEventD,CState4)
ACCEPT_EVENT_AND_NEWSTATE(CEventF,CState5)
END_DEFINE_STATE
DEFINE_STATE(CState4)
ACCEPT_EVENT_AND_NEWSTATE(CEventE,CState5)
END_DEFINE_STATE
DEFINE_STATE(CState5)
END_DEFINE_STATE
////////////////object definition
class CMySprite : public CMyObject
{
public:
CMySprite():CMyObject(new CState1<CMySprite>(this)){}
void doStateChange(CState1<CMySprite>*oldstate, CEventA *e)
{
cout<<"CState1 with CEventA to CState2"<<endl;
}
void doStateChange(CState1<CMySprite>*oldstate, CEventB *e)
{
cout<<"CState1 with CEventB to CState3"<<endl;
}
void doStateChange(CState2<CMySprite>*oldstate, CEventC *e)
{
cout<<"CState2 with CEventC to CState2"<<endl;
}
void doStateChange(CState3<CMySprite>*oldstate, CEventD *e)
{
cout<<"CState3 with CEventD to CState4"<<endl;
}
void doStateChange(CState3<CMySprite>*oldstate, CEventF *e)
{
cout<<"CState3 with CEventF to CState5"<<endl;
}
void doStateChange(CState4<CMySprite>*oldstate, CEventE *e)
{
cout<<"CState4 with CEventE to CState5"<<endl;
}
};
void proceed(CMyObject * o,CEventBase * e)
{
o->processEvent(e);
delete e;
}
int main()
{
CMyObject * o = new CMySprite();
proceed(o,new CEventB());
proceed(o,new CEventD());
proceed(o,new CEventA());
proceed(o,new CEventE());
proceed(o,new CEventE());
delete o;
return 0;
}