From 1a2aeca518f0d32a09b9637335e8c2d453441732 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=B5=E5=A4=A9=E6=B5=A9?= Date: Tue, 21 Apr 2026 07:00:49 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0=EF=BC=8C=E5=9F=BA=E7=A1=80=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- fsm.c | 147 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- fsm.h | 11 +++-- 2 files changed, 152 insertions(+), 6 deletions(-) diff --git a/fsm.c b/fsm.c index 134d954..e85a711 100644 --- a/fsm.c +++ b/fsm.c @@ -2,8 +2,33 @@ // Created by Hydro on 2026/4/21. // #include "fsm.h" + +fsm_transition_t * +fsm_transition (fsm_handle_t *handle_ptr, const fsm_event_t *event) +{ + fsm_transition_t *trans = NULL; + do + { + if (!(handle_ptr && event)) + { + break; + } + const fsm_state_t *current_state = fsm_get_state(handle_ptr); + for (size_t i = 0; i < handle_ptr->num_trans; i++) + { + if (handle_ptr->p_trans_list[i].state == current_state->state + && handle_ptr->p_trans_list[i].event == event->event) + { + trans = &handle_ptr->p_trans_list[i]; + break; + } + } + } while (0); + return trans; +} fsm_result_e fsm_init_with_queue (fsm_handle_t *handle_ptr, + uint16_t init_state, const fsm_event_queue_init event_queue_init, const fsm_event_queue_put event_queue_put, const fsm_event_queue_get event_queue_get) @@ -17,14 +42,134 @@ fsm_init_with_queue (fsm_handle_t *handle_ptr, result = FSM_FAIL; break; } + for (size_t i = 0; i < handle_ptr->num_states; i++) + { + if (handle_ptr->p_state_list[i].state == init_state) + { + handle_ptr->current_state = &handle_ptr->p_state_list[i]; + } + } handle_ptr->event_queue_get = event_queue_get; handle_ptr->event_queue_put = event_queue_put; handle_ptr->event_queue_init = event_queue_init; - + handle_ptr->custom_queue = true; result = handle_ptr->event_queue_init(handle_ptr->event_queue_handle, handle_ptr->event_queue, EVENT_QUEUE_LEN * sizeof(fsm_event_t)); } while (0); return result; +} +fsm_result_e +fsm_event_put (fsm_handle_t *handle_ptr, fsm_event_t *event) +{ + fsm_result_e result = FSM_OK; + do + { + if (!(handle_ptr && event)) + { + result = FSM_FAIL; + break; + } + if (handle_ptr->custom_queue) + { + result = handle_ptr->event_queue_put(handle_ptr->event_queue_handle, + event); + } + else + { + // TODO:补充默认队列的环形缓冲区填充逻辑 + result = FSM_FAIL; + } + } while (0); + return result; +} +fsm_result_e +fsm_process_queue (fsm_handle_t *handle_ptr) +{ + fsm_result_e result = FSM_OK; + do + { + if (!handle_ptr) + { + result = FSM_FAIL; + break; + } + fsm_event_t event = { 0 }; + if (handle_ptr->custom_queue) + { + result = handle_ptr->event_queue_get(handle_ptr->event_queue_handle, + &event); + } + if (result != FSM_OK) + { + result = FSM_FAIL; + break; + } + fsm_dispatch(handle_ptr, &event); + } while (0); + return result; +} +fsm_result_e +fsm_dispatch (fsm_handle_t *handle_ptr, const fsm_event_t *event) +{ + fsm_result_e result = FSM_OK; + do + { + if (!(handle_ptr && event)) + { + result = FSM_FAIL; + break; + } + const fsm_transition_t *trans = fsm_transition(handle_ptr, event); + fsm_state_t *current_state = fsm_get_state(handle_ptr); + if (trans) + { + // 发生状态切换 + if (trans->next_state != current_state->state) + { + if (current_state->on_exit) + { + current_state->on_exit(current_state->user_data); + } + // 执行事件动作 + if (trans->on_action) + { + trans->on_action(event->user_data); + } + for (size_t i = 0; i < handle_ptr->num_states; i++) + { + if (handle_ptr->p_state_list[i].state == trans->next_state) + { + current_state = &handle_ptr->p_state_list[i]; + if (current_state->on_entry) + { + current_state->on_entry(current_state->user_data); + } + break; + } + } + handle_ptr->current_state = current_state; + } + else + { + // 执行事件动作 + if (trans->on_action) + { + trans->on_action(event->user_data); + } + } + } + else + { + result = FSM_FAIL; + break; + } + } while (0); + return result; +} +fsm_state_t * +fsm_get_state (const fsm_handle_t *h) +{ + return h->current_state; } \ No newline at end of file diff --git a/fsm.h b/fsm.h index ae90945..2b1b8f2 100644 --- a/fsm.h +++ b/fsm.h @@ -46,9 +46,9 @@ struct qf_fsm_event }; struct qf_fsm { - uint16_t current_state; - uint16_t num_states; + fsm_state_t *current_state; char *name; + uint16_t num_states; fsm_state_t *p_state_list; uint32_t num_trans; fsm_transition_t *p_trans_list; @@ -59,13 +59,14 @@ struct qf_fsm fsm_event_queue_put event_queue_put; fsm_event_queue_get event_queue_get; }; -fsm_result_e fsm_init(fsm_handle_t *handle_ptr); +fsm_result_e fsm_init(fsm_handle_t *handle_ptr, uint16_t init_state); fsm_result_e fsm_init_with_queue(fsm_handle_t *handle_ptr, + uint16_t init_state, fsm_event_queue_init event_queue_init, fsm_event_queue_put event_queue_put, fsm_event_queue_get event_queue_get); fsm_result_e fsm_event_put(fsm_handle_t *handle_ptr, fsm_event_t *event); fsm_result_e fsm_process_queue(fsm_handle_t *handle_ptr); -fsm_result_e fsm_dispatch(fsm_handle_t *handle_ptr, fsm_event_t *event); -uint16_t fsm_get_state(fsm_handle_t *h); +fsm_result_e fsm_dispatch(fsm_handle_t *handle_ptr, const fsm_event_t *event); +fsm_state_t *fsm_get_state(const fsm_handle_t *h); #endif // QF_FSM_FSM_H