1.2 State Processing with cStateManager(用cStateManager处理状态)
这个状态管理类(state Manager)引入连个概念:调用目的(calling purposes)和在函数中加入一个用户自定义数据指针(。。。不懂吧,看程序理解吧)。
NOTE:调用目的(Calling Purposes),就像它的名字一样,调用原因是一个状态被调用。其中的“purposes”可以是INITPURPOSE (发送一个程序初始化的信号),FRAMEPURPOSE(用来处理一个独立的框架),SHUTDOWNPURPOSE(当处理完毕用来释放所有资源) PS 。 这个cStateManager和下面那个什么Manager我都没怎么详细用过。翻译的忒差劲。 |
下面是cStateManager类的声明:
class cStateManager { // 状态函数指针(链表) typedef struct sState { void (*Function)(void *Ptr, long Purpose); sState *Next; // 构造结构体,清空链表 sState() { Function = NULL; Next = NULL; } // 析构函数,删除链表 ~sState() { delete Next; } } sState;
protected: sState *m_StateParent; // 状态栈,父链表
public: cStateManager(); // 构造函数 ~cStateManager(); // 析构函数 // 在栈中导入一个状态, 除了一个 // 用户自定义的指针.这个Push函数将会调用一个包含一个初始化Purpose的state函数 void Push(void (*Function)(void *Ptr, long Purpose), / void *DataPtr = NULL); // 导出栈,,用一个shutdown purpose调用他 BOOL Pop(void *DataPtr = NULL); // 导出所有状态,每一个都调用SHUTDOWN purpose void PopAll(void *DataPtr = NULL); // 使用一个 frame purpose.处理栈顶状态 BOOL Process(void *DataPtr = NULL); }; |
刚开始使用cStateManager类看起来挺奇怪的(特别是这个purposes),但是不用担心,下面将是一个例子。看看这个例子,它是基于先前的cApplication:
Class cApp : public cApplication { Private: cStateManager m_StateManager; // 状态函数原型 Static void Function1(void *, long); Static void Function2(void *, long);
Public: BOOL Init() { m_StateManager.Push(Function1, this);} } |
Void cApp::Function1(void *DataPtr, long Purpose) { // 获得调用类的指针,因为这个函数是静态的, // 所以意味着他将不能被分配一个类实例 cApp *cc = (cApp*)DataPtr;
// 用INIT显示一条信息,并将第二个状态导入 If(Purposer == INITPURPOSE) { MessageBos(cc->GethWnd(), “State 1”, “Message”, MB_OK); cc->m_StateManager.Push(Function2, cc); return; }
// 强行退出程序 If(Purpose == FRAMEPURPOSE) cc->m_StateManager.Pop(cc); } |
Void cApp :: Function2(void *DataPtr, long Purpose) { cApp *cc = (cApp*)DataPtr;
// 显示一条消息并导出(pop)他自己 If(Purpose == FRAMEPURPOSE) { MessageBox(cc->GethWnd(), “State 2”, “Message”, MB_OK); cc->m_StateManager.Pop(cc); return ; } } |
一次运行,cApp类竟会把这个状态函数(Function1)导入到栈中。一次导入,Function1状态函数就被调用,使用一个初始化purpose,它将会导致Function1导入第二个状态函数(Function2)。当使用一个frame purpose时Function2函数将被调用,显示一条消息,状态导出(pop),执行结束。
注意附加的用户自定义数据有一个purpose,因为你必须在类中用static定义状态函数(否则程序将不会通过编译),你需要通过一个指针指向状态函数,因为状态函数仍然是这个类的以部分,状态函数可以使用指针自由的存取类数据(包括private数据)