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