/** ********************************************************************************************************************** * @file menu_api.c * @brief 菜单组件对外API接口实现 * @author menu_component * @date 2025-12-19 ********************************************************************************************************************** */ /* Includes ----------------------------------------------------------------------------------------------------------*/ #include "menu_api.h" #include "../src/core/menu_core.h" #include "../src/core/menu_event.h" #include "../src/core/menu_hash.h" /* 函数实现 ---------------------------------------------------------------------------------------------------------*/ /* 菜单初始化与反初始化 ---------------------------------------------------------------------------------------------*/ MenuErrCode menu_init(void) { return menu_core_init(); } MenuErrCode menu_deinit(void) { return menu_core_deinit(); } /* 菜单节点管理 -----------------------------------------------------------------------------------------------------*/ MenuNodeId menu_register_node(MenuNodeId node_id, MenuNodeId parent_id, const char* name, MenuCallback enter_cb, MenuCallback exit_cb) { // 参数验证 if (name == NULL) { return 0; // 保持原有API兼容,0表示注册失败 } // 调用核心层的节点注册功能 return menu_core_register_node(node_id, parent_id, name, enter_cb, exit_cb); } MenuErrCode menu_register_nodes(const struct MenuNode* nodes, uint16_t count) { // 暂未实现批量注册功能 (void)nodes; (void)count; return MENU_ERR_OPERATION_FAILED; } MenuErrCode menu_unregister_node(MenuNodeId node_id) { // 调用核心层的节点注销功能 return menu_core_unregister_node(node_id); } MenuErrCode menu_update_node(MenuNodeId node_id, const char* name, MenuCallback enter_cb, MenuCallback exit_cb) { MenuCoreCtx* core_ctx = menu_get_core_ctx(); MenuNode* node = menu_hash_find(core_ctx, node_id); if (node == NULL || !node->flags.is_registered) { return MENU_ERR_NODE_NOT_FOUND; } // 更新节点信息 if (name != NULL) { node->name = name; } if (enter_cb != NULL) { node->enter_cb = enter_cb; } if (exit_cb != NULL) { node->exit_cb = exit_cb; } return MENU_ERR_OK; } const struct MenuNode* menu_find_node(MenuNodeId node_id) { MenuCoreCtx* core_ctx = menu_get_core_ctx(); return menu_hash_find(core_ctx, node_id); } /* 菜单事件处理 -----------------------------------------------------------------------------------------------------*/ MenuErrCode menu_post_event(MenuEventType event_type, uint8_t priority) { MenuCoreCtx* core_ctx = menu_get_core_ctx(); MenuEvent event; event.type = event_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); } MenuErrCode menu_post_event_with_data(MenuEventType event_type, uint8_t priority, void* data) { MenuCoreCtx* core_ctx = menu_get_core_ctx(); MenuEvent event; event.type = event_type; event.priority = priority; event.target_node_id = core_ctx->current_node_id; event.data = data; event.timestamp = core_ctx->last_refresh_tick; return menu_event_queue_push(&core_ctx->event_queue, &event); } /* 菜单导航操作 -----------------------------------------------------------------------------------------------------*/ MenuErrCode menu_main_loop(uint32_t tick) { // 调用核心层的主循环功能 return menu_core_main_loop(tick); } MenuErrCode menu_enter(void) { return menu_post_event(MENU_EVENT_KEY_ENTER, 1); } MenuErrCode menu_exit(void) { return menu_post_event(MENU_EVENT_KEY_ESC, 1); } MenuErrCode menu_up(void) { return menu_post_event(MENU_EVENT_KEY_UP, 1); } MenuErrCode menu_down(void) { return menu_post_event(MENU_EVENT_KEY_DOWN, 1); } MenuErrCode menu_select(MenuNodeId node_id) { // 暂未实现直接选择指定节点功能 (void)node_id; return MENU_ERR_OPERATION_FAILED; } MenuErrCode menu_reset(void) { // 暂未实现重置功能 return MENU_ERR_OPERATION_FAILED; } /* 菜单状态查询 -----------------------------------------------------------------------------------------------------*/ MenuState menu_get_state(void) { return menu_get_current_state(); } MenuNodeId menu_get_current_node(void) { return menu_get_current_node_id(); } uint8_t menu_get_nav_depth(void) { MenuCoreCtx* core_ctx = menu_get_core_ctx(); return core_ctx->nav_path.depth; } uint8_t menu_get_nav_path(MenuNodeId* path, uint8_t max_depth) { MenuCoreCtx* core_ctx = menu_get_core_ctx(); uint8_t actual_depth = core_ctx->nav_path.depth; if (actual_depth > max_depth) { actual_depth = max_depth; } for (uint8_t i = 0; i < actual_depth; i++) { path[i] = core_ctx->nav_path.path[i]; } return actual_depth; } /* 状态机扩展接口 ---------------------------------------------------------------------------------------------------*/ #if MENU_CONFIG_ENABLE_STATE_MACHINE_EXT MenuErrCode menu_state_register_transition(const MenuStateTransition* transition) { MenuCoreCtx* core_ctx = menu_get_core_ctx(); if (core_ctx->custom_transition_count >= MENU_CONFIG_MAX_STATE_TRANSITIONS) { return MENU_ERR_OUT_OF_MEMORY; } core_ctx->custom_transitions[core_ctx->custom_transition_count] = *transition; core_ctx->custom_transition_count++; return MENU_ERR_OK; } MenuErrCode menu_state_unregister_transition(MenuState current_state, MenuEventType event) { MenuCoreCtx* core_ctx = menu_get_core_ctx(); bool found = false; // 查找并删除匹配的状态转换规则 for (uint16_t i = 0; i < core_ctx->custom_transition_count; i++) { if (core_ctx->custom_transitions[i].current_state == current_state && core_ctx->custom_transitions[i].event == event) { // 找到匹配的规则,将后续规则前移 for (uint16_t j = i; j < core_ctx->custom_transition_count - 1; j++) { core_ctx->custom_transitions[j] = core_ctx->custom_transitions[j + 1]; } core_ctx->custom_transition_count--; found = true; break; } } return found ? MENU_ERR_OK : MENU_ERR_INVALID_STATE; } MenuErrCode menu_state_switch(MenuState state) { MenuCoreCtx* core_ctx = menu_get_core_ctx(); core_ctx->current_state = state; return MENU_ERR_OK; } #endif /* 内存监控接口 -----------------------------------------------------------------------------------------------------*/ #if MENU_CONFIG_ENABLE_MEM_MONITOR uint16_t menu_mem_get_used_nodes(void) { MenuCoreCtx* core_ctx = menu_get_core_ctx(); return core_ctx->node_count; } uint16_t menu_mem_get_free_nodes(void) { MenuCoreCtx* core_ctx = menu_get_core_ctx(); return core_ctx->free_node_count; } uint16_t menu_mem_get_max_nodes(void) { return MENU_CONFIG_MAX_NODES; } #endif