From ba76434f258f4c56c0fb12266ffb0e7587abdeda Mon Sep 17 00:00:00 2001 From: Lucas Date: Tue, 8 Nov 2022 12:33:12 +0800 Subject: [PATCH 1/4] tidy --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3875e09..106e62e 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # cpp\_tbox #### 介绍 -cpp\_tbox,全称: C++ Treasure Box,C++开发百宝箱,是基于事件的服务型应用开发库。 +cpp-tbox,全称: C++ Treasure Box,C++开发百宝箱,是基于事件的服务型应用开发库。 #### 适用环境 -- Gitee From d62e9d08b85b342b52ee05336dfeb42e821937a8 Mon Sep 17 00:00:00 2001 From: Lucas Date: Tue, 8 Nov 2022 12:36:02 +0800 Subject: [PATCH 2/4] =?UTF-8?q?=E7=BB=99=E7=8A=B6=E6=80=81=E6=9C=BA?= =?UTF-8?q?=E5=8A=A0=E5=86=85=E9=83=A8=E4=BA=8B=E4=BB=B6=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/util/state_machine.cpp | 39 ++++++++++++++++++++++++++++++---- modules/util/state_machine.h | 16 ++++++++++++++ 2 files changed, 51 insertions(+), 4 deletions(-) diff --git a/modules/util/state_machine.cpp b/modules/util/state_machine.cpp index 4662459..6f1f6c4 100644 --- a/modules/util/state_machine.cpp +++ b/modules/util/state_machine.cpp @@ -20,6 +20,8 @@ class StateMachine::Impl { public: bool newState(StateID state_id, const ActionFunc &enter_action, const ActionFunc &exit_action); bool addRoute(StateID from_state_id, EventID event_id, StateID to_state_id, const GuardFunc &guard, const ActionFunc &action); + bool addEvent(StateID state_id, EventID event_id, const ActionFunc &action); + void setInitState(StateID init_state_id) { init_state_id_ = init_state_id; } bool setSubStateMachine(StateID state_id, StateMachine *wp_sub_sm); @@ -45,7 +47,8 @@ class StateMachine::Impl { ActionFunc enter_action; ActionFunc exit_action; StateMachine::Impl *sub_sm; //! 子状态机 - vector routes; + vector routes; //! 转换路由 + map events; //! 内部事件 }; State* findState(StateID state_id) const; @@ -81,6 +84,11 @@ bool StateMachine::addRoute(StateID from_state_id, EventID event_id, StateID to_ return impl_->addRoute(from_state_id, event_id, to_state_id, guard, action); } +bool StateMachine::addEvent(StateID state_id, EventID event_id, const ActionFunc &action) +{ + return impl_->addEvent(state_id, event_id, action); +} + void StateMachine::setInitState(StateID init_state_id) { impl_->setInitState(init_state_id); @@ -169,6 +177,24 @@ bool StateMachine::Impl::addRoute(StateID from_state_id, EventID event_id, State return true; } +bool StateMachine::Impl::addEvent(StateID state_id, EventID event_id, const ActionFunc &action) +{ + if (action == nullptr) { + LogWarn("action is nullptr", state_id); + return false; + } + + //! 要求 from_state_id 必须是已存在的状态 + auto from_state = findState(state_id); + if (from_state == nullptr) { + LogWarn("from_state %d not exist", state_id); + return false; + } + + from_state->events[event_id] = action; + return true; +} + bool StateMachine::Impl::setSubStateMachine(StateID state_id, StateMachine *wp_sub_sm) { auto state = findState(state_id); @@ -248,6 +274,11 @@ bool StateMachine::Impl::run(Event event) return false; } + //! 检查事件,并执行 + auto event_iter = curr_state_->events.find(event.id); + if (event_iter != curr_state_->events.end()) + event_iter->second(event); + //! 如果有子状态机,则给子状态机处理 if (curr_state_->sub_sm != nullptr) { bool ret = curr_state_->sub_sm->run(event); @@ -257,7 +288,7 @@ bool StateMachine::Impl::run(Event event) } //! 找出可行的路径 - auto iter = std::find_if(curr_state_->routes.begin(), curr_state_->routes.end(), + auto route_iter = std::find_if(curr_state_->routes.begin(), curr_state_->routes.end(), [event] (const Route &item) -> bool { if (item.event_id != 0 && item.event_id != event.id) return false; @@ -268,11 +299,11 @@ bool StateMachine::Impl::run(Event event) ); //! 如果没有跳转则直接退出 - if (iter == curr_state_->routes.end()) + if (route_iter == curr_state_->routes.end()) return false; //! 以下是有跳转的情况 - const Route &route = *iter; + const Route &route = *route_iter; State *next_state = findState(route.next_state_id); if (next_state == nullptr) { diff --git a/modules/util/state_machine.h b/modules/util/state_machine.h index 3a2e619..4e184e8 100644 --- a/modules/util/state_machine.h +++ b/modules/util/state_machine.h @@ -75,6 +75,22 @@ class StateMachine { guard, action); } + /** + * \brief 添加事件 + * + * \param state_id 状态 + * \param event_id 事件,0表示任意事件 + * \param action 执行的动作 + * + * \return bool 成功与否 + */ + bool addEvent(StateID state_id, EventID event_id, const ActionFunc &action); + + template + bool addEvent(S state_id, E event_id, const ActionFunc &action) { + return addEvent(static_cast(state_id), static_cast(event_id), action); + } + /** * \brief 设置起始与终止状态 * -- Gitee From 8b5be7204d2657ed4183c9f6ecccb8ad69c78cc0 Mon Sep 17 00:00:00 2001 From: Lucas Date: Tue, 8 Nov 2022 12:47:15 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E6=B7=BB=E5=8A=A0StateMachine::addEvent()?= =?UTF-8?q?=E7=9A=84=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/util/state_machine_test.cpp | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/modules/util/state_machine_test.cpp b/modules/util/state_machine_test.cpp index 9f3d588..c095baa 100644 --- a/modules/util/state_machine_test.cpp +++ b/modules/util/state_machine_test.cpp @@ -499,6 +499,34 @@ TEST(StateMachine, EventExtra) EXPECT_EQ(count, 7); } +TEST(StateMachine, InnerEvent) { + enum class State { kTerm, k1, k2 }; + enum class Event { kNone, k1 }; + + SM sm; + + bool is_k1_event_run = false; + bool is_k2_event_run = false; + + sm.setInitState(State::k1); + sm.newState(State::k1, nullptr, nullptr); + sm.newState(State::k2, nullptr, nullptr); + sm.addEvent(State::k1, Event::k1, [&](SM::Event) { is_k1_event_run = true; }); + sm.addRoute(State::k1, Event::k1, State::k2, nullptr, nullptr); + sm.addEvent(State::k2, Event::k1, [&](SM::Event) { is_k2_event_run = true; }); + + sm.start(); + sm.run(Event::k1); + EXPECT_TRUE(is_k1_event_run); + EXPECT_FALSE(is_k2_event_run); + EXPECT_EQ(sm.currentState(), State::k2); + + is_k1_event_run = false; + sm.run(Event::k1); + EXPECT_FALSE(is_k1_event_run); + EXPECT_TRUE(is_k2_event_run); +} + TEST(StateMachine, SetInitState) { enum class State { kTerm, k1, kInit }; -- Gitee From c6e19c229c3abcbf48e916887a05b04639b22d33 Mon Sep 17 00:00:00 2001 From: Lucas Date: Tue, 8 Nov 2022 13:23:15 +0800 Subject: [PATCH 4/4] =?UTF-8?q?=E4=BF=AE=E6=94=B9StateMachine::addEvent()?= =?UTF-8?q?=E7=9A=84=E6=B3=A8=E9=87=8A=EF=BC=8C=E8=A1=A8=E7=A4=BA=E4=B8=8D?= =?UTF-8?q?=E6=94=AF=E6=8C=810=E4=BA=8B=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/util/state_machine.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/util/state_machine.h b/modules/util/state_machine.h index 4e184e8..922e218 100644 --- a/modules/util/state_machine.h +++ b/modules/util/state_machine.h @@ -79,7 +79,7 @@ class StateMachine { * \brief 添加事件 * * \param state_id 状态 - * \param event_id 事件,0表示任意事件 + * \param event_id 事件 * \param action 执行的动作 * * \return bool 成功与否 -- Gitee