Chromium最近的代码库中, 增加了一个新模块<GPU>. 随便浏览了一下这个目录, 被 cmd_buffer_common.h和cmd_buffer_common.cc中的一个实用的小trick给吸引住了, 其功能就是定义一组枚举值, 同时提供了函数接口可以根据给定的枚举值获得相应的字符串名. 代码原理非常简单, 请参考以下详细代码片段:
cmd_buffer_common.h 部分:
// This macro is used to safely and convienently expand the list of commnad
// buffer commands in to various lists and never have them get out of sync. To
// add a new command, add it this list, create the corresponding structure below
// and then add a function in gapi_decoder.cc called Handle_COMMAND_NAME where
// COMMAND_NAME is the name of your command structure.
//
// NOTE: THE ORDER OF THESE MUST NOT CHANGE (their id is derived by order)
#define COMMON_COMMAND_BUFFER_CMDS(OP) \
OP(Noop) /* 0 */ \
OP(SetToken) /* 1 */ \
OP(Jump) /* 2 */ \
OP(JumpRelative) /* 3 */ \
OP(Call) /* 4 */ \
OP(CallRelative) /* 5 */ \
OP(Return) /* 6 */ \
OP(SetBucketSize) /* 7 */ \
OP(SetBucketData) /* 8 */ \
OP(SetBucketDataImmediate) /* 9 */ \
OP(GetBucketSize) /* 10 */ \
OP(GetBucketData) /* 11 */ \
// Common commands.
enum CommandId {
#define COMMON_COMMAND_BUFFER_CMD_OP(name) k ## name,
COMMON_COMMAND_BUFFER_CMDS(COMMON_COMMAND_BUFFER_CMD_OP)
#undef COMMON_COMMAND_BUFFER_CMD_OP
kNumCommands,
kLastCommonId = 255, // reserve 256 spaces for common commands.
};
cmd_buffer_common.cc 部分:
const char* GetCommandName(CommandId command_id) {
static const char* const names[] = {
#define COMMON_COMMAND_BUFFER_CMD_OP(name) # name,
COMMON_COMMAND_BUFFER_CMDS(COMMON_COMMAND_BUFFER_CMD_OP)
#undef COMMON_COMMAND_BUFFER_CMD_OP
};
int id = static_cast<int>(command_id);
return (id >= 0 && id < kNumCommands) ? names[id] : "*unknown-command*";
}
这种方法的后期维护代价是非常低的, 以后碰到需要用到这种功能的地方, 不妨尝试一下.