本篇是创建游戏内核(1)【C风格版】的续篇,关于该内核的细节说明请参考创建游戏内核(2)。
接口:
/*************************************************************************
PURPOSE:
Interface for smanager stack.
*************************************************************************/
#ifndef _CORE_MANAGER_H_
#define _CORE_MANAGER_H_
#include "core_common.h"
enum PURPOSE
{
NO_PURPOSE = 0,
INIT_PURPOSE,
SHUTDOWN_PURPOSE,
FRAME_PURPOSE
};
typedef void (*MANAGER_FUNC)(void_ptr data, long purpose);
typedef struct MANAGER
{
MANAGER_FUNC func;
MANAGER* next;
} *MANAGER_PTR;
typedef MANAGER_PTR& MANAGER_PTR_REF;
MANAGER_PTR create_manager();
void push_manager(MANAGER_PTR_REF top_manager, MANAGER_FUNC func, void_ptr data);
BOOL pop_manager(MANAGER_PTR_REF top_manager, void_ptr data);
void destroy_all_manager(MANAGER_PTR top_manager, void_ptr data);
BOOL process_top_manager(MANAGER_PTR top_manager, void_ptr data);
void process_all_manager(MANAGER_PTR top_manager, void_ptr data);
#endif
实现:
/*************************************************************************
PURPOSE:
Implements for manager stack.
*************************************************************************/
#include "core_common.h"
#include "core_manager.h"
#pragma warning(disable : 4996)
//------------------------------------------------------------------------
// Create manager object.
//------------------------------------------------------------------------
MANAGER_PTR create_manager()
{
MANAGER_PTR manager = (MANAGER_PTR) malloc(sizeof(MANAGER));
memset(manager, 0, sizeof(MANAGER));
return manager;
}
//------------------------------------------------------------------------
// Push one manager function into manager stack.
//------------------------------------------------------------------------
void push_manager(MANAGER_PTR_REF top_manager, MANAGER_FUNC func, void_ptr data)
{
if(func == NULL)
return;
// allocate a new manager and push it into stack
MANAGER_PTR new_manager = (MANAGER_PTR) malloc(sizeof(MANAGER));
new_manager->func = func;
new_manager->next = top_manager;
top_manager = new_manager;
// call manager function with init purpose
new_manager->func(data, INIT_PURPOSE);
}
//------------------------------------------------------------------------
// Pop top manager object from manager stack.
//------------------------------------------------------------------------
BOOL pop_manager(MANAGER_PTR_REF top_manager, void_ptr data)
{
if(top_manager == NULL)
return FALSE;
// first call with shutdown purpose
top_manager->func(data, SHUTDOWN_PURPOSE);
// remove the head of stack (if any)
MANAGER_PTR manager_ptr = top_manager;
top_manager = top_manager->next;
free(manager_ptr);
return TRUE;
}
//------------------------------------------------------------------------
// Pop all manager function from stack.
//------------------------------------------------------------------------
void destroy_all_manager(MANAGER_PTR top_manager, void_ptr data)
{
while(pop_manager(top_manager, data))
;
}
//-----------------------------------------------------------------------------
// process top-most manager function.
//-----------------------------------------------------------------------------
BOOL process_top_manager(MANAGER_PTR top_manager, void_ptr data)
{
if(top_manager == NULL)
return FALSE;
// process the top-most manager function
top_manager->func(data, FRAME_PURPOSE);
return TRUE;
}
//-----------------------------------------------------------------------------
// Process all manager functions in stack.
//-----------------------------------------------------------------------------
void process_all_manager(MANAGER_PTR top_manager, void_ptr data)
{
MANAGER_PTR manager_ptr = top_manager;
while(manager_ptr)
{
manager_ptr->func(data, FRAME_PURPOSE);
manager_ptr = manager_ptr->next;
}
}
测试代码:
/*************************************************************************
PURPOSE:
Test for manager stack.
*************************************************************************/
#include "core_common.h"
#include "core_framework.h"
#include "core_manager.h"
MANAGER_PTR g_manager;
void func2(void* data, long purpose)
{
if(purpose == INIT_PURPOSE)
{
MessageBox(g_hwnd, (LPCSTR)data, "message", MB_OK);
pop_manager(g_manager, "shutdown state2");
pop_manager(g_manager, "shutdown state1");
}
else if(purpose == SHUTDOWN_PURPOSE)
{
MessageBox(g_hwnd, (LPCSTR)data, "message", MB_OK);
}
}
void func1(void* data, long purpose)
{
if(purpose == INIT_PURPOSE)
{
MessageBox(g_hwnd, (LPCSTR)data, "message", MB_OK);
push_manager(g_manager, func2, "init state2");
}
else if(purpose == SHUTDOWN_PURPOSE)
{
MessageBox(g_hwnd, (LPCSTR)data, "message", MB_OK);
}
}
BOOL game_init()
{
push_manager(g_manager, func1, "init state1");
return TRUE;
}
BOOL game_frame()
{
return TRUE;
}
BOOL game_shutdown()
{
destroy_manager(g_manager, NULL);
return TRUE;
}
//--------------------------------------------------------------------------------
// Main function, routine entry.
//--------------------------------------------------------------------------------
int WINAPI WinMain(HINSTANCE inst, HINSTANCE pre_inst, LPSTR cmd_line, int cmd_show)
{
if(! build_window(inst, "MainClass", "MainWindow", WS_OVERLAPPEDWINDOW, 0, 0, 800, 600))
return FALSE;
run_game(game_init, game_frame, game_shutdown);
return 0;
}