返回顶部

收藏

状态机模板类

更多

我写了很多描述,由于操作不熟而丢失了。大家有对状态机不了解了,建议到百度与google去搜一下“状态机”关键字。我相信你会找到很多资料。

很多设备的工作模式不是:“遇到某事做什么”,而是:“在某个状态下,遇到某事,做什么,并变成另一种状态”。

StateMachine就是一个状态机的状模板。你只要关注statemachine.hpp部分的代码,这才是你用得着的。将其包含到你的工程中。

为了方便大家了解StateMachine的使用方法,我写了一个播放机的例子。特别是要看videostatemachine.cpp中是怎么添加状态表与如果实际 状态切换的。

有Qt开发环境了朋友可以下载到同一目录下,并在该目录下执行:

$ qmake -project

$ qmake *.pro

$ make

并执行生成生可执行文件。

本人亲自下载操作一下,是可以的。

由于statemachine.hpp文件中使用了std::vector与Boost::function, Boost::bind。如果你想使用它,你的开发环境需要具备两样东西。

对了,我的boost文件放在 /usr/include/boost/ 中,仅供参考。

#ifndef STATEMACHINE_H
#define STATEMACHINE_H

#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <vector>

template <typename StateType, typename EventType>
class StateMachine
{
public:
    typedef boost::function<bool()> GuardFun;
    typedef boost::function<void()> ActionFun;

    struct Item {
        StateType currState, nextState;
        EventType triger;
        GuardFun  guard;
        ActionFun action;

        Item(StateType cs, StateType ns, EventType t, GuardFun gf, ActionFun af)
            : currState(cs), nextState(ns), triger(t), guard(gf), action(af) {}
    };

    StateMachine(StateType startState) : m_currState(startState) {}

    void append(StateType cs, StateType ns, EventType t, GuardFun gf, ActionFun af) {
        m_stateTable.push_back(Item(cs, ns, t, gf, af));
    }
    void append(StateType cs, StateType ns, EventType t, GuardFun gf) {
        m_stateTable.push_back(Item(cs, ns, t, gf, boost::bind(&StateMachine::default_action, this)));
    }
    void append(StateType cs, StateType ns, EventType t, int, ActionFun af) {
        m_stateTable.push_back(Item(cs, ns, t, boost::bind(&StateMachine::default_guard, this), af));
    }
    void append(StateType cs, StateType ns, EventType t) {
        m_stateTable.push_back(Item(cs, ns, t, boost::bind(&StateMachine::default_guard, this),
                                    boost::bind(&StateMachine::default_action, this)));
    }

    StateType currentState() { return m_currState; }

    bool eventTriger(EventType triger)
    {
        bool isStateChanged = false;

        typename std::vector<Item>::iterator iter = m_stateTable.begin();
        for ( ; iter != m_stateTable.end(); ++iter) {
            if (iter->currState == m_currState && iter->triger == triger) {
                if (iter->guard()) {
                    m_currState = iter->nextState;
                    iter->action();
                    isStateChanged = true;
                }
                break;
            }
        }

        return isStateChanged;
    }

protected:
    bool default_guard() { return true; }
    void default_action() {}

private:
    std::vector<Item> m_stateTable;
    StateType m_currState;
};

#endif // STATEMACHINE_H
//该片段来自于http://outofmemory.cn

标签:c++,基础

收藏

0人收藏

支持

0

反对

0

相关聚客文章
  1. 博主 发表 2011-11-03 16:00:00 C++ 语言基础
  2. thinkpc 发表 2016-03-04 13:55:30 c++&nbsp;11 map基础value排序
  3. linux@linux.cn (linu 发表 2016-11-04 02:37:00 C++ 程序员 Protocol Buffers 基础指南
  4. pansunyou 发表 2014-11-30 02:51:00 C++通用跨数据库访问方案之一: 基础组件cdbc
  5. tanglei 发表 2014-05-28 15:08:01 struct与class区别联系
  6. 博主 发表 2016-06-28 05:17:59 Bazel C++ 基础[翻译]
  7. linux@linux.cn (linu 发表 2016-04-24 02:13:43 基础 JavaScript 装逼指南
  8. 博主 发表 2016-04-28 07:31:22 C++-内存区域
  9. 博主 发表 2016-05-06 00:40:04 大数据实验室(大数据基础培训)——基础概念
  10. 博主 发表 2016-01-06 00:00:00 统计学——基础概念
  11. Sailor 发表 2016-05-26 18:00:00 VC++开发GIS系统(193)删除线之IO函数实现
  12. linux@linux.cn (linu 发表 2016-06-03 06:42:02 21天速成 C++?编程生涯的一点思考

发表评论