宏定義在遊戲日誌枚舉中的應用

1 遇到的問題

在遊戲開發過程中是要記錄一些玩家日誌的,以便分析一些玩家的行爲。當開發過程中使用腳本和C++語言開發時,又需要使用同一套日誌id。
通常的做法是這樣的,建立日誌的枚舉字符串對應關係,然後通過字符串的唯一id建立字符串數組,在使用時通過日誌枚舉取的日誌字符串

2 補充一點小知識

c++ 中的 “#”表示宏處理,但是在宏處理中出現“#”表示取字符串本身,例:

#define NAME(val) #val
NAME(hello); // 這裏預處理之後相當於 “hello”

“##”在宏處理中出現表示,字符串的連接,例:

#define CONNECT(a, b) (#a)##(#b)
CONNECT(hello, world); //這裏再預處理之後相當於 "helloworld"

3 在日誌定義中巧妙的使用宏處理

//LogDef.h
#ifndef _LOG_DEF_H_
#define _LOG_DEF_H_

#if !defined(LOG_DEF)
	#define LOG_DEF(val, log) val, 		// 定義 LOG_DEF 的宏定義
	#define  LOG_DEF_ENUM  				// 定義LOG_DEF_ENUM 的宏定義
	
	enum {
#endif
	LOG_DEF(LT_LogIn, LogIn)			// 這一部分是日誌枚舉的定義部分
 	LOG_DEF(LT_LogOut, LogOut)			// 這一部分是日誌枚舉的定義部分

#if defined(LOG_DEF_ENUM)
	#undef LOG_DEF_ENUM			// 取消對LOG_DEF_ENUM 的宏定義
	#undef LOG_DEF				// 取消對LOG_DEF	的宏定義
	LOG_DEF_MAX					// 日誌枚舉定義的最大值
};
#endif

#endif
//LogDef.cpp
#include "LogDef.h"

// 日誌定義結構體
struct SLogDef
{
	const char* str;
	const char* strlog;
};

static const SLogDef logdef_list[] = {
	#undef  _LOG_DEF_H_ 							// 取消對 _LOG_DEF_H_ 的宏定義
	#define LOG_DEF(val, strlog){#val, #strlog},	// 定義 LOG_DEF 的宏定義
	#include "LogDef.h"								// 重新編譯 LogDef.h 文件,這裏注意當前文件的 LOG_DEF 宏定義替換了 LogDef.h 中的宏定義
	#undef LOG_DEF									// 編譯完,取消 LOG_DEF 的宏定義,這裏生成了 SLogDef logdef_list數組
};

// 獲取日誌字符串
const char* log_string(int log_type)
{
	if (log_type < 0 || log_type >= LOG_DEF_MAX)
	{
		return "WrongType";
	}
	return logdef_list[log_type].strlog;
}

這樣在編譯之後生成的文件如下

//LogDef.h
#ifndef _LOG_DEF_H_
#define _LOG_DEF_H_

enum {
	LT_LogIn, 			// 這一部分是日誌枚舉的定義部分
 	LT_LogOut, 			// 這一部分是日誌枚舉的定義部分
	LOG_DEF_MAX			// 日誌枚舉定義的最大值
};

#endif
//LogDef.cpp

struct SLogDef
{
	const char* str;
	const char* strlog;
};

static const SLogDef logdef_list[] = {
	{"LT_LogIn", "LogIn"},
	{"LT_LogOut", "LogOut"},
};

// 獲取日誌字符串
const char* log_string(int log_type)
{
	if (log_type < 0 || log_type >= LOG_DEF_MAX)
	{
		return "WrongType";
	}
	return logdef_list[log_type].strlog;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章