/** ********************************************************************************************************************** * @file menu_event.c * @brief 菜单组件事件队列实现 * @author menu_component * @date 2025-12-19 ********************************************************************************************************************** */ /* Includes ----------------------------------------------------------------------------------------------------------*/ #include "menu_types.h" /* 函数实现 ---------------------------------------------------------------------------------------------------------*/ /** * @brief 初始化事件队列 * @param queue 事件队列指针 */ void menu_event_queue_init(MenuEventQueue* queue) { MENU_ASSERT(queue != NULL); queue->head = 0; queue->tail = 0; queue->count = 0; queue->reserved = 0; } /** * @brief 检查事件队列是否为空 * @param queue 事件队列指针 * @return true为空,false不为空 */ bool menu_event_queue_is_empty(const MenuEventQueue* queue) { MENU_ASSERT(queue != NULL); return (queue->count == 0); } /** * @brief 检查事件队列是否已满 * @param queue 事件队列指针 * @return true已满,false未满 */ bool menu_event_queue_is_full(const MenuEventQueue* queue) { MENU_ASSERT(queue != NULL); return (queue->count >= MENU_CONFIG_EVENT_QUEUE_LEN); } /** * @brief 获取事件队列中的元素数量 * @param queue 事件队列指针 * @return 元素数量 */ uint8_t menu_event_queue_get_count(const MenuEventQueue* queue) { MENU_ASSERT(queue != NULL); return queue->count; } /** * @brief 向事件队列添加事件 * @param queue 事件队列指针 * @param event 要添加的事件 * @return 错误码 */ MenuErrCode menu_event_queue_push(MenuEventQueue* queue, const MenuEvent* event) { MENU_ASSERT(queue != NULL); MENU_ASSERT(event != NULL); // 检查事件优先级是否合法 if (event->priority >= MENU_CONFIG_EVENT_MAX_PRIORITY) { return MENU_ERR_INVALID_PARAM; } if (menu_event_queue_is_full(queue)) { // 队列已满,替换低优先级事件 uint8_t lowest_prio = 0; uint8_t lowest_idx = queue->head; // 找到最低优先级的事件 for (uint8_t i = 0; i < MENU_CONFIG_EVENT_QUEUE_LEN; i++) { uint8_t idx = (queue->head + i) % MENU_CONFIG_EVENT_QUEUE_LEN; if (queue->buffer[idx].priority > lowest_prio) { lowest_prio = queue->buffer[idx].priority; lowest_idx = idx; } } // 替换最低优先级事件 queue->buffer[lowest_idx] = *event; return MENU_ERR_OK; } // 队列未满,添加到队尾 queue->buffer[queue->tail] = *event; queue->tail = (queue->tail + 1) % MENU_CONFIG_EVENT_QUEUE_LEN; queue->count++; return MENU_ERR_OK; } /** * @brief 从事件队列获取下一个事件 * @param queue 事件队列指针 * @param event 用于存储获取的事件 * @return 错误码 */ MenuErrCode menu_event_queue_pop(MenuEventQueue* queue, MenuEvent* event) { MENU_ASSERT(queue != NULL); MENU_ASSERT(event != NULL); if (menu_event_queue_is_empty(queue)) { return MENU_ERR_QUEUE_EMPTY; } // 寻找最高优先级的事件 uint8_t highest_prio = MENU_CONFIG_EVENT_MAX_PRIORITY; uint8_t highest_idx = queue->head; for (uint8_t i = 0; i < queue->count; i++) { uint8_t idx = (queue->head + i) % MENU_CONFIG_EVENT_QUEUE_LEN; if (queue->buffer[idx].priority < highest_prio) { highest_prio = queue->buffer[idx].priority; highest_idx = idx; } } // 取出最高优先级事件 *event = queue->buffer[highest_idx]; // 移除该事件,将后续事件前移 for (uint8_t i = highest_idx; i != queue->tail; i = (i + 1) % MENU_CONFIG_EVENT_QUEUE_LEN) { uint8_t next_idx = (i + 1) % MENU_CONFIG_EVENT_QUEUE_LEN; if (next_idx == queue->tail) { break; } queue->buffer[i] = queue->buffer[next_idx]; } // 更新队列状态 if (queue->tail > 0) { queue->tail--; } else { queue->tail = MENU_CONFIG_EVENT_QUEUE_LEN - 1; } queue->count--; return MENU_ERR_OK; } /** * @brief 清空事件队列 * @param queue 事件队列指针 */ void menu_event_queue_clear(MenuEventQueue* queue) { MENU_ASSERT(queue != NULL); queue->head = 0; queue->tail = 0; queue->count = 0; } /** * @brief 向事件队列推送一个简单事件 * @param core_ctx 菜单核心上下文 * @param type 事件类型 * @param priority 事件优先级 * @return 错误码 */ MenuErrCode menu_core_post_event(struct MenuCoreCtx* core_ctx, MenuEventType type, uint8_t priority) { MenuEvent event; event.type = type; event.priority = priority; event.target_node_id = core_ctx->current_node_id; event.data = NULL; event.timestamp = core_ctx->last_refresh_tick; return menu_event_queue_push(&core_ctx->event_queue, &event); }