X-Macro(X 宏)案例解析 X-Macro 模式解读这是 C/C 中经典的X-Macro技术核心思想是一份数据定义多种用途展开。数据源唯一真源在 light_strip_config.h 中LIGHT_SCENE_STRIP_CONFIGS 是所有灯条配置的唯一列表#defineLIGHT_SCENE_STRIP_CONFIGS(X)\X(LIGHT_STRIP_FRONT_MAIN,FRONT_MAIN_LIGHT_WS2812FX,FRONT_MAIN_LIGHT_NUMS,kMaskBaseAnimSignal)\X(LIGHT_STRIP_FRONT_GRILLE_SIDE,...)\X(LIGHT_STRIP_MIRROR,...)\...共21条...它本身不生成任何代码——它只是接收一个操作符然后对每条灯带调用一次 X(灯带ID, 灯带对象, 灯带LED数, 层掩码)。三次不同展开在 light_scene_manager.cpp 中同一个数据源被用作三种不同的用途用途1构建配置数组#defineLIGHT_SCENE_CONFIG_ENTRY(strip_id,strip_obj,strip_len,strip_mask)\{strip_obj,strip_len,strip_mask},staticStripConfig kStripConfigs[LIGHT_STRIP_COUNT]{LIGHT_SCENE_STRIP_CONFIGS(LIGHT_SCENE_CONFIG_ENTRY)// X LIGHT_SCENE_CONFIG_ENTRY};#undefLIGHT_SCENE_CONFIG_ENTRY展开后等价于staticStripConfig kStripConfigs[21]{{FRONT_MAIN_LIGHT_WS2812FX,FRONT_MAIN_LIGHT_NUMS,kMaskBaseAnimSignal},{FRONT_GRILLE_SIDE_WS2812FX,FRONT_GRILLE_SIDE_NUMS,kMaskBaseAnimSignal},// ... 共21条};用途2统计总像素数#defineLIGHT_SCENE_PIXEL_SUM(strip_id,strip_obj,strip_len,strip_mask)(strip_len)constuint16_tkTotalScenePixels0LIGHT_SCENE_STRIP_CONFIGS(LIGHT_SCENE_PIXEL_SUM);// ↑ 初始值0// ↑ 然后展开为 (灯珠数1) (灯珠数2) ... 总和用途3统计 active byte 总数#defineLIGHT_SCENE_ACTIVE_BYTE_SUM(strip_id,strip_obj,strip_len,strip_mask)activeByteCount(strip_len)constuint16_tkTotalSceneActiveBytes0LIGHT_SCENE_STRIP_CONFIGS(LIGHT_SCENE_ACTIVE_BYTE_SUM);为什么这么写优势说明单一数据源增删改灯带只改 light_strip_config.h 一处编译时计算数组大小、像素总数都在编译期确定零运行时开销不会遗漏数组、统计量、后续可能的其他展开都自动覆盖所有灯带简单说LIGHT_SCENE_STRIP_CONFIGS 是数据菜单而三次#define … #undef是三个不同的厨师拿着同一份菜单做出三道不同的菜。