本篇是的
创建游戏内核(2)续篇,并且以
游戏程序流、状态处理机、进程管理器、数据包系统的实现中介绍的进程管理器的实现为基础。
栈上的每个函数在每帧都要被调用,除了这点小的不同之处,PROCESS_MANAGER和STATE_MANAGER非常相似。
以下是该类的定义:
//==========================================================================
// Defines for process manager.
//==========================================================================
class PROCESS_MANAGER
{
private:
struct PROCESS
{
FUNC_PTR func;
PROCESS* next;
PROCESS()
{
func = NULL;
next = NULL;
}
~PROCESS()
{
delete next;
next = NULL;
}
};
protected:
PROCESS* _process_parent;
public:
PROCESS_MANAGER();
~PROCESS_MANAGER();
void Push(FUNC_PTR func, void* data_ptr = NULL);
BOOL Pop(void* data_ptr = NULL);
void Pop_All(void* data_ptr = NULL);
void Process(void* data_ptr = NULL);
};
接着是它的实现:
//-----------------------------------------------------------------------------
// Constructor.
//-----------------------------------------------------------------------------
PROCESS_MANAGER::PROCESS_MANAGER()
{
_process_parent = NULL;
}
//-----------------------------------------------------------------------------
// Destructor, pop all functions.
//-----------------------------------------------------------------------------
PROCESS_MANAGER::~PROCESS_MANAGER()
{
// pop each process
while(Pop() == TRUE)
;
}
//-----------------------------------------------------------------------------
// Push a function on to the stack
//-----------------------------------------------------------------------------
void PROCESS_MANAGER::Push(FUNC_PTR func, void* data_ptr)
{
// don't push a NULL value
if(func != NULL)
{
// allocate a new process and push it on stack
PROCESS* process_ptr = new PROCESS();
process_ptr->func = func;
process_ptr->next = _process_parent;
_process_parent = process_ptr;
// call process with init purpose
process_ptr->func(data_ptr, INIT_PURPOSE);
}
}
//-----------------------------------------------------------------------------
// Pop top process from stack
//-----------------------------------------------------------------------------
BOOL PROCESS_MANAGER::Pop(void* data_ptr)
{
PROCESS* process_ptr;
// remove the head of stack (if any)
if((process_ptr = _process_parent) != NULL)
{
// first call with shutdown purpose
_process_parent->func(data_ptr, SHUTDOWN_PURPOSE);
_process_parent = process_ptr->next;
process_ptr->next = NULL;
delete process_ptr;
}
// return TRUE if more processes exist, FALSE otherwise
return (_process_parent != NULL);
}
//-----------------------------------------------------------------------------
// Pop all process.
//-----------------------------------------------------------------------------
void PROCESS_MANAGER::Pop_All(void* data_ptr)
{
while(Pop(data_ptr) == TRUE)
;
}
//-----------------------------------------------------------------------------
// Process all functions
//-----------------------------------------------------------------------------
void PROCESS_MANAGER::Process(void* data_ptr)
{
PROCESS* process_ptr = _process_parent;
while(process_ptr != NULL)
{
process_ptr->func(data_ptr, FRAME_PURPOSE);
process_ptr = process_ptr->next;
}
}
下面给出测试代码:
点击下载源码和工程
/*****************************************************************************
PURPOSE:
Test for class PROCESS_MANAGER.
*****************************************************************************/
#include "Core_System.h"
#pragma warning(disable : 4996)
class APP : public APPLICATION
{
private:
PROCESS_MANAGER _process_manager;
static void _Function1(void*, long);
static void _Function2(void*, long);
public:
BOOL Init()
{
_process_manager.Push(_Function1, this);
_process_manager.Push(_Function2, this);
return TRUE;
}
BOOL Frame()
{
_process_manager.Process(this);
_process_manager.Pop_All(this);
return TRUE;
}
};
void APP::_Function1(void* data_ptr, long purpose)
{
APP* app_inst = (APP*) data_ptr;
if(app_inst != NULL)
{
if(purpose == INIT_PURPOSE)
MessageBox(app_inst->Get_Hwnd(), "Process1 - init", "Message", MB_OK);
else if(purpose == FRAME_PURPOSE)
MessageBox(app_inst->Get_Hwnd(), "Process1 - frame", "Message", MB_OK);
else if(purpose == SHUTDOWN_PURPOSE)
MessageBox(app_inst->Get_Hwnd(), "Process1 - shutdown", "Message", MB_OK);
}
}
void APP::_Function2(void* data_ptr, long purpose)
{
APP* app_inst = (APP*) data_ptr;
if(app_inst != NULL)
{
if(purpose == INIT_PURPOSE)
MessageBox(app_inst->Get_Hwnd(), "Process2 - init", "Message", MB_OK);
else if(purpose == FRAME_PURPOSE)
MessageBox(app_inst->Get_Hwnd(), "Process2 - frame", "Message", MB_OK);
else if(purpose == SHUTDOWN_PURPOSE)
MessageBox(app_inst->Get_Hwnd(), "Process2 - shutdown", "Message", MB_OK);
}
}
int PASCAL WinMain(HINSTANCE inst, HINSTANCE, LPSTR cmd_line, int cmd_show)
{
APP app;
return app.Run();
}
运行截图: