不支持多实例的tinyfsm
tinyfsm (https://github.com/digint/tinyfsm)是一款基于c++模板实现的状态机,因为模板所以效率很高,但又因为是模板,所以无法支持多实例,据说可以通过静态模板支持多实例,但静态模板需要在代码阶段就定义出来,那这多实例也太鸡肋了。因此基于tinyfsm,魔改了一款支持多实例的fsm。
支持多实例的mi_tinyfsm
mi是multi instance的缩写,多实例tinyfsm摒弃了模板(高效率),并且使用了STL,但真正支持多实例,相当于在功能和效率之间的一个取舍吧。
举个栗子
参考tinyfsm经典例子switch实现的多实例switch,输入0或者1对switch0或者switch1进行开关状态切换。完整源码见以下链接。
https://gitee.com/cyy1205/mi_tinyfsmm
关键代码
/*
* MI_TinyFSM - Multi Instansce tinyfsm
*
* Salute to tinyfsm https://github.com/digint/tinyfsm
*
* Copyright (c) 2023-2024 yuping.li
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef MI_TINYFSM_H
#define MI_TINYFSM_H
#include <functional>
#include <map>
#include <string>
class MiTinyfsm {
public:
struct State {
std::string name;
std::function<void()> entry;
std::function<void()> exit;
std::map<std::string, std::function<void()>> events;
};
explicit MiTinyfsm(State &initial_state) : current_state_ptr(&initial_state) { }
virtual void enter_initial_state() const {
if (current_state_ptr->entry) {
current_state_ptr->entry();
}
}
virtual void start() {
enter_initial_state();
}
virtual void dispatch(const std::string& event) {
if (current_state_ptr->events.count(event)) {
current_state_ptr->events[event]();
}
}
protected:
virtual void transit(State& state) {
if (current_state_ptr->exit) {
current_state_ptr->exit();
}
current_state_ptr = &state;
if (current_state_ptr->entry) {
current_state_ptr->entry();
}
}
virtual void transit(State& state, const std::function<void()>& action) {
if (current_state_ptr->exit) {
current_state_ptr->exit();
}
action();
current_state_ptr = &state;
if (current_state_ptr->entry) {
current_state_ptr->entry();
}
}
virtual void transit(State& state, const std::function<void()>& action, const std::function<bool()>& condition) {
if (condition()) {
transit(state, action);
}
}
State* current_state_ptr{nullptr};
};
#endif //MI_TINYFSM_H