本篇是创建游戏内核(1)【OO改良版】的续篇,关于该内核的细节说明请参阅创建游戏内核(2)。
接口:
/*************************************************************************
PURPOSE:
Interface for manager stack.
*************************************************************************/
#ifndef _CORE_MANAGER_H_
#define _CORE_MANAGER_H_
enum PURPOSE
{
NO_PURPOSE = 0,
INIT_PURPOSE,
SHUTDOWN_PURPOSE,
FRAME_PURPOSE
};
typedef void (*MANAGER_FUNC)(void* data, long purpose);
typedef struct S_MANAGER
{
MANAGER_FUNC func;
S_MANAGER* next;
} *S_MANAGER_PTR;
class MANAGER
{
public:
MANAGER();
~MANAGER();
void push(MANAGER_FUNC func, void* data);
BOOL pop(void* data);
void pop_all(void* data);
BOOL process_top(void* data);
void process_all(void* data);
private:
S_MANAGER_PTR m_root;
};
typedef MANAGER* MANAGER_PTR;
#endif
实现:
/*************************************************************************
PURPOSE:
Implements for manager stack.
*************************************************************************/
#include "core_common.h"
#include "core_manager.h"
//-----------------------------------------------------------------------------
// Constructor, initialize member data.
//-----------------------------------------------------------------------------
MANAGER::MANAGER()
{
m_root = NULL;
}
//-----------------------------------------------------------------------------
// Destructor, pop off all functions.
//-----------------------------------------------------------------------------
MANAGER::~MANAGER()
{
pop_all(NULL);
}
//-----------------------------------------------------------------------------
// push a function on to the stack.
//-----------------------------------------------------------------------------
void MANAGER::push(MANAGER_FUNC func, void* data)
{
// do not push NULL value
if(func == NULL)
return;
// allocate a new state and push in into stack
S_MANAGER_PTR _manager = new S_MANAGER();
_manager->func = func;
_manager->next = m_root;
m_root = _manager;
// call manager function with init purpose
func(data, INIT_PURPOSE);
}
//-----------------------------------------------------------------------------
// pop a function off the stack.
//-----------------------------------------------------------------------------
BOOL MANAGER::pop(void* data)
{
S_MANAGER_PTR _manager;
// remove the head of stack if any
if((_manager = m_root) != NULL)
{
// first call with shutdown purpose
_manager->func(data, SHUTDOWN_PURPOSE);
m_root = m_root->next;
_manager->next = NULL;
delete _manager;
}
// return TRUE if more manager exist, FALSE otherwise.
return (m_root != NULL);
}
//-----------------------------------------------------------------------------
// pop all managers off the stack.
//-----------------------------------------------------------------------------
void MANAGER::pop_all(void* data)
{
while(pop(data))
;
}
//-----------------------------------------------------------------------------
// process top-most manager.
//-----------------------------------------------------------------------------
BOOL MANAGER::process_top(void* data)
{
// return an error if no more managers
if(m_root == NULL)
return FALSE;
// process the top-most manager
m_root->func(data, FRAME_PURPOSE);
return TRUE;
}
//-----------------------------------------------------------------------------
// process all managers.
//-----------------------------------------------------------------------------
void MANAGER::process_all(void* data)
{
S_MANAGER_PTR _manager = m_root;
while(_manager)
{
_manager->func(data, FRAME_PURPOSE);
_manager = _manager->next;
}
}
测试代码:
/*****************************************************************************
PURPOSE:
Test for class FRAMEWORK.
*****************************************************************************/
#include "core_common.h"
#include "core_framework.h"
#include "core_manager.h"
class APP : public FRAMEWORK
{
public:
static void func2(void* data, long purpose)
{
APP* app_inst = (APP*) data;
if(purpose == INIT_PURPOSE)
{
MessageBox(g_hwnd, "init state2", "message", MB_OK);
app_inst->m_manager.process_top(app_inst);
app_inst->m_manager.pop(app_inst);
app_inst->m_manager.pop(app_inst);
}
else if(purpose == FRAME_PURPOSE)
{
MessageBox(g_hwnd, "frame state2", "message", MB_OK);
}
else if(purpose == SHUTDOWN_PURPOSE)
{
MessageBox(g_hwnd, "shutdown state2", "message", MB_OK);
}
}
static void func1(void* data, long purpose)
{
APP* app_inst = (APP*) data;
if(purpose == INIT_PURPOSE)
{
MessageBox(g_hwnd, "init state1", "message", MB_OK);
app_inst->m_manager.process_top(app_inst);
app_inst->m_manager.push(func2, app_inst);
}
else if(purpose == FRAME_PURPOSE)
{
MessageBox(g_hwnd, "frame state1", "message", MB_OK);
}
else if(purpose == SHUTDOWN_PURPOSE)
{
MessageBox(g_hwnd, "shutdown state1", "message", MB_OK);
}
}
BOOL init()
{
m_manager.push(func1, this);
return TRUE;
}
private:
MANAGER m_manager;
};
//--------------------------------------------------------------------------------
// Main function, routine entry.
//--------------------------------------------------------------------------------
int WINAPI WinMain(HINSTANCE inst, HINSTANCE pre_inst, LPSTR cmd_line, int cmd_show)
{
APP app;
if(! build_window(inst, "MainClass", "MainWindow", WS_OVERLAPPEDWINDOW, 0, 0, 640, 480))
return -1;
app.run();
return 0;
}